#include "stdafx.h" #ifdef _COUNTRY_ME_ #include "../KTextParser.h" #include "../KTextPhrase.h" #include "KUIWndManager.h" #include "KUIControlEdit_ME.h" #include #include "Imm.h" #include #include #include "SDebug_Util.h" #include "SGameOperationManager.h" 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_bUpdateFlag = false; m_IMEInput.InitInput(); m_EditboxInfo.SetInputInterface(&m_IMEInput); SetFont( "Default" ); // [sonador] 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() { 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::SetInitFocus() { // editcontrol 포커스 초기화 하는 함수 추가. sfreer 2009.04.30 ::SetFocus( KUIWndManager::GetHWnd() ); s_hWndCurrentFocus = NULL; } void KUIControlEdit::SetLimitation(int nLimitation, bool bBufferLimit/*false*/) { 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 > 300 ) { _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.24 - prodongi m_EditboxInfo.setCaption(CREATE_ARG.lpszCaption); } void KUIControlEdit::_destroyControl() { KUIControl::_destroyControl(); } static std::string StrFormat( const char* szString, ... ) { char szBuf[1024]; va_list va; va_start( va, szString ); _vsnprintf( szBuf, _countof(szBuf), szString, va ); va_end( va ); return std::string( szBuf ); } void KUIControlEdit::SetReSize( const KRect &rcNewRect ) { KUIWnd::OnSizeChangeNofity( rcNewRect); _reArrangeRect(); _initPhrase(); _DrawReadingCandidate(); std::string strTemp = StrFormat( "<#%02x%02x%02x>%s", m_nFontSize, m_Color.r, m_Color.g, m_Color.b, m_sCaption.c_str() ); // 2010.06.24 - prodongi //m_pCaptionPhrase->AddString(strTemp.c_str(), m_bTagEnable, true); m_pCaptionPhrase->AddString(strTemp.c_str(), m_bTagEnable, true, true, true, m_EditboxInfo.isScroll()); } 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); // m_pCaptionPhrase = new KTextPhrase(m_rcCaptionArea.right - m_rcCaptionArea.left, m_rcCaptionArea.bottom - m_rcCaptionArea.top ); m_pCaptionPhrase = new KTextLayout2(m_rcCaptionArea.right - m_rcCaptionArea.left, m_rcCaptionArea.bottom - m_rcCaptionArea.top ); 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 KTextLayout2(/*m_rcCaptionArea.right - m_rcCaptionArea.left+*/512, (m_rcCaptionArea.bottom - m_rcCaptionArea.top)*2 ); //m_pCandidatePhrase->SetPosition(m_rcCaptionArea.left, m_rcRegion.top + m_rcCaptionArea.bottom - m_rcCaptionArea.top +3,m_fZPos); m_pCandidatePhrase->SetAlign( m_dwCaptionAlign); SAFE_DELETE(m_pReadingPhrase); m_pReadingPhrase = new KTextLayout2(m_rcCaptionArea.right - m_rcCaptionArea.left, m_rcCaptionArea.bottom - m_rcCaptionArea.top ); //m_pCandidatePhrase->SetPosition(m_rcCaptionArea.left, m_rcRegion.top + m_rcCaptionArea.bottom - m_rcCaptionArea.top + 3 ,m_fZPos); m_pReadingPhrase->SetAlign( m_dwCaptionAlign); // 2010.06.24 - prodongi m_EditboxInfo.setMaxWidth(m_pCaptionPhrase->GetWidth()); m_EditboxInfo.setBold(false); m_EditboxInfo.setAlign(m_dwCaptionAlign); m_EditboxInfo.setSpacing(m_pCaptionPhrase->GetSpacing()); } 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] 경매장 구현 } } LPCSTR KUIControlEdit::GetText() { _UpdateEditText(); wchar_t wbuff[1024]; char buff[1024]; wbuff[0] = 0; buff[0] = 0; // 2010.06.24 - prodongi //int nPos = m_EditboxInfo.GetInputBuffer( wbuff, 1024 ); int nPos = m_EditboxInfo.GetInputBufferOri( wbuff, 1024 ); wbuff[ nPos ] = 0; if( !wbuff[0] ) return ""; buff[ WideCharToMultiByte(g_pGameOperationManager->GetDefaultCodePage(),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; } } // 임시 태그 막기 ... 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: { if( !i->second->OnMessage( hWnd, uMsg, wParam, lParam ) ) { //// { [sonador][3.1.3]경매장 서버 연동-Delete키->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); } 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.24 - 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.24 - 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) { text_len = WideCharToMultiByte(g_pGameOperationManager->GetDefaultCodePage(),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 조건이 달라진다. //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; // ******* 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(); std::string strTemp = StrFormat( "<#%02x%02x%02x>%s", m_nFontSize, m_Color.r, m_Color.g, m_Color.b, m_sCaption.c_str() ); // 2010.06.24 - prodongi m_pCaptionPhrase->AddString( strString.c_str(), 0.0f, m_bTagEnable, true, true, m_EditboxInfo.isScroll() ); //m_pCaptionPhrase->AddString(strTemp.c_str(), m_bTagEnable, true); /* int newLineCount = m_pCaptionPhrase->GetLineNumber(); //라인이 바뀌었는지 위로 통보(크기 변경등에 사용) if( m_bLineChange && oldLineCount != newLineCount) { PumpUpMessage( GetID(), KEDIT_LINE_CHANGE, oldLineCount, newLineCount ); } */ } } // 2010.06.24 - 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,sizeof(w_text)); memcpy(w_temptext,w_text,sizeof(wchar_t)*pos-1); KTextPhrase::GetTextWidth(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 && beginGetDefaultCodePage(), begin, 0); ZeroMemory(tmp,sizeof(tmp)); memcpy(tmp,begin,sizeof(wchar_t)*(next-begin)); ::sprintf( temptext , "<#FFFFFF>%s",tmp ); m_pReadingPhrase->Clear(); m_pReadingPhrase->SetPosition(cx, cy-40,0); m_pReadingPhrase->AddString( temptext,m_bTagEnable, true ); MultiByteToWideChar(g_pGameOperationManager->GetDefaultCodePage(),0,temptext,strlen(temptext),cbuff,1024); KTextPhrase::GetTextWidth(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; KTextPhrase::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[2] = {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,sizeof(inputbuffer)); if( m_bPassword ) { //for( int i = 0; i < inputlen; ++i ) inputbuffer[i] = '*'; } complen = m_IMEInput.GetComp(compbuffer,sizeof(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}-조합버퍼에 조합중인 버퍼가 없을때 cursorlen=1; memcpy(cursorbuffer,&inputbuffer[cursorpos-1],sizeof(wchar_t)); 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; } // 2011. 11. 2 - marine void KUIControlEdit::SetSpaceLimit(bool bFlag) { m_IMEInput.SetSpaceLimit(bFlag); } void KUIControlEdit::SetPasteLimit(bool bFlag) { m_bPasteLimit = bFlag; } 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,}; 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