DragonNest/Common/EtInterface/EtUIEditBox.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

1832 lines
No EOL
48 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "EtUIEditBox.h"
#include "EtUIDialog.h"
#include "EtUIIME.h"
#include "StringUtil.h"
#include "strsafe.h"
#include "EtUINameLinkMgr.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
SUICoord CEtUIEditBox::s_CurrentCaretPos;
std::vector<WCHAR> CEtUIEditBox::s_vecInvalidCharater;
bool CEtUIEditBox::s_bCheckThaiLanguageVowelRule = false;
CEtUIEditBox::CEtUIEditBox( CEtUIDialog *pParent )
: CEtUIControl( pParent )
{
m_Property.UIType = UI_CONTROL_EDITBOX;
m_bCaretOn = true;
m_fCaretBlinkTime = GetCaretBlinkTime() * 0.001f;
QueryPerformanceCounter( &m_liLastBlinkTime );
m_nFirstVisible = 0;
m_nLastVisible = 0;
m_nCaret = 0;
m_FullTextCaret = 0;
m_nSelStart = 0;
m_bInsertMode = true;
m_bMouseDrag = false;
m_fCompositionWidth = 0.0f;
m_nFilterOption = 0;
m_RenderTextColor = 0;
}
CEtUIEditBox::~CEtUIEditBox(void)
{
}
void CEtUIEditBox::Initialize( SUIControlProperty *pProperty )
{
CEtUIControl::Initialize( pProperty );
UpdateRects();
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
}
void CEtUIEditBox::SetTemplate( int nTemplateIndex )
{
CEtUIControl::SetTemplate( nTemplateIndex );
SUIElement *pElement(NULL);
pElement = GetElement(0);
//if( pElement )
//{
// ID3DXFont *pFont = m_pParent->GetFont( pElement->nFontIndex, pElement->nFontHeight );
// SetFont( pFont );
//}
if( m_Property.EditBoxProperty.dwMaxChars == 0 )
m_Property.EditBoxProperty.dwMaxChars = 256;
SetMaxEditLength( m_Property.EditBoxProperty.dwMaxChars );
}
void CEtUIEditBox::Focus( bool bFocus )
{
CEtUIControl::Focus( bFocus );
CEtUIControl::SetFocusEditBox( IsFocus() );
ResetCaretBlink();
if( IsFocus() )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_FOCUS, true, this );
}
else
{
m_pParent->ProcessCommand( EVENT_EDITBOX_RELEASEFOCUS, true, this );
SetSelection(GetCaretPos(), GetCaretPos());
}
}
void CEtUIEditBox::SetText( LPCWSTR wszText, bool bSelected )
{
ASSERT( wszText != NULL );
const CEtUINameLinkMgr& nameLinkMgr = EtInterface::GetNameLinkMgr();
std::wstring translated = wszText;
if (translated.empty() == false)
nameLinkMgr.TranslateText(translated, wszText);
if( m_Buffer.SetText( translated.c_str() ) )
m_FullTextBuffer.SetText( wszText );
m_nFirstVisible = 0;
PlaceCaret( m_Buffer.GetTextSize() );
if( bSelected )
{
m_nSelStart = 0;
}
else
{
m_nSelStart = m_nCaret;
}
}
void CEtUIEditBox::AddText( LPCWSTR wszText, bool bFocus )
{
ASSERT( wszText != NULL );
std::wstring translated;
int pureTextLength = EtInterface::GetNameLinkMgr().TranslateText( translated, wszText );
if( m_Buffer.IsEnableInsertString( m_nCaret, translated.c_str() ) &&
m_FullTextBuffer.IsEnableInsertString( m_FullTextCaret, wszText ) )
{
m_Buffer.InsertString( m_nCaret, translated.c_str(), -1, true );
m_FullTextBuffer.InsertString( m_FullTextCaret, wszText, -1, true );
PlaceCaret( m_nCaret + pureTextLength );
m_nSelStart = m_nCaret;
if( bFocus && m_bFocus == false )
m_pParent->RequestFocus( this );
}
}
HRESULT CEtUIEditBox::GetTextCopy( LPWSTR strDest, UINT bufferCount )
{
ASSERT( strDest );
if( bufferCount != 0 ) {
//wcscpy_s( strDest, bufferCount, m_Buffer.GetBuffer() );
StringCchCopyW(strDest, bufferCount, m_Buffer.GetBuffer());
}
return S_OK;
}
void CEtUIEditBox::ClearText()
{
m_FullTextBuffer.Clear();
m_Buffer.Clear();
m_RenderBuffer.Clear();
m_nFirstVisible = 0;
PlaceCaret( 0 );
m_nSelStart = 0;
}
void CEtUIEditBox::ClearTextMemory()
{
m_FullTextBuffer.ClearMemory();
m_Buffer.ClearMemory();
m_RenderBuffer.ClearMemory();
m_nFirstVisible = 0;
PlaceCaret( 0 );
m_nSelStart = 0;
}
int CEtUIEditBox::GetTextToInt()
{
const WCHAR *pBuffer = m_Buffer.GetBuffer();
if( pBuffer )
{
if( wcslen( pBuffer ) == 0 )
return -1;
return _wtoi( pBuffer );
}
return 0;
}
void CEtUIEditBox::SetIntToText( int nValue )
{
WCHAR wszBuffer[256]={0};
_itow( nValue, wszBuffer, 10 );
SetText( wszBuffer, false );
}
INT64 CEtUIEditBox::GetTextToInt64()
{
const WCHAR *pBuffer = m_Buffer.GetBuffer();
if( pBuffer )
{
return _wtoi64( pBuffer );
}
return 0;
}
void CEtUIEditBox::SetInt64ToText( INT64 nValue )
{
WCHAR wszBuffer[256]={0};
_i64tow( nValue, wszBuffer, 10 );
SetText( wszBuffer, false );
}
#define IN_FLOAT_CHARSET( c ) \
( (c) == L'-' || (c) == L'.' || ( (c) >= L'0' && (c) <= L'9' ) )
void CEtUIEditBox::ParseFloatArray( float *pNumbers, int nCount )
{
int nWritten;
const WCHAR *pToken, *pEnd;
WCHAR wszToken[ 60 ];
nWritten = 0;
pToken = m_Buffer.GetBuffer();
while( ( nWritten < nCount ) && ( *pToken != L'\0' ) )
{
while( *pToken == L' ' )
{
pToken++;
}
if( *pToken == L'\0' )
{
break;
}
// Locate the end of number
pEnd = pToken;
while( IN_FLOAT_CHARSET( *pEnd ) )
{
pEnd++;
}
int nTokenLen;
nTokenLen = min( sizeof( wszToken ) / sizeof( wszToken[ 0 ] ) - 1, int( pEnd - pToken ) );
wcscpy_s( wszToken, nTokenLen, pToken );
*pNumbers = ( float )wcstod( wszToken, NULL );
nWritten++;
pNumbers++;
pToken = pEnd;
}
}
void CEtUIEditBox::SetTextFloatArray( const float *pNumbers, int nCount )
{
WCHAR wszBuffer[ 512 ] = { 0 };
WCHAR wszTmp[ 64 ];
if( pNumbers == NULL )
{
return;
}
int i;
for( i = 0; i < nCount; i++ )
{
swprintf_s( wszTmp, 64, L"%.4f ", pNumbers[i] );
wcscat_s( wszBuffer, 512, wszTmp );
}
if( ( nCount > 0 ) && ( wcslen( wszBuffer ) > 0 ) )
{
wszBuffer[ wcslen( wszBuffer ) - 1 ] = 0;
}
SetText( wszBuffer );
}
bool CEtUIEditBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( !IsEnable() || !IsShow() || !IsKeyLock())
{
return false;
}
bool bHandled(false);
if( uMsg == WM_KEYDOWN )
{
switch( wParam )
{
case VK_HOME:
PlaceCaret( 0 );
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_END:
PlaceCaret( m_Buffer.GetTextSize() );
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_INSERT:
if( GetKeyState( VK_CONTROL ) < 0 )
{
CopyToClipboard();
}
else if( GetKeyState( VK_SHIFT ) < 0 )
{
PasteFromClipboard();
}
else
{
m_bInsertMode = !m_bInsertMode;
}
break;
case VK_DELETE:
if( m_nCaret != m_nSelStart )
{
DeleteSelectionText();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
else
{
if (RemoveChar(m_nCaret, 1))
{
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
}
ResetCaretBlink();
bHandled = true;
break;
case VK_LEFT:
if( GetKeyState( VK_CONTROL ) < 0 )
{
// Note : <20>ѱۿ<D1B1><DBBF><EFBFBD><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵȴ<C8B5>. <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20><> <20><>...
m_Buffer.GetPriorItemPos( m_nCaret, &m_nCaret );
PlaceCaret( m_nCaret );
}
else if( m_nCaret > 0 )
{
PlaceCaret( GetPrevCaret() );
}
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_RIGHT:
if( GetKeyState( VK_CONTROL ) < 0 )
{
m_Buffer.GetNextItemPos( m_nCaret, &m_nCaret );
PlaceCaret( m_nCaret );
}
else if( m_nCaret < m_Buffer.GetTextSize() )
{
PlaceCaret( GetNextCaret() );
}
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_UP:
if( GetKeyState( VK_SHIFT ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_SHIFT_KEYUP, true, this );
}
else if ( GetKeyState( VK_LCONTROL ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_LCTRL_KEYUP, true, this );
}
else
{
m_pParent->ProcessCommand( EVENT_EDITBOX_KEYUP, true, this );
}
bHandled = true;
break;
case VK_DOWN:
if( GetKeyState( VK_SHIFT ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_SHIFT_KEYDOWN, true, this );
}
else if ( GetKeyState( VK_LCONTROL ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_LCTRL_KEYDOWN, true, this );
}
else
{
m_pParent->ProcessCommand( EVENT_EDITBOX_KEYDOWN, true, this );
}
bHandled = true;
break;
case VK_ESCAPE:
m_pParent->ProcessCommand( EVENT_EDITBOX_ESCAPE, true, this );
bHandled = true;
break;
case VK_TAB:
break;
default:
bHandled = wParam != VK_ESCAPE;
}
}
return bHandled;
}
bool CEtUIEditBox::HandleMouse( UINT uMsg, float fX, float fY, WPARAM wParam, LPARAM lParam )
{
if( !IsEnable() || !IsShow() || !IsKeyLock())
{
return false;
}
switch( uMsg )
{
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
{
if( !m_bFocus )
{
m_pParent->RequestFocus( this );
}
if( !IsInside( fX, fY ) )
{
return false;
}
m_bMouseDrag = true;
SetCapture( m_pParent->GetHWnd() );
int nCP, nTrail, nX1st;
CEtFontMng& FontMng = CEtFontMng::GetInstance();
SUIElement* pElement = GetElement( 0 );
nX1st = FontMng.GetCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible );
//m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st );
nCP = FontMng.GetCaretFromCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight,
( int )( m_pParent->GetScreenWidth() * ( fX - m_TextCoord.fX ) + nX1st ), nTrail );
// nTrail <20>̶<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD> <20>;<EFBFBD><CDBE>ϴ<EFBFBD><CFB4><EFBFBD> <20><><EFBFBD>θ<EFBFBD> <20>˷<EFBFBD><CBB7>ִ<EFBFBD> <20><><EFBFBD>̴<EFBFBD>
if( 0 <= nCP )
//if( SUCCEEDED( m_Buffer.XtoCP( ( int )( m_pParent->GetScreenWidth() * ( fX - m_TextCoord.fX ) + nX1st ), &nCP, &nTrail ) ) )
{
if( ( nTrail ) && ( nCP < m_Buffer.GetTextSize() ) )
{
PlaceCaret( nCP + 1 );
}
else
{
PlaceCaret( nCP );
}
m_nSelStart = m_nCaret;
ResetCaretBlink();
}
return true;
}
case WM_LBUTTONUP:
ReleaseCapture();
m_bMouseDrag = false;
break;
case WM_MOUSEMOVE:
if( m_bMouseDrag )
{
int nCP, nTrail, nX1st;
CEtFontMng& FontMng = CEtFontMng::GetInstance();
SUIElement* pElement = GetElement( 0 );
nX1st = FontMng.GetCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible );
//m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st );
nCP = FontMng.GetCaretFromCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight,
( int )( m_pParent->GetScreenWidth() * (fX-GetUICoord().fX) + nX1st ), nTrail );
if( 0 <= nCP )
//if( SUCCEEDED( m_Buffer.XtoCP( ( int )( m_pParent->GetScreenWidth() * fX + nX1st ), &nCP, &nTrail ) ) )
{
if( ( nTrail ) && ( nCP < m_Buffer.GetTextSize() ) )
{
PlaceCaret( nCP + 1 );
}
else
{
PlaceCaret( nCP );
}
}
}
break;
}
return false;
}
bool CEtUIEditBox::InsertChar(WCHAR wChar)
{
if( m_Buffer.IsEnableInsertChar( m_nCaret, wChar ) &&
m_FullTextBuffer.IsEnableInsertChar( m_FullTextCaret, wChar ) )
{
m_Buffer.InsertChar( m_nCaret, wChar, true );
m_FullTextBuffer.InsertChar( m_FullTextCaret, wChar, true );
return true;
}
return false;
}
bool CEtUIEditBox::OverTypeChar(WCHAR wChar)
{
if (RemoveChar(m_nCaret, 1))
return InsertChar(wChar);
return false;
}
void CEtUIEditBox::GetFullTextTagFieldPos(int& tagFieldStart, int& tagFieldEnd, int curCursorPos) const
{
std::wstring fullText = m_FullTextBuffer.GetBuffer();
std::wstring targetTag;
std::wstring::size_type tagStart, tagEnd;
tagStart = tagEnd = std::wstring::npos;
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_START);
tagStart = fullText.rfind(targetTag, curCursorPos);
if (tagStart != std::wstring::npos)
{
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_END);
tagEnd = fullText.find(targetTag, tagStart);
if (int(tagStart) <= curCursorPos && curCursorPos < int(tagEnd))
{
tagFieldStart = int(tagStart);
tagFieldEnd = int(tagEnd);
}
}
}
bool CEtUIEditBox::RemoveChar(int startCaretPos, int length)
{
int tempS, tempE;
tempS = tempE = -1;
int fullTextStartCaretPos = GetFullTextCaretPos(startCaretPos, false);
GetFullTextTagFieldPos(tempS, tempE, fullTextStartCaretPos);
fullTextStartCaretPos = (tempS == -1) ? fullTextStartCaretPos : tempS;
tempS = tempE = -1;
int endCaretPos = startCaretPos + length;
int fullTextEndCaretPos = GetFullTextCaretPos(endCaretPos, false);
GetFullTextTagFieldPos(tempS, tempE, fullTextEndCaretPos);
fullTextEndCaretPos = (tempE == -1) ? fullTextEndCaretPos : tempE;
int processingCaretPos = fullTextStartCaretPos;
int i = 0;
for (; i < fullTextEndCaretPos - fullTextStartCaretPos;)
{
std::wstring fullText = m_FullTextBuffer.GetBuffer();
if (fullText.size() <= 0)
break;
std::wstring targetTag;
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_START);
if (processingCaretPos >= 0)
{
std::wstring::size_type tagStart = std::wstring::npos;
if (EtInterface::GetNameLinkMgr().IsTagType(fullText, processingCaretPos, CEtUINameLinkMgr::eNLTAG_START))
tagStart = (std::wstring::size_type)processingCaretPos;
if (tagStart == std::wstring::npos && processingCaretPos > 0)
tagStart = fullText.rfind(targetTag, processingCaretPos - 1);
if (tagStart != std::wstring::npos)
{
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_END);
std::wstring::size_type tagEnd = fullText.find(targetTag, tagStart);
int calculatedTagEnd = int(tagEnd) + 2;
if (int(tagStart) <= processingCaretPos && processingCaretPos <= int(tagEnd))
{
fullText.erase(tagStart, calculatedTagEnd - tagStart);
SetText(fullText.c_str(), false);
processingCaretPos = (int)tagStart;
i += calculatedTagEnd - int(tagStart);
continue;
}
}
}
int textCaretPos = GetTextCaretPos(processingCaretPos);
if( m_Buffer.RemoveChar(textCaretPos) == false ||
m_FullTextBuffer.RemoveChar(processingCaretPos) == false )
{
_ASSERT(0);
return false;
}
++i;
}
PlaceCaret(GetTextCaretPos(processingCaretPos));
m_nSelStart = m_nCaret;
return true;
}
bool CEtUIEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( !IsEnable() || !IsShow() || !IsKeyLock() )
{
return false;
}
switch( uMsg )
{
case WM_KEYUP:
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_RETURN:
m_pParent->ProcessCommand( EVENT_EDITBOX_STRING, true, this, (UINT)wParam );
return true;
}
break;
case WM_CHAR:
switch( ( WCHAR )wParam )
{
// Ctrl+<2B><EFBFBD><E9BDBA><EFBFBD>̽<EFBFBD><CCBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> <20>˾ƺ<CBBE><C6BA><EFBFBD> 0x7f<37>ε<EFBFBD> <20>ѱ۹<D1B1><DBB9><EFBFBD><EFBFBD><EFBFBD> <20>ƴϰ<C6B4> <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD>ڴ<EFBFBD>.
// DxCustomUI<55><49> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>Ŷ<EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD>Ƶα<C6B5><CEB1><EFBFBD> <20>Ѵ<EFBFBD>.
case 0x7f:
break;
// Ctrl+h<><68> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WM_CHAR<41><52> 0x08<30><38> <20><><EFBFBD>ԵǼ<D4B5> <20><><EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
// <20>ذ<EFBFBD><D8B0>ϱ<EFBFBD> <20><><EFBFBD>ؼ<EFBFBD>,
// VK_BACK<43><4B> WM_KEYDOWN<57><4E><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD>(<28>̶<EFBFBD> WM_CHAR-VK_BACK<43><4B><EFBFBD><EFBFBD> <20>ƹ<EFBFBD><C6B9>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> break)
// H<><48> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD> <20>˻<EFBFBD>.
// <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD>.
case VK_BACK:
if( GetKeyState('H')&0x80 )
break;
if( m_nCaret != m_nSelStart )
{
DeleteSelectionText();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
else if( m_nCaret > 0 )
{
PlaceCaret( m_nCaret - 1 );
m_nSelStart = m_nCaret;
RemoveChar(m_nCaret, 1);
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
ResetCaretBlink();
break;
case 24: // Ctrl-X Cut
case VK_CANCEL: // Ctrl-C Copy
CopyToClipboard();
if( ( WCHAR )wParam == 24 )
{
DeleteSelectionText();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
break;
case 22: // Ctrl-V Paste
PasteFromClipboard();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
break;
case 1: // Ctrl-A Select All
if( m_nSelStart == m_nCaret )
{
m_nSelStart = 0;
PlaceCaret( m_Buffer.GetTextSize() );
}
break;
case VK_RETURN:
// m_pParent->ProcessCommand( EVENT_EDITBOX_STRING, true, this, (UINT)wParam );
// break;
// Junk characters we don't want in the string
case 26: // Ctrl Z
case 2: // Ctrl B
case 14: // Ctrl N
case 19: // Ctrl S
case 4: // Ctrl D
case 6: // Ctrl F
case 7: // Ctrl G
case 10: // Ctrl J
case 11: // Ctrl K
case 12: // Ctrl L
case 17: // Ctrl Q
case 23: // Ctrl W
case 5: // Ctrl E
case 18: // Ctrl R
case 20: // Ctrl T
case 25: // Ctrl Y
case 21: // Ctrl U
case 9: // Ctrl I
case 15: // Ctrl O
case 16: // Ctrl P
case 27: // Ctrl [
case 29: // Ctrl ]
case 28: // Ctrl \
break;
default:
// <20>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD> <20><>ȯó<C8AF><C3B3>
ProcessHalfWidth( wParam );
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>
if( !CheckValidCharacter( (WCHAR)wParam ) )
break;
if( s_bCheckThaiLanguageVowelRule )
{
if( !CheckThaiLanguageVowelRule( (WCHAR)wParam ) )
break;
}
if( m_Property.UIType == UI_CONTROL_EDITBOX )
{
if( m_Property.EditBoxProperty.bOnlyDigit && !iswdigit( (WCHAR)wParam ) )
{
break;
}
}
bool bFiltering = false;
if (m_nFilterOption != 0)
{
if (m_nFilterOption & eDIGIT)
{
if (iswdigit((WCHAR)wParam))
bFiltering = true;
}
if (m_nFilterOption & eALPHABET)
{
if (iswalpha((WCHAR)wParam))
bFiltering = true;
}
if (bFiltering == false)
break;
}
if( m_nCaret != m_nSelStart )
{
DeleteSelectionText();
}
if( ( !m_bInsertMode ) && ( m_nCaret < m_Buffer.GetTextSize() ) )
{
if (OverTypeChar((WCHAR)wParam))
{
PlaceCaret(m_nCaret + 1);
m_nSelStart = m_nCaret;
}
}
else
{
if (InsertChar((WCHAR)wParam))
{
PlaceCaret( m_nCaret + 1 );
//UpdateLastVisible();
m_nSelStart = m_nCaret;
}
}
ResetCaretBlink();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
return true;
}
return false;
}
void CEtUIEditBox::ProcessHalfWidth(WPARAM &wParam)
{
const int nOffset = 0xFEE0;
if( (WCHAR)wParam >= 0x0041+nOffset && (WCHAR)wParam <= 0x005A+nOffset ) // L'A' ~ L'Z'
wParam -= nOffset;
else if( (WCHAR)wParam >= 0x0061+nOffset && (WCHAR)wParam <= 0x007A+nOffset ) // L'a' ~ L'z'
wParam -= nOffset;
else if( (WCHAR)wParam >= 0x0030+nOffset && (WCHAR)wParam <= 0x0039+nOffset ) // L'0' ~ L'9'
wParam -= nOffset;
}
bool CEtUIEditBox::CheckValidCharacter( WCHAR wChar )
{
for( DWORD dwIndex = 0; dwIndex < (DWORD)s_vecInvalidCharater.size(); ++dwIndex )
{
if( s_vecInvalidCharater[dwIndex] == wChar )
return false;
}
return true;
}
void CEtUIEditBox::AddInvalidCharacter( wchar_t wCharStart, wchar_t wCharEnd )
{
if( static_cast<DWORD>(wCharStart) > static_cast<DWORD>(wCharEnd) )
return;
for( DWORD dwIndex = static_cast<DWORD>(wCharStart); dwIndex <= static_cast<DWORD>(wCharEnd); ++dwIndex )
s_vecInvalidCharater.push_back( (WCHAR)dwIndex );
}
void CEtUIEditBox::UpdateRects()
{
m_TextCoord = m_Property.UICoord;
m_TextCoord.fX += m_Property.EditBoxProperty.fBorder;
m_TextCoord.fWidth -= m_Property.EditBoxProperty.fBorder * 2;
m_TextCoord.fY += m_Property.EditBoxProperty.fBorder;
m_TextCoord.fHeight -= m_Property.EditBoxProperty.fBorder * 2;
m_RenderCoord[ 0 ] = m_TextCoord;
m_RenderCoord[ 1 ].SetCoord( m_Property.UICoord.fX, m_Property.UICoord.fY, m_TextCoord.fX - m_Property.UICoord.fX, m_Property.UICoord.fHeight );
m_RenderCoord[ 2 ].SetCoord( m_TextCoord.Right(), m_Property.UICoord.fY, m_Property.UICoord.Right() - m_TextCoord.Right(), m_Property.UICoord.fHeight );
m_RenderCoord[ 3 ].SetCoord( m_TextCoord.fX, m_Property.UICoord.fY, m_TextCoord.fWidth, m_TextCoord.fY - m_Property.UICoord.fY );
m_RenderCoord[ 4 ].SetCoord( m_TextCoord.fX, m_TextCoord.Bottom(), m_TextCoord.fWidth, m_Property.UICoord.Bottom() - m_TextCoord.Bottom() );
m_TextCoord.fX += m_Property.EditBoxProperty.fSpace;
m_TextCoord.fWidth -= m_Property.EditBoxProperty.fSpace * 2;
m_TextCoord.fY += m_Property.EditBoxProperty.fSpace;
m_TextCoord.fHeight -= m_Property.EditBoxProperty.fSpace * 2;
}
void CEtUIEditBox::RenderText(float fElapsedTime, SUIElement* pElement, const SUICoord& TempCoord, bool bNeedDivide)
{
// EditBox <20>۾<EFBFBD><DBBE><EFBFBD><EFBFBD><EFBFBD> wordbreak<61><6B> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
bool bFontMngWordBreak = CEtFontMng::s_bUseWordBreak;
CEtFontMng::s_bUseWordBreak = false;
//pElement = GetElement(0);
if (pElement)
{
pElement->TextureColor.Blend( m_CurrentState, fElapsedTime, m_fBlendRate );
pElement->FontColor.Blend( m_CurrentState, fElapsedTime, m_fBlendRate );
pElement->ShadowFontColor.Blend( m_CurrentState, fElapsedTime, m_fBlendRate );
if (false == bNeedDivide)
{
SUICoord drawCoord = TempCoord;
DrawTextWithTraslation(m_FullTextBuffer.GetBuffer(), pElement, drawCoord);
}
else
{
wstring strBuf = m_RenderBuffer.GetBuffer() + m_nFirstVisible;
wstring strFormer = strBuf.substr( 0, (m_nCaret-m_nFirstVisible) );
wstring strLatter = strBuf.substr( max(0, min((int)strBuf.length(), m_nCaret-m_nFirstVisible)), strBuf.length()-(m_nCaret-m_nFirstVisible) );
SUICoord FormerCoord = TempCoord;
SUICoord LatterCoord = TempCoord;
SUICoord WidthCoord; // <20>ʺ<EFBFBD><CABA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӽ÷<D3BD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>
m_pParent->DrawDlgText( strFormer.c_str(), pElement,
m_Property.EditBoxProperty.dwTextColor, FormerCoord, -1, pElement->dwFontFormat, true );
m_pParent->CalcTextRect( strFormer.c_str(), pElement, WidthCoord );
LatterCoord.fX += (WidthCoord.fWidth + m_fCompositionWidth);
m_pParent->DrawDlgText( strLatter.c_str(), pElement,
m_Property.EditBoxProperty.dwTextColor, LatterCoord, -1, pElement->dwFontFormat, true );
}
}
CEtFontMng::s_bUseWordBreak = bFontMngWordBreak;
}
void CEtUIEditBox::Render( float fElapsedTime )
{
if( !IsShow() )
return;
//HRESULT hr;
int nSelStartX(0), nCaretX(0);
SUIElement *pElement = NULL;
// Note : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ䰡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <09><><EFBFBD>߿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǹ<EFBFBD> <20>ּ<EFBFBD><D6BC><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
//pElement = &m_Template.m_vecElement[ 0 ];
//if( pElement )
//{
// m_Buffer.SetFont( m_pParent->GetFont( pElement->nFontIndex ) );
// PlaceCaret( m_nCaret );
//}
UpdateBlendRate();
int nVecSize = (int)m_Template.m_vecElement.size();
for( int i = 0; i < nVecSize; i++ )
{
pElement = GetElement(i);
if( !m_bFocus )
{
if (IsEnable() == false)
pElement->TextureColor.Blend( UI_STATE_DISABLED, fElapsedTime, 0.5f );
else
pElement->TextureColor.Blend( UI_STATE_NORMAL, fElapsedTime, m_fBlendRate );
}
else
{
pElement->TextureColor.Blend( UI_STATE_FOCUS, fElapsedTime, m_fBlendRate );
}
if( m_bExistTemplateTexture )
m_pParent->DrawSprite( m_Template.m_hTemplateTexture, pElement->TemplateUVCoord, pElement->TextureColor.dwCurrentColor, m_RenderCoord[ i ] );
else
m_pParent->DrawSprite( pElement->UVCoord, pElement->TextureColor.dwCurrentColor, m_RenderCoord[ i ] );
}
UpdateLastVisible();
wstring strBuf = m_Buffer.GetBuffer();
if( m_Property.EditBoxProperty.bPassword )
strBuf.replace(0, int(strBuf.size()), int(strBuf.size()), '*');
m_RenderBuffer.SetText( strBuf.substr( 0, m_nLastVisible ).c_str() );
const WCHAR* pTextToRender = m_RenderBuffer.GetBuffer();
int nXFirst = 0;
CEtFontMng& FontMng = CEtFontMng::GetInstance();
pElement = GetElement(0);
if( pElement )
{
nXFirst = FontMng.GetCaretPos( pTextToRender, pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible);
//m_RenderBuffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst );
#ifdef _TEST_CODE_KAL
nCaretX = FontMng.GetCaretPos( strBuf.c_str(), pElement->nFontIndex, pElement->nFontHeight, m_nCaret );
#else
nCaretX = FontMng.GetCaretPos( pTextToRender, pElement->nFontIndex, pElement->nFontHeight, m_nCaret );
#endif
//hr = m_RenderBuffer.CPtoX( m_nCaret, FALSE, &nCaretX );
if( m_nCaret != m_nSelStart )
{
//hr = m_RenderBuffer.CPtoX( m_nSelStart, FALSE, &nSelStartX );
// Note: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20>ٷ<EFBFBD><D9B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>
//m_nSelStart = m_nSelStart - m_nFirstVisible;
//if( m_nSelStart < 0 )
// m_nSelStart = 0;
#ifdef _TEST_CODE_KAL
nSelStartX = FontMng.GetCaretPos(strBuf.c_str(), pElement->nFontIndex, pElement->nFontHeight, m_nSelStart);
#else
nSelStartX = FontMng.GetCaretPos(m_RenderBuffer.GetBuffer()/*+m_nFirstVisible*/, pElement->nFontIndex, pElement->nFontHeight, m_nSelStart);
#endif
}
else
{
nSelStartX = nCaretX;
}
}
SUICoord SelectionCoord;
if( m_nCaret != m_nSelStart )
{
int nSelLeftX, nSelRightX;
nSelLeftX = nCaretX;
nSelRightX = nSelStartX;
if( nSelLeftX > nSelRightX )
{
std::swap( nSelLeftX, nSelRightX );
}
float fMinRight, fMinBottom;
int nTextWidth = ( int )( m_TextCoord.fWidth * m_pParent->GetScreenWidth() );
int nSelRightXTemp = nSelRightX, nSelLeftXTemp = nSelLeftX;
if( nSelRightX >= nXFirst )
nSelRightXTemp = nSelRightX - nXFirst;
if( nSelLeftX >= nXFirst )
nSelLeftXTemp = nSelLeftX - nXFirst;
int nSelWidth = nSelRightXTemp - nSelLeftXTemp;
//if( nSelWidth > nTextWidth )
// nSelWidth -= nXFirst;
//nSelWidth = nSelWidth % nTextWidth;
SelectionCoord.SetCoord( ( ( float )nSelLeftX ) / m_pParent->GetScreenWidth(), m_TextCoord.fY,
( ( float )( nSelWidth ) ) / m_pParent->GetScreenWidth(), m_TextCoord.fHeight );
SelectionCoord.fX += m_TextCoord.fX - ( ( float )nXFirst ) / m_pParent->GetScreenWidth();
fMinRight = min( m_TextCoord.Right(), SelectionCoord.Right() );
fMinBottom = min( m_TextCoord.Bottom(), SelectionCoord.Bottom() );
SelectionCoord.fWidth = fMinRight - SelectionCoord.fX;
SelectionCoord.fHeight = fMinBottom - SelectionCoord.fY;
SelectionCoord.fX = max( m_TextCoord.fX, SelectionCoord.fX );
SelectionCoord.fY = max( m_TextCoord.fY, SelectionCoord.fY );
SelectionCoord.fWidth = min( m_TextCoord.fWidth, SelectionCoord.fWidth );
bool bEnableZ = GetEtDevice()->EnableZ( false );
m_pParent->DrawRect( SelectionCoord, m_Property.EditBoxProperty.dwSelBackColor );
GetEtDevice()->EnableZ( bEnableZ );
}
// <20><><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD> <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20>ִٸ<D6B4> <20>ʺ<EFBFBD> <20><>ŭ <20>ڷ<EFBFBD> <20>о<EFBFBD><D0BE>ش<EFBFBD>.
// <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
SUICoord TempCoord = m_TextCoord;
bool bNeedDivide = false;
if( 0.0f != m_fCompositionWidth )
{
if( m_nCaret < m_nLastVisible )
{
if( 0 == m_nCaret )
TempCoord.fX += m_fCompositionWidth;
else
bNeedDivide = true;
}
}
RenderText(fElapsedTime, pElement, TempCoord, bNeedDivide);
//if( wcslen(m_RenderBuffer.GetBuffer() + m_nFirstVisible) > 0 )
//{
// OutputDebugStringW( L"[Edit Box]" );
// OutputDebugStringW( m_RenderBuffer.GetBuffer() + m_nFirstVisible );
// OutputDebugStringW( L"\n" );
//}
//if( m_nCaret != m_nSelStart )
//{
// int nFirstToRender, nNumChatToRender;
// nFirstToRender = max( m_nFirstVisible, min( m_nSelStart, m_nCaret ) );
// nNumChatToRender = max( m_nSelStart, m_nCaret ) - nFirstToRender;
// m_pParent->DrawDlgText( m_RenderBuffer.GetBuffer() + nFirstToRender, pElement,
// m_Property.EditBoxProperty.dwSelTextColor, SelectionCoord, -1, pElement->dwFontFormat, true );
//}
//CEtFontMng::GetInstance().EnableFreeType( true );
LARGE_INTEGER liCurTime, liFrequency;
float fElapsedBlinkTime;
QueryPerformanceCounter( &liCurTime );
QueryPerformanceFrequency( &liFrequency );
fElapsedBlinkTime = ( ( float )( liCurTime.QuadPart - m_liLastBlinkTime.QuadPart ) ) / liFrequency.QuadPart;
if( fElapsedBlinkTime >= m_fCaretBlinkTime )
{
m_bCaretOn = !m_bCaretOn;
m_liLastBlinkTime = liCurTime;
}
SUICoord CaretCoord;
CaretCoord = TempCoord;
CaretCoord.fX += ( ( float )( -nXFirst + nCaretX - 1 ) ) / m_pParent->GetScreenWidth();
CaretCoord.fWidth = 2.0f / m_pParent->GetScreenWidth();
if (IsFocus())
{
s_CurrentCaretPos = CaretCoord;
// <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD>̾<EFBFBD><CCBE>α<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٰ<EFBFBD> ó<><C3B3><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>, <20>θ<EFBFBD><CEB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20≯<EFBFBD> <20><><EFBFBD>صд<D8B5>.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD> <20>Ʒ<EFBFBD> ( !CEtUIIME::s_bHideCaret ) <20><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD> false<73><65> <20>Ǽ<EFBFBD> s_CurrentCaretPos <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>,
// <20>̷<EFBFBD><CCB7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>׻<EFBFBD> ó<><C3B3><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD> <20>ߴ<EFBFBD>.
if( m_pParent )
{
s_CurrentCaretPos.fX += m_pParent->GetXCoord();
s_CurrentCaretPos.fY += m_pParent->GetYCoord();
}
}
if( ( m_bFocus ) && ( m_bCaretOn ) && ( !CEtUIIME::s_bHideCaret ) )
{
if( !m_bInsertMode )
{
int nRightEdgeX = 0;
//m_RenderBuffer.CPtoX( m_nCaret, TRUE, &nRightEdgeX );
nRightEdgeX = FontMng.GetCaretPos( pTextToRender, pElement->nFontIndex, pElement->nFontHeight, m_nCaret );
CaretCoord.fWidth = m_TextCoord.fX + ( ( float )( nRightEdgeX - nXFirst ) ) / m_pParent->GetScreenWidth() - CaretCoord.fX;
}
bool bEnableZ = GetEtDevice()->EnableZ( false );
m_pParent->DrawRect( CaretCoord, m_Property.EditBoxProperty.dwCaretColor );
GetEtDevice()->EnableZ( bEnableZ );
}
}
void CEtUIEditBox::PlaceCaret( int nCP )
{
ASSERT( ( nCP >= 0 ) && ( nCP <= m_Buffer.GetTextSize() ) );
int nX1st, nX, nX2;
m_nCaret = nCP;
m_FullTextCaret = GetFullTextCaretPos(m_nCaret, true);
CEtFontMng& FontMng = CEtFontMng::GetInstance();
const WCHAR* pText = m_Buffer.GetBuffer();
SUIElement* pElement = GetElement( 0 );
if( !pElement ) {
return;
}
nX1st = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible );
//m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st );
nX = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nCP );
//m_Buffer.CPtoX( nCP, FALSE, &nX ); // LEAD
if( nCP == m_Buffer.GetTextSize() )
{
nX2 = nX;
}
else
{
//m_Buffer.CPtoX( nCP, TRUE, &nX2 );
nX2 = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nCP );
}
if( nX < nX1st )
{
// Note : <20><><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>տ<EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾұ<CABE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// m_nFirstVisible<6C><65> <20><><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD>.
if( nCP >= 2 )
nCP -= GetTextMoveCount( 2, false );
m_nFirstVisible = nCP;
//UpdateLastVisible();
}
else
{
int nTextWidth;
nTextWidth = ( int )( m_TextCoord.fWidth * m_pParent->GetScreenWidth() );
if( nX2 > nX1st + nTextWidth )
{
int nXNewLeft = 0, nCPNew1st = 0, nNewTrail = 0, nXNew1st = 0;
nXNewLeft = nX2 - nTextWidth;
//m_Buffer.XtoCP( nXNewLeft, &nCPNew1st, &nNewTrail );
nCPNew1st = FontMng.GetCaretFromCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nXNewLeft, nNewTrail );
nXNew1st = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nCPNew1st );
//m_Buffer.CPtoX( nCPNew1st, FALSE, &nXNew1st );
if( nXNew1st < nXNewLeft )
{
// Note : <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>Է<EFBFBD> <20><><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// <09>Ʒ<EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD> <20>ִ<EFBFBD> <20>Է<EFBFBD> <20><><EFBFBD>̰<EFBFBD> 3<>̻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <09><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><33><C4AD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
if( s_bCheckThaiLanguageVowelRule )
{
int nTemp = m_Buffer.GetMaxEditBoxLength() - GetThaiLength( m_Buffer.GetBuffer() );
if( nTemp < 3 )
nCPNew1st += GetTextMoveCount( 1, true );
else
nCPNew1st += GetTextMoveCount( 3, true );
}
else
{
int nTemp = m_Buffer.GetMaxEditBoxLength() - m_Buffer.GetTextSize();
if( nTemp < 3 )
++nCPNew1st;
else
nCPNew1st += 3;
}
}
m_nFirstVisible = nCPNew1st;
}
}
}
void CEtUIEditBox::DeleteSelectionText()
{
int nFirst, nLast;
nFirst = min( m_nCaret, m_nSelStart );
nLast = max( m_nCaret, m_nSelStart );
RemoveChar( nFirst, nLast - nFirst );
}
void CEtUIEditBox::ResetCaretBlink()
{
m_bCaretOn = true;
QueryPerformanceCounter( &m_liLastBlinkTime );
}
void CEtUIEditBox::CopyToClipboard()
{
if( ( m_nCaret != m_nSelStart ) && ( OpenClipboard( NULL ) ) )
{
HGLOBAL hBlock;
EmptyClipboard();
hBlock = GlobalAlloc( GMEM_MOVEABLE, sizeof( WCHAR ) * ( m_Buffer.GetTextSize() + 1 ) );
if( hBlock )
{
WCHAR *pwszText;
int nFirst, nLast;
pwszText = ( WCHAR * )GlobalLock( hBlock );
if( pwszText )
{
nFirst = min( m_nCaret, m_nSelStart );
nLast = max( m_nCaret, m_nSelStart );
if( nLast - nFirst > 0 )
{
memcpy( pwszText, m_Buffer.GetBuffer() + nFirst, ( nLast - nFirst ) * sizeof( WCHAR ) );
}
pwszText[ nLast - nFirst ] = L'\0';
GlobalUnlock( hBlock );
}
SetClipboardData( CF_UNICODETEXT, hBlock );
}
CloseClipboard();
if( hBlock )
{
GlobalFree( hBlock );
}
}
}
void CEtUIEditBox::PasteFromClipboard()
{
DeleteSelectionText();
if( OpenClipboard( NULL ) )
{
HANDLE handle;
handle = GetClipboardData( CF_UNICODETEXT );
if( handle )
{
WCHAR *pwszText;
pwszText = ( WCHAR * )GlobalLock( handle );
if( pwszText )
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><>ü.
int nLen = (int)wcslen( pwszText );
for( int i = 0; i < nLen; ++i )
{
if( pwszText[i] == '\n' )
pwszText[i] = ' ';
// <20>ٿ<EFBFBD><D9BF>ֱ⿡<D6B1><E2BFA1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EBB0A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>
if( !CheckValidCharacter( pwszText[i] ) )
pwszText[i] = ' ';
}
// <20><><EFBFBD>ڸ<EFBFBD> <20>޾ƾ<DEBE><C6BE>ϴ<EFBFBD> <20><>Ȳ<EFBFBD>ε<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴѰ<C6B4> <20>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF>ֱ⸦ <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
if( m_Property.EditBoxProperty.bOnlyDigit == TRUE )
{
int nLenInner = (int)wcslen( pwszText );
for( int i = 0; i < nLenInner; ++i )
{
if( !iswdigit( pwszText[i] ) )
{
CloseClipboard();
return;
}
}
}
AddText(pwszText, true);
GlobalUnlock( handle );
}
}
CloseClipboard();
}
}
void CEtUIEditBox::SetMaxEditLength( DWORD dwMaxLength )
{
ASSERT( dwMaxLength > 0 );
m_RenderBuffer.SetMaxEditBoxLength( dwMaxLength );
m_Buffer.SetMaxEditBoxLength( dwMaxLength-1 );
}
void CEtUIEditBox::UpdateLastVisible( void )
{
CEtFontMng& FontMng = CEtFontMng::GetInstance();
const WCHAR* pText = m_Buffer.GetBuffer();
SUIElement* pElement = GetElement( 0 );
int nTrail = 0;
int nTextWidth = ( int )( m_TextCoord.fWidth * m_pParent->GetScreenWidth() );
if( CEtFontMng::s_bUseUniscribe )
{
// EditBox <20>۾<EFBFBD><DBBE><EFBFBD><EFBFBD><EFBFBD> wordbreak<61><6B> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
bool bFontMngWordBreak = CEtFontMng::s_bUseWordBreak;
CEtFontMng::s_bUseWordBreak = false;
std::vector<std::wstring> vecTextLine;
std::wstring strText( pText + m_nFirstVisible );
int nMaxWidth;
bool bRtnWordBreakText = CEtFontMng::GetInstance().GetWordBreakText( strText, pElement->nFontIndex, pElement->nFontHeight, static_cast<float>( nTextWidth ), vecTextLine, nMaxWidth );
CEtFontMng::s_bUseWordBreak = bFontMngWordBreak;
if( !bRtnWordBreakText )
return;
if( static_cast<int>( vecTextLine.size() ) > 0 )
{
m_nLastVisible = static_cast<int>( vecTextLine[0].length() ) + m_nFirstVisible;
}
}
else
{
m_nLastVisible = FontMng.GetCaretFromCaretPos( pText+m_nFirstVisible, pElement->nFontIndex, pElement->nFontHeight, nTextWidth, nTrail )+m_nFirstVisible+1; // ī<><C4AB>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>־<EFBFBD><D6BE><EFBFBD> <20>ϹǷ<CFB9> +1
}
}
void CEtUIEditBox::SetSelection(int startPos, int caretPos)
{
if (caretPos < 0 || caretPos > GetTextLength() ||
startPos < 0 || startPos > GetTextLength())
return;
m_nSelStart = startPos;
m_nCaret = caretPos;
}
int CEtUIEditBox::GetMaxChar() const
{
return m_Property.EditBoxProperty.dwMaxChars;
}
void CEtUIEditBox::SetMaxChar( DWORD dwChar )
{
m_Property.EditBoxProperty.dwMaxChars = dwChar;
SetMaxEditLength( dwChar );
}
void CEtUIEditBox::SetTextWithEllipsis(const wchar_t* text, const wchar_t* wszSymbol, bool bSelected)
{
std::wstring result;
std::wstring tempStr = text;
std::wstring ellipsis = wszSymbol;
DWORD maxChar = GetMaxChar();
if (wcslen(text) >= maxChar)
{
result = tempStr.substr(0, maxChar - ellipsis.size() - 2);
result += ellipsis;
}
else
{
result = tempStr;
}
m_pParent->MakeStringWithEllipsis(GetElement(0), m_TextCoord.fWidth, result, wszSymbol);
SetText(result.c_str(), bSelected);
}
bool CEtUIEditBox::DrawTextPiece(const std::wstring& piece, int pieceStart, int pieceEnd, SUIElement* pElement, SUICoord& drawCoord)
{
if (piece.empty())
return true;
if (m_nFirstVisible > pieceEnd || m_nLastVisible < pieceStart)
return true;
// viewporting(?)
bool res = true;
SUICoord widthCoord;
std::wstring drawText(piece);
int pieceSize = (int)piece.size() - abs(m_nFirstVisible - pieceStart);
if (pieceStart >= m_nFirstVisible)
{
if (pieceEnd > m_nLastVisible)
{
drawText = piece.substr(0, m_nLastVisible - pieceStart);
res = false;
}
}
else
{
if (pieceEnd > m_nLastVisible)
{
drawText = piece.substr(m_nFirstVisible - pieceStart, m_nLastVisible - m_nFirstVisible);
res = false;
}
else
{
drawText = piece.substr(m_nFirstVisible - pieceStart, std::wstring::npos);
}
}
if( m_Property.EditBoxProperty.bPassword )
drawText.replace(0, int(drawText.size()), int(drawText.size()), '*');
m_pParent->DrawDlgText(drawText.c_str(), pElement, m_RenderTextColor, drawCoord, -1, pElement->dwFontFormat, true, 0.f);
m_pParent->CalcTextRect(drawText.c_str(), pElement, widthCoord);
drawCoord.fX += widthCoord.fWidth;
return res;
}
int CEtUIEditBox::GetFullTextCaretPos(int caretPos, bool bRetWithCalcTagLast) const
{
if (caretPos == 0)
return 0;
std::wstring text = m_FullTextBuffer.GetBuffer();
std::wstring::size_type linkStartPos = 0;
int caretPosFound = 0;
int fullTextCaretPos = 0;
int processTextCaretPos = 0;
bool bInsideTag = false;
WORD sep = EtInterface::GetNameLinkMgr().GetNameLinkSeperator();
while(fullTextCaretPos < int(text.size()))
{
if (caretPos == caretPosFound)
{
if (bRetWithCalcTagLast)
{
if (bInsideTag)
{
std::wstring parsee = text.substr(fullTextCaretPos, std::wstring::npos);
std::wstring targetTag;
targetTag = FormatW(L"%ce", sep);
std::wstring::size_type loc = parsee.find(targetTag.c_str());
fullTextCaretPos += (loc != std::wstring::npos) ? int(loc + 2) : int(parsee.length());
}
}
else
{
CEtUINameLinkMgr::eNameLinkTagType type = EtInterface::GetNameLinkMgr().IsTagType(text, fullTextCaretPos);
if (type != CEtUINameLinkMgr::eNLTAG_NONE)
{
std::wstring parsee = text.substr(fullTextCaretPos, std::wstring::npos);
std::wstring targetTag;
targetTag = FormatW(L"%ce", sep);
std::wstring::size_type loc = parsee.find(targetTag.c_str());
fullTextCaretPos += (loc != std::wstring::npos) ? int(loc + 2) : int(parsee.length());
}
}
break;
}
CEtUINameLinkMgr::eNameLinkTagType type = EtInterface::GetNameLinkMgr().IsTagType(text, fullTextCaretPos);
if (type != CEtUINameLinkMgr::eNLTAG_NONE)
{
if (type == CEtUINameLinkMgr::eNLTAG_START)
bInsideTag = true;
else if (type == CEtUINameLinkMgr::eNLTAG_END)
bInsideTag = false;
// todo by kalliste : parsee <20><> <20>±<EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><><EFBFBD>̰<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3>. <20><> <20>ʿ䰡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>±<EFBFBD> Ÿ<>Կ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ѱ<EFBFBD><D1B1><EFBFBD> <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD>.
int offset = 0;
std::wstring parsee = text.substr(++fullTextCaretPos, std::wstring::npos);
EtInterface::GetNameLinkMgr().GetTagOffsetByParseText(parsee, offset);
fullTextCaretPos += offset;
}
else
{
++caretPosFound;
++fullTextCaretPos;
}
}
return fullTextCaretPos;
}
int CEtUIEditBox::GetTextCaretPos(int fullTextCaretPos)
{
if (fullTextCaretPos <= 0)
return 0;
std::wstring text = m_FullTextBuffer.GetBuffer();
std::wstring::size_type linkStartPos = 0;
int caretPosFound = 0;
int curFullCaretPos = 0;
bool bInsideTag = false;
while(curFullCaretPos < int(text.size()) && (curFullCaretPos < fullTextCaretPos))
{
CEtUINameLinkMgr::eNameLinkTagType type = EtInterface::GetNameLinkMgr().IsTagType(text, curFullCaretPos);
if (type != CEtUINameLinkMgr::eNLTAG_NONE)
{
int offset = 0;
std::wstring parsee = text.substr(curFullCaretPos + 1, std::wstring::npos);
EtInterface::GetNameLinkMgr().GetTagOffsetByParseText(parsee, offset);
curFullCaretPos += (offset + 1);
}
else
{
++caretPosFound;
++curFullCaretPos;
}
}
return caretPosFound;
}
// todo : refactoring using command pattern. by kalliste
int CEtUIEditBox::DrawTextWithTraslation(const WCHAR* originalStr, SUIElement* pElement, SUICoord& drawCoord)
{
if (pElement == NULL || (drawCoord.fHeight == 0.f && drawCoord.fWidth == 0.f))
return 0;
std::wstring rest;
const std::wstring& trs_org = originalStr;
std::wstring::size_type linkStartPos = 0;
int posWithoutTag, lengthWithoutTag, fullTextCaretIdx, i;
posWithoutTag =
lengthWithoutTag =
i =
fullTextCaretIdx = 0;
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
WCHAR sep = EtInterface::GetNameLinkMgr().GetNameLinkSeperator();
rest = originalStr;
while(rest.size() > 0 || linkStartPos != std::wstring::npos)
{
linkStartPos = rest.find_first_of(sep, linkStartPos);
if (linkStartPos == std::wstring::npos)
{
lengthWithoutTag = posWithoutTag + int(rest.length());
DrawTextPiece(rest, posWithoutTag, lengthWithoutTag, pElement, drawCoord);
break;
}
else
{
std::wstring drawText = rest.substr(0, linkStartPos);
if (DrawTextPiece(drawText, posWithoutTag, posWithoutTag + (int)linkStartPos, pElement, drawCoord) == false)
break;
rest = rest.substr(linkStartPos + 1, std::wstring::npos);
posWithoutTag += int(drawText.length());
lengthWithoutTag += int(drawText.length());
int tagOffset = 1;
if (EtInterface::GetNameLinkMgr().ParseText(rest, tagOffset, this) == false)
{
lengthWithoutTag = posWithoutTag + int(rest.length());
DrawTextPiece(rest, posWithoutTag, posWithoutTag + int(rest.length()), pElement, drawCoord);
break;
}
linkStartPos = 0;
}
}
return lengthWithoutTag;
}
bool CEtUIEditBox::OnParseTextColor(DWORD color)
{
m_RenderTextColor = (color != 0) ? color : m_Property.EditBoxProperty.dwTextColor;
return true;
}
bool CEtUIEditBox::OnParseTextFailColor()
{
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
return true;
}
bool CEtUIEditBox::OnParseTextRestoreColor()
{
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
return true;
}
void CEtUIEditBox::SetFilterOption(int option)
{
m_nFilterOption |= option;
}
static const WCHAR s_wThaiVowels[26] =
{
// Allow to use double vowels
0xE40, 0xE41, 0xE42, 0xE43, 0xE44, 0xE45, 0xE46,
// Behind vowels
0xE30, 0xE32,
// Below vowels
0xE38, 0xE39, 0xE3A,
// Above vowels in 1st class
0xE31, 0xE33, 0xE34, 0xE35, 0xE36, 0xE37,
// Above vowels in 2nd class
0xE47, 0xE48, 0xE49, 0xE4A, 0xE4B, 0xE4C, 0xE4D, 0xE4E
};
#define ISTHAIBASECONSONANT( ch ) ( (unsigned int)(ch) - 0xE01 ) <= ( 0xE2E - 0xE01 ) // <20>±<EFBFBD><C2B1><EFBFBD> <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
static const WCHAR s_wThaiStart = 0xE01;
static const int s_nThaiAllowDoubleVowelLastIndex = 6;
static const int s_nBehindVowelStartIndex = 7;
static const int s_nBelowVowelStartIndex = 9;
static const int s_nAboveVowelStartIndex = 12;
static const int s_nAboveVowelsIn1stClassStartIndex = 12;
static const int s_nAboveVowelsIn2ndClassStartIndex = 18;
int CEtUIEditBox::CheckThaiLanguageVowel( WCHAR wChar )
{
int nVowelIndex = -1;
for( int i=0; i<26; i++ )
{
if( s_wThaiVowels[i] == wChar )
{
nVowelIndex = i;
break;
}
}
return nVowelIndex;
}
int CEtUIEditBox::GetThaiLength( const WCHAR* pWChar )
{
if( pWChar == NULL ) return 0;
int nBufferThaiLength = 0;
int nBufferSize = lstrlenW( pWChar );
for( int i=0; i<nBufferSize; i++ )
{
int nTextIndex = CheckThaiLanguageVowel( pWChar[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
nBufferThaiLength++;
}
return nBufferThaiLength;
}
WCHAR CEtUIEditBox::GetThaiStartChar()
{
return s_wThaiStart;
}
int CEtUIEditBox::GetThaiBelowVowelStartIndex()
{
return s_nBelowVowelStartIndex;
}
bool CEtUIEditBox::CheckThaiLanguageVowelRule( WCHAR wChar )
{
int nVowelIndex = CheckThaiLanguageVowel( wChar );
bool bCheckAvailableChar = true;
if( nVowelIndex >= 0 ) // <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>츸 Ȯ<><C8AE>
{
int nTextSize = m_Buffer.GetTextSize();
WCHAR wLastChar = m_Buffer[m_nCaret-1];
if( m_nCaret > 0 && m_nCaret <= nTextSize && wLastChar >= s_wThaiStart ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
int nLastTextIndex = CheckThaiLanguageVowel( wLastChar );
if( nVowelIndex > s_nThaiAllowDoubleVowelLastIndex && nLastTextIndex == nVowelIndex ) // <20><><EFBFBD>߸<EFBFBD><DFB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ȵǴ<C8B5> <20>͵<EFBFBD> Ȯ<><C8AE>
{
bCheckAvailableChar = false;
}
else if( nLastTextIndex == -1 && !( ISTHAIBASECONSONANT( wLastChar ) ) ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴ<EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20>н<EFBFBD>
{
bCheckAvailableChar = false;
}
else if( nLastTextIndex >= 0 && nVowelIndex >= s_nBehindVowelStartIndex ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̰<EFBFBD> <20>Է<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><>,<2C>Ʒ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
if( nLastTextIndex < s_nBelowVowelStartIndex ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20>ܵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
bCheckAvailableChar = false;
}
else if( ( nLastTextIndex >= s_nAboveVowelStartIndex ) && ( nVowelIndex >= s_nBelowVowelStartIndex && nVowelIndex < s_nAboveVowelStartIndex ) ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD> <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
bCheckAvailableChar = false;
}
else if( ( nLastTextIndex >= s_nBelowVowelStartIndex && nLastTextIndex < s_nAboveVowelStartIndex ) && ( nVowelIndex >= s_nBelowVowelStartIndex && nVowelIndex < s_nAboveVowelStartIndex ) )
{
bCheckAvailableChar = false; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20>Ʒ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD> <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
}
else
{
std::vector<WCHAR> vecVowelChar;
for( int i=m_nCaret-1; i>=0; i-- )
{
int nTextIndex = CheckThaiLanguageVowel( m_FullTextBuffer[i] );
if( nTextIndex >= 0 )
vecVowelChar.push_back( nTextIndex );
else
break;
}
int nAboveVowelsCount = 0;
int nAboveVowelsIn1stClassCount = 0;
int nAboveVowelsIn2ndClassCount = 0;
for( int i=0; i<static_cast<int>( vecVowelChar.size() ); i++ )
{
if( vecVowelChar[i] == nVowelIndex )
{
bCheckAvailableChar = false;
break;
}
if( vecVowelChar[i] >= s_nAboveVowelStartIndex )
nAboveVowelsCount++;
if( vecVowelChar[i] >= s_nAboveVowelsIn1stClassStartIndex && vecVowelChar[i] < s_nAboveVowelsIn2ndClassStartIndex )
nAboveVowelsIn1stClassCount++;
if( vecVowelChar[i] >= s_nAboveVowelsIn2ndClassStartIndex )
nAboveVowelsIn2ndClassCount++;
if( vecVowelChar[i] == 13 ) // behind vowel<65><6C> 0xE33<33><33> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
bCheckAvailableChar = false;
}
if( nAboveVowelsCount >= 2 ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
bCheckAvailableChar = false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> 2<><32><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>. 0xE33<33><33> 2<><32> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־ <20><><EFBFBD><20><> <20>ִ<EFBFBD>.
if( ( nVowelIndex >= s_nAboveVowelsIn1stClassStartIndex && nVowelIndex < s_nAboveVowelsIn2ndClassStartIndex ) &&
( nAboveVowelsIn1stClassCount > 0 || ( nVowelIndex != 13 && nAboveVowelsIn2ndClassCount > 0 ) ) )
bCheckAvailableChar = false;
if( nVowelIndex >= s_nAboveVowelsIn2ndClassStartIndex && nAboveVowelsIn2ndClassCount > 0 )
bCheckAvailableChar = false;
}
}
}
else // ù <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
if( nVowelIndex >= s_nBehindVowelStartIndex ) // <20><>, <20><>,<2C>Ʒ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
bCheckAvailableChar = false;
}
}
return bCheckAvailableChar;
}
int CEtUIEditBox::GetPrevCaret()
{
int nPrevCaret = 0;
if( s_bCheckThaiLanguageVowelRule )
{
const WCHAR* pBuffer = m_Buffer.GetBuffer();
if( pBuffer == NULL ) return false;
for( int i=m_nCaret-1; i>=0; i-- )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
nPrevCaret = i;
break;
}
}
}
else
{
nPrevCaret = m_nCaret - 1;
}
return nPrevCaret;
}
int CEtUIEditBox::GetNextCaret()
{
int nNextCaret = 0;
if( s_bCheckThaiLanguageVowelRule )
{
int nBufferSize = m_Buffer.GetTextSize();
const WCHAR* pBuffer = m_Buffer.GetBuffer();
if( pBuffer == NULL ) return false;
for( int i=m_nCaret; i<nBufferSize; i++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
int nVowels = 0;
for( int j=i+1; j<nBufferSize; j++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[j] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 )
break;
else
nVowels++;
}
nNextCaret = i + 1 + nVowels;
break;
}
}
}
else
{
nNextCaret = m_nCaret + 1;
}
return nNextCaret;
}
int CEtUIEditBox::GetTextMoveCount( int nMoveCount, bool bForward )
{
int nResultMoveCount = 0;
if( s_bCheckThaiLanguageVowelRule )
{
const WCHAR* pBuffer = m_Buffer.GetBuffer();
int nBufferSize = m_Buffer.GetBufferSize();
if( pBuffer == NULL ) return 0;
int nCount = 0;
if( bForward )
{
for( int i=m_nFirstVisible; i<nBufferSize; i++, nResultMoveCount++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
nCount++;
if( nCount > nMoveCount )
break;
}
}
}
else
{
for( int i=m_nCaret; i>=0; i--, nResultMoveCount++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
nCount++;
if( nCount > nMoveCount )
break;
}
}
}
}
else
{
nResultMoveCount = nMoveCount;
}
return nResultMoveCount;
}