Files
2026-06-01 12:46:52 +02:00

1378 lines
34 KiB
C++

#include "stdafx.h"
#ifndef _COUNTRY_ME_
#include "../KTextParser.h"
#include "../KTextPhrase.h"
#include "KUIWndManager.h"
#include "KUIControlEdit.h"
#include <dump/XException.h>
#include "Imm.h"
#include <toolkit/nsluni.h>
#include <toolkit/SafeTickCount.h>
#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 = "<font:\"돋움\">";
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 = "<font:";
m_strFontTag += lpszFontName;
m_strFontTag += ">";
// 2010.06.07 - prodongi
m_EditboxInfo.setFontName(lpszFontName);
}
// }
// 2010.06.07 - prodongi
void KUIControlEdit::SetFontSize(int nSize)
{
m_nFontSize = nSize;
m_EditboxInfo.setFontSize(nSize);
}
// 2010.06.08 - prodongi
void KUIControlEdit::setEditBoxScroll(bool scroll)
{
m_EditboxInfo.setScroll(scroll);
}
void KUIControlEdit::SetOnlyNumber(bool bEnable)
{
m_IMEInput.SetOnlyNum(bEnable);
}
// 2011. 11. 2 - marine
void KUIControlEdit::SetSpaceLimit(bool bFlag)
{
m_IMEInput.SetSpaceLimit(bFlag);
}
void KUIControlEdit::SetPasteLimit(bool bFlag)
{
m_bPasteLimit = bFlag;
}
void KUIControlEdit::SetPrefixString(LPCSTR lpszPrefix)
{
m_sPrefixString = lpszPrefix;
// _oprint( "++++KUIControlEdit::SetPrefixString %s\n",m_sPrefixString.c_str() );
_UpdateEditText();
}
void KUIControlEdit::PostWndMsgToFocusEdit( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( NULL != s_hWndCurrentFocus )
{
// _oprint( "edit control(%u)에 윈도우 메시지를 보냅니다.\n", s_hWndCurrentFocus );
::PostMessage( s_hWndCurrentFocus, uMsg, wParam, lParam );
}
}
LRESULT CALLBACK KUIControlEdit::EditBoxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( uMsg == WM_CONTEXTMENU )
{
return 0;
}
if( uMsg == WM_SYSKEYDOWN )
{
if( wParam == VK_F4 ) return 0;
}
HandleMap::iterator i = KUIControlEdit::m_mapEditControl.find(hWnd);
int nRet = 0;
// Keyboard Message를 전달
if(i != KUIControlEdit::m_mapEditControl.end() )
{
switch( uMsg )
{
case WM_IME_STARTCOMPOSITION : _performance_print( "2 WM_IME_STARTCOMPOSITION %d\n", wParam ); break;
case WM_IME_ENDCOMPOSITION : _performance_print( "2 WM_IME_ENDCOMPOSITION %d\n", wParam ); break;
case WM_IME_COMPOSITION : _performance_print( "2 WM_IME_COMPOSITION %d\n", wParam ); break;
case WM_IME_SETCONTEXT : _performance_print( "2 WM_IME_SETCONTEXT %d\n", wParam ); break;
case WM_IME_NOTIFY : _performance_print( "2 WM_IME_NOTIFY %d\n", wParam ); break;
case WM_IME_CONTROL : _performance_print( "2 WM_IME_CONTROL %d\n", wParam ); break;
case WM_IME_COMPOSITIONFULL : _performance_print( "2 WM_IME_COMPOSITIONFULL %d\n", wParam ); break;
case WM_IME_SELECT : _performance_print( "2 WM_IME_SELECT %d\n", wParam ); break;
case WM_IME_CHAR : _performance_print( "2 WM_IME_CHAR %d\n", wParam ); break;
case WM_IME_REQUEST : _performance_print( "2 WM_IME_REQUEST %d\n", wParam ); break;
case WM_IME_KEYDOWN : _performance_print( "2 WM_IME_KEYDOWN %d\n", wParam ); break;
case WM_IME_KEYUP : _performance_print( "2 WM_IME_KEYUP %d\n", wParam ); break;
}
// Process Enter to call SendMessage
if(uMsg == WM_CHAR) //WM_CHAR 는 VK_PRIOR, VK_NEXT, VK_UP,VK_DOWN 들은 쓸 수 없다;;;
{
int nCount = 0;
while(1)
{
if(wParam == KUIControlEdit::m_dwSysKey[nCount] )
{
i->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(); i<count; ++i, ++k)
{
char text[16] = { 0, };
int textLen = m_IMEInput.GetCandidate(i, text, _countof(text));
char tmp[32] = { 0, };
if(i == m_IMEInput.GetCandidateSelection()) sprintf( tmp, "%d.%s ", k, text );
else sprintf( tmp, "%d.%s ", k, text );
//SetBkColor(hdc, 0x00FFCFCF); } else {
//SetBkColor(hdc, 0x00FF7F7F);
strCandidate += tmp;
}
if( strCandidate.size() ) m_pCandidatePhrase->AddString( strCandidate.c_str() );
*/
int nStringSize = static_cast<int>(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, "<inv>%s</inv>", buf );
str.replace( nSelS-nStartIndex, nLen, buff );
strcpy( buff, str.c_str() );
}
else
{
int pos = nSelS - nStartIndex;
int len = static_cast<int>(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, "<u>%s</u>", pszSubStr );
str.replace( pos, nCharCount, buff );
strcpy( buff, str.c_str() );
delete pszSubStr;
}
else
strcat( buff, "<u> </u>" );
}
}
else
strcat( buff, "<u> </u>" );
}
*/
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<end; ++i)
{
char* next = CharNextExA(GET_CODEPAGE(), begin, 0);
ZeroMemory(tmp,sizeof(tmp));
memcpy(tmp,begin,sizeof(wchar_t)*(next-begin));
::sprintf( temptext , "<#FFFFFF><inv>%s</inv>",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<count; ++i, ++k)
{
char text[256] = { 0, };
int textLen = m_IMEInput.GetCandidate(i, text, _countof(text));
char tmp[256] = { 0, };
if(i == m_IMEInput.GetCandidateSelection())
::sprintf( tmp, "<#ff0000>%d.%s<#000000> ", k, text );
else
::sprintf( tmp, "%d.%s ", k, text );
strCandidate += tmp;
}
if( strCandidate.size() )
{
std::string strTmp = "<font:\"돋움\"><size:9><inv>";
strTmp += strCandidate;
strTmp += "</inv>";
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( "<font:\"돋움\">", 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"<inv>";
const wchar_t *szCursorEnd = L"</inv>";
if( m_bCursorBlink )
{
szCursorBegin = L"";//<B>";
szCursorEnd = L"";//</B>";
}
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"<inv>%s</inv>", 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