#include "stdafx.h" #ifndef _COUNTRY_ME_ #include "../KTextParser.h" #include "../KTextPhrase.h" #include "KUIWndManager.h" #include "KUIControlEdit.h" #include #include "Imm.h" #include #include #ifdef _COUNTRY_TL_ #include "./Localization/Thailand.h" #endif using namespace KUI_MESSAGE; // Edit Control Implement HandleMap KUIControlEdit::m_mapEditControl; // -1 indicates End of Array. DWORD KUIControlEdit::m_dwSysKey[] = { VK_RETURN, VK_TAB, VK_ESCAPE, KUIControlEdit::KEDIT_SYSKEY_END}; HWND KUIControlEdit::s_hWndCurrentFocus = NULL; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KUIControlEdit Implement //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace { KUIWnd* Creator() { return new KUIControlEdit; } bool bRegister = KUIFactory::GetInstance()->RegisterCreator( Creator, "edit"); } bool KUIControlEdit::m_FocusedEdit = false; KUIControlEdit::KUIControlEdit() // Default's edit control can't supply tag! : m_bOpenFlag(false), m_nFontSize(10), m_bCaretEnable(true), m_bTagEnable(true), m_bPassword(false) , m_bPasteLimit(false) { m_IMEInput.InitInput(); m_EditboxInfo.SetInputInterface(&m_IMEInput); //#if defined(_COUNTRY_TL_) SetFont( "Tahoma" ); // [sonador] //#else // SetFont( "굴림" ); // [sonador] //#endif SetFontColor( KColor(255, 255, 255, 255) ); m_sCaption = ""; m_bLineChange = false; m_pCaptionPhrase = NULL; m_pCandidatePhrase = NULL; m_pReadingPhrase = NULL; /// 2011.10.13 - prodongi m_isGhostText = false; } KUIControlEdit::~KUIControlEdit() { SetParent(NULL); //vista에서 게임 종료시 dmp 생성관련 버그 sfreer 2009.04.28 SetFocus( false ); //vista 다운버그? sfreer 2009.04.14 SAFE_DELETE(m_pCaptionPhrase); SAFE_DELETE(m_pCandidatePhrase); SAFE_DELETE(m_pReadingPhrase); KUIControlEdit::m_mapEditControl.erase(m_hWnd); _oprint( "~KUIControlEdit : %u\n", this ); //_CloseIME(); //SetFocus( false ); // 핸들을 삭제하자 } void KUIControlEdit::SetLimitation(int nLimitation, bool bBufferLimit/*true*/) { assert( nLimitation > 0 ); m_EditboxInfo.SetLimitation( nLimitation, bBufferLimit ); } DWORD KUIControlEdit::OnKeyMessage(DWORD dwMessage, DWORD dwKeyCode) { if( IsDisable() ) return 0; DWORD dwRet = KUIControl::OnKeyMessage(dwMessage, dwKeyCode); //_oprint( "KUIControlEdit::OnKeyMessage( " ); switch( dwMessage ) { case WM_KEYUP: { if( dwKeyCode == VK_DOWN && GetParent() ) GetParent()->PumpUpMessage( GetID(), KEDIT_VK_DOWN, 0, 0 ); else if( dwKeyCode == VK_UP && GetParent() ) GetParent()->PumpUpMessage( GetID(), KEDIT_VK_UP, 0, 0 ); } break; } //_oprint( ", %d )\n", dwKeyCode ); if(KMR_NO_GET & dwRet) return dwRet; m_bUpdateFlag = true; return dwRet; } DWORD KUIControlEdit::OnMouseMessage( DWORD dwMessage, int x, int y ) { if( IsDisable() ) return 0; DWORD dwRet = KUIControl::OnMouseMessage(dwMessage,x,y); if(KMR_NO_GET & dwRet) return dwRet; if( !GetRect().IsInRect( x, y ) ) return dwRet; m_bUpdateFlag = true; x -= m_rcCaptionArea.left; y -= m_rcCaptionArea.top; // 2010.06.23 13때문에 마우스 클릭이 잘 안될때가 있음, 왜 13이라는 숫자가 나왔는지 모르겠음,,- prodongi //if(y<13) m_EditboxInfo.OnMouseMessage(dwMessage,x,y); return dwRet; } void KUIControlEdit::Process(DWORD dwTime) { if( GetSafeTickCount() - m_dwLastCursorRenderTime > 500 ) { _UpdateEditText(); m_bUpdateFlag = false; m_dwLastCursorRenderTime = GetSafeTickCount(); m_bCursorBlink = !m_bCursorBlink; #ifdef _KUI_INVALIDATION InvalidateWnd(); #endif } #ifdef _KUI_INVALIDATION if( m_bUpdateFlag ) InvalidateWnd(); #endif KUIControl::Process(dwTime); } void KUIControlEdit::Render(KViewportObject *pViewport, bool isFront ) { //이제 render는 컨트롤들이 업데이트 될때만 호출된다. 따라서 아래 구문을 process에서 체크한다. /*if( GetSafeTickCount() - m_dwLastCursorRenderTime > 500 ) { _UpdateEditText(); m_bUpdateFlag = false; m_dwLastCursorRenderTime = GetSafeTickCount(); m_bCursorBlink = !m_bCursorBlink; }*/ if ( m_bShowFlag ) { if ( m_bUpdateFlag ) { _UpdateEditText(); m_bUpdateFlag = false; } // if( m_pCaptionPhrase ) m_pCaptionPhrase->SetCaretEnable( (m_bHasFocus ? m_bCursorBlink : false) ); // TODO : m_pCaptionPhrase 가 NULL 인경우가 있어서 땜질. -_- by Testors KUIControl::Render(pViewport, isFront); m_pReadingPhrase->Render(pViewport, isFront); // is it right? -_-; by Testors m_pCandidatePhrase->Render( pViewport, isFront ); } } void KUIControlEdit::Create(KUIWND_CREATE_ARG& CREATE_ARG) { KUIControl::Create(CREATE_ARG); // 2010.06.08 - prodongi m_EditboxInfo.setCaption(CREATE_ARG.lpszCaption); } void KUIControlEdit::_destroyControl() { KUIControl::_destroyControl(); } void KUIControlEdit::SetReSize( const KRect &rcNewRect ) { KUIWnd::OnSizeChangeNofity( rcNewRect); _reArrangeRect(); _initPhrase(); _DrawReadingCandidate(); std::string strTemp = ""; strTemp += m_sCaption.c_str(); KTextParser::TEXT_PRIMITIVE & currentTP = m_pCaptionPhrase->GetParser()->GetCurrentTP(); currentTP.nFontSize = m_nFontSize; currentTP.Color = m_Color; // 2010.06.08 - prodongi m_pCaptionPhrase->AddString(strTemp.c_str(), m_bTagEnable, true, false, m_bUseEmoticonFilter, m_EditboxInfo.isScroll()); //m_pCaptionPhrase->AddString(strTemp.c_str(), m_bTagEnable, true, false, m_bUseEmoticonFilter); } void KUIControlEdit::_initPhrase() { m_rcCaptionArea = KRect(m_rcRegion.left + KEDIT_XSIZE_GAP, m_rcRegion.top, m_rcRegion.right - KEDIT_XSIZE_GAP, m_rcRegion.bottom ); SAFE_DELETE(m_pCaptionPhrase); #ifdef _COUNTRY_ME_ m_pCaptionPhrase = new KTextLayout2(m_rcCaptionArea.right - m_rcCaptionArea.left, m_rcCaptionArea.bottom - m_rcCaptionArea.top ); #else m_pCaptionPhrase = new KTextPhrase(m_rcCaptionArea.right - m_rcCaptionArea.left, m_rcCaptionArea.bottom - m_rcCaptionArea.top ); #endif m_pCaptionPhrase->SetPosition(m_rcCaptionArea.left, m_rcRegion.top,m_fZPos); m_pCaptionPhrase->SetAlign( m_dwCaptionAlign); m_pCaptionPhrase->SetEditMode( true ); SAFE_DELETE(m_pCandidatePhrase); m_pCandidatePhrase = new KTextPhrase(512, (m_rcCaptionArea.bottom - m_rcCaptionArea.top)*2 ); m_pCandidatePhrase->SetAlign( m_dwCaptionAlign); SAFE_DELETE(m_pReadingPhrase); m_pReadingPhrase = new KTextPhrase(m_rcCaptionArea.right - m_rcCaptionArea.left, m_rcCaptionArea.bottom - m_rcCaptionArea.top ); m_pReadingPhrase->SetAlign( m_dwCaptionAlign); // 2010.06.03 - prodongi m_EditboxInfo.setMaxWidth(m_pCaptionPhrase->GetWidth()); m_EditboxInfo.setFontFlag(m_pCaptionPhrase->GetParser()->GetCurrentTP().dwFontFlag); } void KUIControlEdit::_initControl() { _CreateEditWindow(); _reArrangeRect(); _initPhrase(); SetText( "" ); } void KUIControlEdit::OnSysKey(DWORD dwKeyCode) { } void KUIControlEdit::OnPosChangeNofity(int XOffset, int YOffset) { KUIControl::OnPosChangeNofity(XOffset, YOffset); m_IMEInput.SetCompositionWndPos( m_rcRegion.left, m_rcRegion.top ); } void KUIControlEdit::OnFocusNotify() { // _oprint( "void KUIControlEdit::OnFocusNotify(%u) : %s / %s\n", m_hWnd, m_bHasFocus ? "true" : "false", GetID() ); if( IsDisable() ) //컨트롤이 disable중이면 포커스 주지 마라 m_bHasFocus = false; if( m_bHasFocus ) { ::EnableWindow( m_hWnd, TRUE ); ::SetFocus( m_hWnd ); m_bOpenFlag = true; s_hWndCurrentFocus = m_hWnd; //_OpenIME(); PumpUpMessage( GetID( ), KUI_MESSAGE::KFOCUS_ACTIVATED, 0, 0 ); // [soandor][3.1.2] 경매장 구현 /// 2011.10.13 - prodongi cancelGhostText(); setFocusFlag(true); } else { ::EnableWindow(m_hWnd, FALSE); ::SetFocus( KUIWndManager::GetHWnd() ); m_bOpenFlag = false; //_CloseIME(); s_hWndCurrentFocus = NULL; PumpUpMessage( GetID( ), KUI_MESSAGE::KFOCUS_DEACTIVATED, 0, 0 ); // [soandor][3.1.2] 경매장 구현 } } void KUIControlEdit::SetInitFocus() { // editcontrol 포커스 초기화 하는 함수 추가. sfreer 2009.04.30 ::SetFocus( KUIWndManager::GetHWnd() ); s_hWndCurrentFocus = NULL; } LPCSTR KUIControlEdit::GetText() { _UpdateEditText(); wchar_t wbuff[1024]; char buff[1024]; wbuff[0] = 0; buff[0] = 0; // 2010.06.09 - prodongi int nPos = m_EditboxInfo.GetInputBufferOri( wbuff, 1024 ); //int nPos = m_EditboxInfo.GetInputBuffer( wbuff, 1024 ); wbuff[ nPos ] = 0; if( !wbuff[0] ) return ""; // AziaMafia Fix CODEPAGE CP_UTF8 // GET_CODEPAGE() buff[ WideCharToMultiByte(GET_CODEPAGE(),0,wbuff,wcslen(wbuff),buff,1024,NULL,NULL) ] = 0; // _oprint( "++++KUIControlEdit::GetText HWND %d -> %s\n", m_hWnd, buff ); m_sCaption.assign(buff); return m_sCaption.c_str(); } void KUIControlEdit::SetText(LPCSTR lpszText) { m_isGhostText = false; /// 2011.10.13 - prodongi setTextOriginal(lpszText); } // { [sonador] void KUIControlEdit::SetFont(LPCSTR lpszFontName) { m_strFontTag = "second->OnSysKey(wParam); if ( i->second->GetParent() ) i->second->GetParent()->PumpUpMessage( i->second->GetID(), KEDIT_SYSKEY, wParam, 0 ); return 0; } nCount++; // End of syskey array if(m_dwSysKey[nCount] == KEDIT_SYSKEY_END) break; } } // Block temporary tags... if( uMsg == WM_CHAR ) { switch( wParam ) { case '<': wParam = 0x1E; break; case '>': wParam = 0x1F; break; } } switch(uMsg) { case WM_CHAR: if( !i->second->OnMessage( hWnd, uMsg, wParam, lParam ) ) //변경 후 알림 if ( i->second->GetParent() ) i->second->GetParent()->PumpUpMessage( i->second->GetID(), KEDIT_CHANGE, 0, 0 ); return 0L; /* IME Messages */ case WM_IME_SETCONTEXT: lParam = 0; break; case WM_IME_STARTCOMPOSITION: return 0L; case WM_INPUTLANGCHANGE: case WM_IME_COMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_KEYDOWN: case WM_KEYUP: { #ifdef _DEV // bintitle. 2011.11.09. if( (wParam==VK_UP) || (wParam==VK_DOWN) ) { if ( i->second->GetParent() ) i->second->GetParent()->PumpUpMessage( i->second->GetID(), KEDIT_VK_UP, wParam, 0 ); } #endif if( !i->second->OnMessage( hWnd, uMsg, wParam, lParam ) ) { //// { [sonador][3.1.3] Auction House server integration: pressing Delete key triggers KEDIT_CHANGE message //if ( i->second->GetParent() ) // i->second->GetParent()->PumpUpMessage( i->second->GetID(), KEDIT_CHANGE, 0, 0 ); //// } return 0L; } } break; case WM_IME_NOTIFY: { if ( i->second->GetParent() ) i->second->GetParent()->PumpUpMessage( i->second->GetID(), KEDIT_IME_CHANGE, wParam, 0 ); if( i->second->OnMessage( hWnd, uMsg, wParam, lParam ) == 0L ) return 0L; } break; /* End of IME Messages */ } nRet = CallWindowProc(i->second->m_oldProc, i->second->m_hWnd, uMsg,wParam,lParam); int pn=0; switch(uMsg) { case WM_KEYDOWN: case WM_KEYUP: // If you remove this line, this module acts abnormally when typing Korean language. /* case WM_CHAR: i->second->OnKeyMessage(uMsg, wParam); break; */ case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: { int x = LOWORD(lParam); int y = HIWORD(lParam); i->second->OnMouseMessage( uMsg, x, y ); } break; case WM_KILLFOCUS: i->second->SetFocus( false ); setFocusFlag(false); //_oprint( "에디트 컨트롤 WM_KILLFOCUS : %s\n", i->second->GetID() ); break; default: break; } } return nRet; } LONG KUIControlEdit::OnMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { m_bUpdateFlag = true; switch( msg ) { /* IME Messages */ case WM_INPUTLANGCHANGE: m_IMEInput.OnInputLanguageChange(hWnd, wParam, lParam); //InvalidateRect(hWnd, NULL, TRUE); break; case WM_IME_SETCONTEXT: lParam = 0; break; case WM_IME_STARTCOMPOSITION: return 0L; case WM_IME_COMPOSITION: if( m_IMEInput.IsOnlyNum() ) return 1; if(m_IMEInput.OnComposition(hWnd, wParam, lParam)) { m_EditboxInfo.DeleteSelectText(); // InvalidateRect(hWnd, NULL, TRUE); return 0L; } break; case WM_IME_ENDCOMPOSITION: if(m_IMEInput.OnEndComposition(hWnd, wParam, lParam)) { // InvalidateRect(hWnd, NULL, TRUE); return 0L; } break; case WM_IME_NOTIFY: // _performance_print( "WM_IME_NOTIFY %d\n", wParam ); if(m_IMEInput.OnNotify(hWnd, wParam, lParam)) { // InvalidateRect(hWnd, NULL, TRUE); return 0L; } //InvalidateRect(hWnd, NULL, TRUE); break; case WM_CHAR: if( m_IMEInput.OnChar(hWnd, wParam, lParam) ) { m_EditboxInfo.OnChar(wParam); return 0L; } //InvalidateRect(hWnd, NULL, TRUE); break; ///* End of IME Messages */ case WM_KEYDOWN: // 2011. 11. 3 - marine if(isPasteLimit() && wParam == 86) break; // 2010.06.08 - prodongi setUnActivateBlinkCursor(); /// 2012.02.16 - prodongi m_IMEInput.OnKeyDown(wParam); if( !m_EditboxInfo.OnKeyDown(wParam) ) return 0L; break; case WM_KEYUP: m_EditboxInfo.OnKeyUp(wParam); break; case WM_LBUTTONDOWN: // 2010.06.08 - prodongi setUnActivateBlinkCursor(); m_EditboxInfo.OnChar(wParam); break; case WM_LBUTTONUP: m_EditboxInfo.OnChar(wParam); break; case WM_MOUSEMOVE: m_EditboxInfo.OnChar(wParam); break; } return 1; } LONG KUIControlEdit::OnIMEMessage( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { m_bUpdateFlag = true; switch( msg ) { /* IME Messages */ case WM_INPUTLANGCHANGE: m_IMEInput.OnInputLanguageChange(hWnd, wParam, lParam); //InvalidateRect(hWnd, NULL, TRUE); break; case WM_IME_SETCONTEXT: lParam = 0; break; case WM_IME_STARTCOMPOSITION: return 0L; case WM_IME_COMPOSITION: if( m_IMEInput.IsOnlyNum() ) return 1; if(m_IMEInput.OnComposition(hWnd, wParam, lParam)) { // InvalidateRect(hWnd, NULL, TRUE); return 0L; } break; case WM_IME_ENDCOMPOSITION: if(m_IMEInput.OnEndComposition(hWnd, wParam, lParam)) { // InvalidateRect(hWnd, NULL, TRUE); return 0L; } break; case WM_IME_NOTIFY: _performance_print( "WM_IME_NOTIFY %d\n", wParam ); if(m_IMEInput.OnNotify(hWnd, wParam, lParam)) { // InvalidateRect(hWnd, NULL, TRUE); return 0L; } //InvalidateRect(hWnd, NULL, TRUE); break; case WM_CHAR: if( m_IMEInput.OnChar(hWnd, wParam, lParam) ) return 0L; //InvalidateRect(hWnd, NULL, TRUE); break; /* End of IME Messages */ } return 1; } void KUIControlEdit::_OpenIME() { HIMC hIMC = ImmGetContext(m_hWnd); if (NULL == hIMC) { m_dwConv = 0; m_dwSentence = 0; // m_bOpenStatus = FALSE; return; } /* // 예전의 Status를 저장 (Close를 위해서) m_bOpenStatus = ImmGetOpenStatus(hIMC); ImmGetConversionStatus(hIMC, &m_dwConv, &m_dwSentence); // // ** Must Open IME First ** -> See MSDN Article ID: Q150024 // ImmSetOpenStatus(hIMC, TRUE); ImmSetConversionStatus(hIMC, m_dwConv | IME_CMODE_NATIVE, m_dwSentence); ImmReleaseContext(m_hWnd, hIMC); */ } void KUIControlEdit::_CloseIME() { HIMC hIMC = ImmGetContext(m_hWnd); if (NULL == hIMC) return; /* if(!m_bOpenFlag) return; // Recover old state // // ** Must Open IME First ** -> See MSDN Article ID: Q150024 // ImmSetOpenStatus(hIMC, TRUE); ImmSetConversionStatus(hIMC, m_dwConv, m_dwSentence); ImmSetOpenStatus(hIMC, m_bOpenStatus); ImmReleaseContext(m_hWnd, hIMC); */ m_bOpenFlag = FALSE; } void KUIControlEdit::_CreateEditWindow() { m_hWnd = ::CreateWindow( "EDIT", NULL, WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_LEFT, m_rcRegion.left+2, m_rcRegion.top+2, m_rcRegion.right - m_rcRegion.left - 2, m_rcRegion.bottom - m_rcRegion.top - 2, KUIWndManager::GetHWnd(), NULL, KUIWndManager::GetInstance(), NULL ); m_IMEInput.OnInputLanguageChange(m_hWnd, 0, (LPARAM)GetKeyboardLayout(0)); // 예전 proc를 보관 m_oldProc = (WNDPROC)( SetWindowLong(m_hWnd, GWL_WNDPROC,(LONG)(KUIControlEdit::EditBoxProc) ) ); // _oprint( "KUIControlEdit::_CreateEditWindow -> %d \n", m_hWnd ); DWORD capwidth = m_rcRegion.GetWidth() < 32 ? 32 : m_rcRegion.GetWidth(); capwidth = KTextPhrase::GetStringSize( "X", capwidth).width; m_nShowChar = (m_rcRegion.GetWidth() - 5)/capwidth; // 핸들을 보관해 주자. KUIControlEdit::m_mapEditControl[m_hWnd] = this; } void KUIControlEdit::_UpdateEditText() { int text_len=0; char buff[1024]={0,}; wchar_t wbuff[1024]={0,}; text_len = m_IMEInput.GetInput(wbuff, 1024); if(text_len) // g_input의 input버퍼에 하나라도 남아 있음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌 { m_EditboxInfo.AddInputBuffer(wbuff,text_len); m_IMEInput.ClearInput(); ZeroMemory(wbuff,sizeof(wbuff)); } text_len=0; text_len=_CreateEditTextBuffer(wbuff,sizeof(wbuff)); if(text_len) { // AziaMafia Fix CODEPAGE CP_UTF8 // GET_CODEPAGE() text_len = WideCharToMultiByte(GET_CODEPAGE(),0,wbuff,text_len,buff,1024,NULL,NULL); buff[text_len] = 0; } _DrawReadingCandidate(); /* m_pCandidatePhrase->Clear(); std::string strCandidate; int k = 1; int count = min(m_IMEInput.GetCandidateCount(), m_IMEInput.GetCandidatePageStart()+m_IMEInput.GetCandidatePageSize()); for(int i=m_IMEInput.GetCandidatePageStart(); iAddString( strCandidate.c_str() ); */ int nStringSize = static_cast(strlen(buff)); // MIMI 2005/08/16 이모티콘이 있는 경우 limit 조건이 달라진다. int nEmoticonLimit = nStringSize; if( m_pCaptionPhrase ) nEmoticonLimit = m_pCaptionPhrase->GetTextSize(buff); if( nEmoticonLimit < 0 ) nEmoticonLimit = nStringSize; //if( nStringSize > m_nLimitation ) /* if( nEmoticonLimit > m_nLimitation ) { if( m_bOnlyNumber ) { buff[m_nLimitation] = 0; nStringSize = m_nLimitation; } else { buff[nStringSize-2] = 0; } this->SetText(buff); } */ /* if( m_bOnlyNumber ) { bool bChange = false; for(int i = 0; i < nStringSize; ++i) { if( buff[i] < '0' || buff[i] > '9') { bChange = true; buff[i] = 0; } } if( bChange ) SetText( buff); } */ // save data m_sCaption.assign(buff); // for changing size // m_pCaptionPhrase 이 NULL 이라서 다운되었었음. 2005/05/15 by Testors if( !m_pCaptionPhrase ) return; KTextParser::TEXT_PRIMITIVE & currentTP = m_pCaptionPhrase->GetParser()->GetCurrentTP(); currentTP.nFontSize = m_nFontSize; currentTP.Color = m_Color; // ******* replacing for password //::SetWindowText( m_hWnd, buff ); /* if(m_bPassword) { for( int i = 0; i < m_EditboxInfo.GetInputBufferSize(); ++i ) buff[i] = '*'; //memset(wbuff,'*',sizeof(char) * nStringSize); buff[m_EditboxInfo.GetInputBufferSize()] = 0; } */ RECT rect; rect.top = m_rcRegion.top; rect.bottom = m_rcRegion.bottom; rect.left = m_rcRegion.left; rect.right = m_rcRegion.right; SendMessage( m_hWnd, EM_SETRECT, 0, (LPARAM)&rect ); SendMessage( m_hWnd, EM_GETRECT, 0, (LPARAM)&rect ); int nStartIndex = ::SendMessage( m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0 ); //if ( m_bEnable ) strncpy( buff, &buff[nStartIndex], m_nShowChar ); //else // strcpy( szText, m_szText ); /* if ( m_bHasFocus ) { if ( buff[0] != '\0' ) { int nSelS, nSelE; nSelS = nSelE = 0; int ncharIndex = ::SendMessage( m_hWnd, EM_GETSEL, (WPARAM)&nSelS, (LPARAM)&nSelE ); if( nSelE - nSelS >= 1 ) { int pos = nSelS - nStartIndex; int nLen = nSelE-nSelS+1; std::string str = buff; char buf[1024]; strncpy( buf, (buff+pos), nLen ); buf[nLen] = '\0'; wsprintf( buff, "%s", buf ); str.replace( nSelS-nStartIndex, nLen, buff ); strcpy( buff, str.c_str() ); } else { int pos = nSelS - nStartIndex; int len = static_cast(strlen(buff)); if( pos >= 0 && len > pos ) { std::string str = buff; LPCSTR lpszPrev = buff + pos; LPCSTR lpszNext = CharNext( lpszPrev); const int nCharCount = lpszNext - lpszPrev; char* pszSubStr = new char[nCharCount+1]; ::strncpy( pszSubStr, buff + pos, nCharCount ); pszSubStr[nCharCount] = 0; ::wsprintf( buff, "%s", pszSubStr ); str.replace( pos, nCharCount, buff ); strcpy( buff, str.c_str() ); delete pszSubStr; } else strcat( buff, " " ); } } else strcat( buff, " " ); } */ if ( strcmp( m_sPhraseText.c_str(), buff ) != 0 ) { // { [sonador] std::string strString( m_strFontTag ); // } /// 2011.10.13 - prodongi if (m_isGhostText) strString += m_ghostTextColor; strString += (m_sPrefixString + buff); m_sPhraseText = buff; int oldLineCount = m_pCaptionPhrase->GetLineNumber(); m_pCaptionPhrase->Clear(); // 2010.06.08 - prodongi m_pCaptionPhrase->AddString( strString.c_str(), m_bTagEnable, true, false, m_bUseEmoticonFilter, m_EditboxInfo.isScroll() ); //m_pCaptionPhrase->AddString( strString.c_str(), m_bTagEnable, true, false, m_bUseEmoticonFilter ); int newLineCount = m_pCaptionPhrase->GetLineNumber(); //라인이 바뀌었는지 위로 통보(크기 변경등에 사용) if( m_bLineChange && oldLineCount != newLineCount) { PumpUpMessage( GetID(), KEDIT_LINE_CHANGE, oldLineCount, newLineCount ); } } } // 2010.06.08 - prodongi void KUIControlEdit::setUnActivateBlinkCursor() { m_dwLastCursorRenderTime = GetSafeTickCount(); m_bCursorBlink = false; } void KUIControlEdit::_DrawReadingCandidate() { int textLen=0; int pos=m_EditboxInfo.GetCursorPos(); SIZE editTextSize; wchar_t cbuff[1024]={0,}; //Input { wchar_t w_text[1024]={0,}; wchar_t w_temptext[1024]={0,}; textLen=m_EditboxInfo.GetInputBuffer(w_text,_countof(w_text)); memcpy(w_temptext,w_text,sizeof(wchar_t)*pos-1); KTextRender::GetFreeTypeTextWidth(w_temptext,pos-1,&editTextSize); ZeroMemory(w_text,sizeof(w_text)); ZeroMemory(w_temptext,sizeof(w_temptext)); } //Reading { char text[1024] = {0,}; char temptext[1024] = {0,}; textLen = m_IMEInput.GetReading(text, sizeof(text)); if( textLen == 0 ) m_pReadingPhrase->Clear(); int cx = m_rcCaptionArea.left+editTextSize.cx; int cy = m_rcRegion.top + m_rcCaptionArea.bottom - m_rcCaptionArea.top; int candiatecx=cx; if(!m_IMEInput.IsVerticalReading()) { m_pReadingPhrase->Clear(); m_pReadingPhrase->SetPosition(cx,cy-40 ,0); m_pReadingPhrase->AddString( text,m_bTagEnable, true ); } else { char tmp[1024] = {0,}; char* begin = text; char* end = text + textLen; for(int i=0; i<4 && begin%s",tmp ); m_pReadingPhrase->Clear(); m_pReadingPhrase->SetPosition(cx, cy-40,0); m_pReadingPhrase->AddString( temptext,m_bTagEnable, true ); // AziaMafia CP_UTF8 //MultiByteToWideChar(GET_CODEPAGE(),0,temptext,strlen(temptext),cbuff,1024); MultiByteToWideChar(GET_CODEPAGE(),0,temptext,strlen(temptext),cbuff,1024); KTextRender::GetFreeTypeTextWidth(cbuff,next-begin,&editTextSize); cy += editTextSize.cy; begin = next; } } //Candidate m_pCandidatePhrase->Clear(); m_pCandidatePhrase->SetPosition(candiatecx, cy - 40,0); std::string strCandidate; int k = 1; int count = min(m_IMEInput.GetCandidateCount(), m_IMEInput.GetCandidatePageStart()+m_IMEInput.GetCandidatePageSize()); for(int i=m_IMEInput.GetCandidatePageStart(); i%d.%s<#000000> ", k, text ); else ::sprintf( tmp, "%d.%s ", k, text ); strCandidate += tmp; } if( strCandidate.size() ) { std::string strTmp = ""; strTmp += strCandidate; strTmp += ""; bool IsOldUseWordWrap = KTextParser::GetUseWordWrap(); KTextParser::SetUseWordWrap( false ); m_pCandidatePhrase->AddString( strTmp.c_str() ); KTextParser::SetUseWordWrap( IsOldUseWordWrap ); // { Candidate 창 벗어나지 않도록 조절 DWORD nTextSize = 0; DWORD nTextHeight = 0; KTextRender::GetStringSize( "", 9, false, strCandidate.c_str(), strCandidate.size(), &nTextSize, &nTextHeight ); K3DVector v = m_pCandidatePhrase->GetPosition(); int nRight = (int)(v.x + nTextSize); int nLineNum = m_pCandidatePhrase->GetLineNumber(); int nOffSet = nLineNum <= 1 ? 46 : 54; if( nRight > m_pManager->GetResolution().width ) { int nMod = nRight - m_pManager->GetResolution().width; m_pCandidatePhrase->SetPosition( v.x - nMod, cy-nOffSet, 0.f ); } else { m_pCandidatePhrase->SetPosition( v.x, cy-nOffSet, 0.f ); } // } } } } int KUIControlEdit::_CreateEditTextBuffer(wchar_t * buffer,int buff_size) { // _oprint( "1" ); assert( buff_size <= sizeof(wchar_t)*1024 && "OverFlow" ); wchar_t frontbuffer[1024]={0,}; wchar_t selectbuffer[1024]={0,}; wchar_t backbuffer[1024]={0,}; wchar_t cursorbuffer[20] = {0,}; wchar_t compbuffer[1024]={0,}; wchar_t inputbuffer[1024]={0,}; int inputlen,frontlen,backlen,cursorlen,complen,selectlen; int cursorpos=m_EditboxInfo.GetCursorPos(); inputlen = m_EditboxInfo.GetInputBuffer(inputbuffer,_countof(inputbuffer)); if( m_bPassword ) { //for( int i = 0; i < inputlen; ++i ) inputbuffer[i] = '*'; } complen = m_IMEInput.GetComp(compbuffer,_countof(compbuffer)); // 2010.06.23 - prodongi m_EditboxInfo.setCompBuffer(compbuffer); int selectstart=m_EditboxInfo.GetSelectIndexBegin(); int selectend=m_EditboxInfo.GetSelectIndexEnd(); if(selectstart>selectend) //선택된 문자열의 시작위치보다 끝위치가 작으면 바꿔줌 { int temp; temp=selectstart; selectstart=selectend; selectend=temp; } if(!(selectend-selectstart)) //selectstart에 값이 있다는 것은 선택된 문자열이 있다는 것을 의미함 { frontlen=cursorpos-1; selectlen=0; } else { frontlen=selectstart-1; selectlen=selectend-selectstart; memcpy(selectbuffer,&inputbuffer[selectstart-1],sizeof(wchar_t)*selectlen); cursorpos=selectend; } // _oprint( "2" ); //if( frontlen <= 0 ) frontlen = 1; if( frontlen < 0 ) frontlen = 0; bool bEndCursur = false; memcpy(frontbuffer,inputbuffer,sizeof(wchar_t)*frontlen); // _oprint( "3" ); // m_bCursorBlink = ((GetSafeTickCount()%1000) > 600); const wchar_t *szCursorBegin = L""; const wchar_t *szCursorEnd = L""; if( m_bCursorBlink ) { szCursorBegin = L"";//"; szCursorEnd = L"";//"; } if(inputlen>=cursorpos) {// {1}-커서가 중간에 있을때 // _oprint( "4" ); //cursorbuffer설정 if(!complen) { //{3}-조합버퍼에 조합중인 버퍼가 없을때 #ifdef _COUNTRY_TL_ // 태국의 경우 cursorlen= LocalizationTL::GetCursorLength(inputbuffer, inputlen, cursorpos); // 한글자가 2바이트 이상인 경우 커서가 그것까지 모두 커버하게 해야 한다. memcpy(cursorbuffer,&inputbuffer[cursorpos-1],sizeof(wchar_t) * cursorlen); #else cursorlen=1; memcpy(cursorbuffer,&inputbuffer[cursorpos-1],sizeof(wchar_t)); #endif backlen=inputlen-cursorpos; if(backlen<=0)//백버퍼(커서 뒤에 문자열버퍼)에 데이타 존재 유무 { backlen=0; } else { memcpy(backbuffer,&inputbuffer[cursorpos],sizeof(wchar_t)*backlen); } } //{3} else { //{4}-조합버퍼에 조합중인 버퍼가 있을때 // _oprint( "5" ); cursorlen=0; backlen=inputlen-cursorpos+1; if(backlen<=0) //백버퍼(커서 뒤에 문자열버퍼)에 데이타 존재 유무 { backlen=0; } else { memcpy(backbuffer,&inputbuffer[cursorpos-1],sizeof(wchar_t)*backlen); } } //{4} } // {1} else //커서가 끝에 있을때... {// {2} // _oprint( "6" ); cursorlen=0; if(!complen) { wchar_t space[2] = {' '}; memcpy(cursorbuffer,space,sizeof(wchar_t)); bEndCursur = true; //GetFreeTypeTextWidth( cursorbuffer,1, &cursoreditsize); } backlen=0; }// {2} if( m_bPassword ) { for( wchar_t *p = frontbuffer; *p; ++p ) *p = '*'; for( wchar_t *p = selectbuffer; *p; ++p ) *p = '*'; for( wchar_t *p = compbuffer; *p; ++p ) *p = '*'; for( wchar_t *p = cursorbuffer; *p; ++p ) *p = bEndCursur ? ' ' : '*'; for( wchar_t *p = backbuffer; *p; ++p ) *p = '*'; } //그리기 int totalsize=0; //wcscat(buffer, L"<#FFFFFF>" ); wcscat(buffer,frontbuffer); totalsize=wcslen(buffer); if(selectlen)//선택된 문자열 그리기 { ::swprintf( buffer+totalsize, L"%s", selectbuffer ); totalsize=wcslen(buffer); } bool bOverString = m_EditboxInfo.IsMaxInput(); if(complen && !bOverString)//조합퍼버의 내용 유무 //조합버퍼에 값이 있지만 이미 제한된 글 { ::swprintf( buffer+totalsize, L"%s%s%s", szCursorBegin, compbuffer, szCursorEnd ); totalsize=wcslen(buffer); } if(m_bHasFocus) { if((!selectlen)&&(!complen))//선택한 문자열이 있으면 커서를 그리지 말자... { ::swprintf( buffer+totalsize, L"%s%s%s", szCursorBegin, cursorbuffer, szCursorEnd ); totalsize=wcslen(buffer); } else { ::swprintf( buffer+totalsize, L"%s", cursorbuffer ); totalsize=wcslen(buffer); } } else { ::swprintf( buffer+totalsize, L"%s", cursorbuffer ); totalsize=wcslen(buffer); } // _oprint( "4" ); if(backlen) { ::swprintf( buffer+totalsize, L"%s", backbuffer ); totalsize=wcslen(buffer); } /* if( totalsize ) { //if( ( buffer[0] != ' ' || !(buffer[0] != ' ' && totalsize != 1) ) ) { std::wstring tmp = L"<#FFFFFF>"; tmp += buffer; totalsize = tmp.size(); wcsncpy( buffer, tmp.c_str(), tmp.size() ); } } */ return totalsize; } void KUIControlEdit::setGhostText(LPCSTR text, LPCSTR color) { m_isGhostText = true; m_ghostTextColor = color; setTextOriginal(text); SetFocus(false); } void KUIControlEdit::cancelGhostText() { if (!m_isGhostText) return ; m_isGhostText = false; ::SetWindowText(m_hWnd,""); m_sPhraseText.clear(); m_EditboxInfo.ClearInputBuffer(); m_IMEInput.ClearInput(); setUnActivateBlinkCursor(); } void KUIControlEdit::setTextOriginal(LPCSTR lpszText) { ::SetWindowText(m_hWnd,lpszText); // _oprint( "++++KUIControlEdit::SetText HWND %d -> %s\n", m_hWnd, lpszText ); m_EditboxInfo.ClearInputBuffer(); wchar_t wbuff[1024] = {0,}; // AziaMafia CP_UTF8 //size_t len = ::MultiByteToWideChar( GET_CODEPAGE(), 0, lpszText, strlen(lpszText), wbuff, 1024 ); size_t len = ::MultiByteToWideChar(GET_CODEPAGE(), 0, lpszText, strlen(lpszText), wbuff, 1024 ); m_EditboxInfo.AddInputBuffer( (wchar_t*)wbuff, len ); ::SendMessage(m_hWnd, WM_KEYDOWN, VK_END, 0U ); _UpdateEditText(); } #endif