Files
Leviathan/Client/Game/engine/Ui/Controls/CEditBoxInfo.cpp
T
2026-06-01 12:46:52 +02:00

1471 lines
36 KiB
C++
Raw 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 "ceditboxinfo.h"
#include "CInput.h"
#include <toolkit/nsluni.h>
// 2010.08.24 - prodongi
#include "KTextPhrase.h"
#ifdef _COUNTRY_TL_
#include "./Localization/Thailand.h"
#endif
// 2010.06.08 - prodongi
char* CEditBoxInfo::sScrollInfo::token = "<edit_scroll>";
// 2010.06.07 - prodongi
CEditBoxInfo::sScrollInfo::sScrollInfo()
{
m_startPos = 0;
m_endPos = 0;
m_maxWidth = 0;
m_fontName = "default";
m_fontSize = 10;
m_bold = false;
m_is = false;
m_cursorPos = 1;
}
// 2010.06.07 - prodongi
void CEditBoxInfo::sScrollInfo::syncPos(int cursorPos, std::wstring const& inputBuffer, UINT codePage)
{
// 커서가 맨 끝에 있는 경우
if (inputBuffer.size()+1 == cursorPos)
{
syncPosAtEnd(cursorPos, inputBuffer, codePage);
return ;
}
// 1. 시작부터 cursor까지의 스트링을 뽑는다
// 2. 1의 실제 사이즈를 구한다
// 3. 실제 사이즈가 에디트 박스의 최대 사이즈보다 크면 텍스트의 시작 위치를 수정한다
// 4. cursor위치가 텍스트의 시작 위치보다 작으면 시작 위치를 수정한다
setEndPos(cursorPos, inputBuffer);
// 1. 시작부터 cursor까지의 스트링을 뽑는다
std::wstring tmp(inputBuffer.c_str(), m_endPos);
// 2010.06.23 - prodongi
// 2. 1의 실제 사이즈를 구한다
/*
char str[1024];
int len = ConvertString(codePage, tmp.c_str(), tmp.size(), str, 1024);
str[len] = 0x00;
DWORD endWidth = 0, strHeight = 0;
KTextRender::GetStringSize(m_fontName.c_str(), m_fontSize, m_bold, str, strlen(str), &endWidth, &strHeight);
*/
DWORD endWidth, strHeight;
getStringSize(tmp, codePage, endWidth, strHeight);
// 3. 실제 사이즈가 에디트 박스의 최대 사이즈보다 크면 텍스트의 시작 위치를 수정한다
if ((int)endWidth > m_maxWidth)
{
syncPosAtEnd(m_endPos, inputBuffer, codePage);
return ;
}
else
{
if (inputBuffer.size() > (size_t)m_endPos)
{
syncPosAtStart(m_startPos, inputBuffer, codePage);
return ;
}
}
// 4. cursor위치가 텍스트의 시작 위치보다 작으면 시작 위치를 수정한다
if (m_endPos < m_startPos)
setStartPos(m_endPos);
// 2010.06.22 - prodongi
//setInputBuffer(inputBuffer);
setInputBuffer(inputBuffer, m_startPos, m_endPos);
trace(inputBuffer, codePage);
}
// 2010.06.07 - prodongi
void CEditBoxInfo::sScrollInfo::syncPosAtStart(int startPos, std::wstring const& inputBuffer, UINT codePage)
{
// 2010.06.23 - prodongi
/*
DWORD strWidth = 0, strHeight = 0;
char str[MAX_PATH];
*/
DWORD strWidth, strHeight;
// start
setStartPos(startPos);
// end
int size = inputBuffer.size() - (m_startPos - 1);
int i;
for (i = 0; i < size; ++i)
{
std::wstring tmp(inputBuffer.c_str()+(m_startPos-1), i);
// 2010.06.23 - prodongi
/*
int len = ConvertString(codePage, tmp.c_str(), tmp.size(), str, MAX_PATH);
str[len] = 0x00;
KTextRender::GetStringSize(m_fontName.c_str(), m_fontSize, m_bold, str, strlen(str), &strWidth, &strHeight);
*/
getStringSize(tmp, codePage, strWidth, strHeight);
if ((int)strWidth >= m_maxWidth)
{
--i;
break;
}
}
setEndPos(m_startPos + i, inputBuffer);
// 2010.06.09 - prodongi
if (m_endPos < m_startPos)
setStartPos(m_endPos);
// 2010.06.22 - prodongi
//setInputBuffer(inputBuffer);
setInputBuffer(inputBuffer, m_startPos, m_endPos);
trace(inputBuffer, codePage);
}
// 2010.06.07 - prodongi
void CEditBoxInfo::sScrollInfo::syncPosAtEnd(int endPos, std::wstring const& inputBuffer, UINT codePage)
{
// 2010.06.23 - prodongi
/*
DWORD strWidth = 0, strHeight = 0;
char str[MAX_PATH];
*/
DWORD strWidth, strHeight;
// end
setEndPos(endPos, inputBuffer);
// start
int size = m_endPos;
int i;
for (i = 0; i < size; ++i)
{
std::wstring tmp(inputBuffer.c_str() + (size-1) - i, i);
// 2010.06.23 - prodongi
/*
int len = ConvertString(codePage, tmp.c_str(), tmp.size(), str, MAX_PATH);
str[len] = 0x00;
KTextRender::GetStringSize(m_fontName.c_str(), m_fontSize, m_bold, str, strlen(str), &strWidth, &strHeight);
*/
getStringSize(tmp, codePage, strWidth, strHeight);
if ((int)strWidth >= m_maxWidth)
{
--i;
break;
}
}
setStartPos(m_endPos - i);
// 2010.06.23 - prodongi
if (!m_compBuffer.empty())
{
syncPosAtEndWithCompose(endPos, inputBuffer, codePage);
return ;
}
// 2010.06.22 - prodongi
//setInputBuffer(inputBuffer);
setInputBuffer(inputBuffer, m_startPos, m_endPos);
trace(inputBuffer, codePage);
}
// 2010.06.23 - prodongi
void CEditBoxInfo::sScrollInfo::syncPosAtEndWithCompose(int endPos, std::wstring const& inputBuffer, UINT codePage)
{
DWORD strWidth, strHeight;
std::wstring _inputBuffer = inputBuffer + m_compBuffer;
// end
endPos += 1;
if ((int)(_inputBuffer.size()+1) < m_endPos)
m_endPos = (int)(_inputBuffer.size()+1);
// start
int size = endPos;
int i;
for (i = 0; i < size; ++i)
{
std::wstring tmp(_inputBuffer.c_str() + (size-1) - i, i);
getStringSize(tmp, codePage, strWidth, strHeight);
if ((int)strWidth >= m_maxWidth)
{
--i;
break;
}
}
int startPos = endPos - i;
if (1 > startPos) startPos = 1;
setInputBuffer(inputBuffer, startPos, m_endPos);
trace(_inputBuffer, codePage);
}
// 2010.06.08 - prodongi
void CEditBoxInfo::sScrollInfo::setStartPos(int pos)
{
m_startPos = pos;
if (1 > m_startPos) m_startPos = 1;
}
// 2010.06.08 0 prodongi
void CEditBoxInfo::sScrollInfo::setEndPos(int pos, std::wstring const& inputBuffer)
{
m_endPos = pos;
if ((int)(inputBuffer.size()+1) < m_endPos)
m_endPos = (int)(inputBuffer.size()+1);
}
// 2010.06.07 - prodongi
int CEditBoxInfo::sScrollInfo::getInputBuffer(wchar_t* text, int len) const
{
if (len < 0) return 0;
int copy_size = m_inputClipBuffer.size();
if( copy_size > len ) copy_size = len;
memcpy( text, m_inputClipBuffer.c_str(), copy_size*sizeof( wchar_t ) );
if( copy_size == len )
{
text[copy_size] = 0;
--copy_size;
}
return copy_size;
}
// 2010.06.08 - prodongi
void CEditBoxInfo::sScrollInfo::setCursorPos(int pos)
{
m_cursorPos = pos;
if(m_cursorPos < 1)
m_cursorPos=1;
/// 2010.12.14 - prodongi
if (1 == m_startPos && 1 == m_endPos)
m_cursorPos = 1;
if(m_cursorPos > static_cast<int>(m_inputClipBuffer.size()+1) )
m_cursorPos=m_inputClipBuffer.size()+1;
}
void CEditBoxInfo::sScrollInfo::syncCursorPos(int cursorPos)
{
setCursorPos(cursorPos - m_startPos + 1);
}
// 2010.06.23 - prodongi
void CEditBoxInfo::sScrollInfo::setCompBuffer(wchar_t const* compBuffer)
{
if (!compBuffer || wcslen(compBuffer) == 0)
m_compBuffer.clear();
else
m_compBuffer = compBuffer;
}
// 2010.06.07 - prodongi
void CEditBoxInfo::sScrollInfo::trace(std::wstring const& inputBuffer, UINT codePage)
{
/*
_oprint("start:%d end:%d \n", m_startPos, m_endPos);
char str[MAX_PATH];
int len = ConvertString(codePage, m_inputClipBuffer.c_str(), m_inputClipBuffer.size(), str, MAX_PATH);
str[len] = 0x00;
DWORD strWidth, strHeight;
KTextRender::GetStringSize(m_fontName.c_str(), m_fontSize, m_bold, str, strlen(str), &strWidth, &strHeight);
_oprint("out: %s size: %d \n", str, strWidth);
*/
}
// 2010.06.22 - prodongi
/*
// 2010.06.07 - prodongi
void CEditBoxInfo::sScrollInfo::setInputBuffer(std::wstring const& inputBuffer)
{
// 2010.06.16 - prodongi
if (m_endPos < m_startPos)
return ;
m_inputClipBuffer = std::wstring(inputBuffer.c_str()+(m_startPos-1),m_endPos- m_startPos );
}
*/
void CEditBoxInfo::sScrollInfo::setInputBuffer(std::wstring const& inputBuffer, int startPos, int endPos)
{
// 2010.06.16 - prodongi
if (endPos < startPos)
return ;
m_inputClipBuffer = std::wstring(inputBuffer.c_str()+(startPos-1),endPos- startPos );
}
// 2010.06.23 - prodongi
void CEditBoxInfo::sScrollInfo::getStringSize(std::wstring &wstr, UINT codePage, DWORD &strWidth, DWORD &strHeight)
{
static char str[1024];
strWidth = strHeight = 0;
// 2010.08.24 - prodongi
int len = ConvertString(codePage, wstr.c_str(), wstr.size(), str, 1024);
str[len] = 0x00;
#ifdef _COUNTRY_ME_
// 2010.08.24 - prodongi
KTextPhrase::GetStringSize(m_fontName.c_str(), m_fontSize, m_bold, str, strlen(str), &strWidth, &strHeight);
/*
int text_len = wstr.length();
text_len = WideCharToMultiByte(g_pGameOperationManager->GetDefaultCodePage(),0,wstr.c_str(),text_len,str,1024,NULL,NULL);
str[text_len] = 0x00;
KTextParser parser;
DWORD dwHALign = ( KTextParagraph::KTALIGN_LEFT & m_align ) | (KTextParagraph::KTALIGN_HCENTER & m_align);
DWORD dwVALign = ( KTextParagraph::KTALIGN_BOTTOM & m_align ) | (KTextParagraph::KTALIGN_VCENTER & m_align);
parser.SetAlign( dwHALign, dwVALign );
parser.AddString( str, m_maxWidth, true, false, true );
int paragraphCount = parser.GetParagraphCount();
if (paragraphCount > 0)
{
KParagraphLayout layout(m_maxWidth, -1, m_spacing, m_align);
KTextParagraph* pPara = parser.GetTextParagraph( 0 );
KSize size = layout.GetActualSize( pPara, 0 );
strWidth = size.width;
strHeight = size.height;
}
*/
#else
KTextRender::GetStringSize(m_fontName.c_str(), m_fontSize, m_bold, str, strlen(str), &strWidth, &strHeight);
#endif
}
// 2010.06.23 - prodongi
DWORD CEditBoxInfo::sScrollInfo::getClipStringWidth(UINT codePage)
{
DWORD strWidth, strHeight;
getStringSize(m_inputClipBuffer, codePage, strWidth, strHeight);
return strWidth;
}
std::vector<CEditBoxInfo::_EXCEPTION_WORD_> CEditBoxInfo::s_ClipExceptionList;
bool CEditBoxInfo::s_bUseClipException = false;
CEditBoxInfo::CEditBoxInfo(void)
: m_nTextLen(0)
, m_nCursorPos(1)
, m_nSelectIndexBegin(0)
, m_nSelectIndexEnd(0)
, m_pInput(NULL)
, m_bShiftOn(false)
, m_bCtrlOn(false)
, m_OldCursorPos(0)
, m_bLButtonDown(false)
, m_bBufferLimit(false)
{
int i=0;
m_InputBuffer = L""; // servantes 2011.02.22
m_nLimitation = 65535;
}
CEditBoxInfo::~CEditBoxInfo(void)
{
}
int CEditBoxInfo::GetInputBuffer(wchar_t* text,int len)
{
// 2010.06.07 - prodongi
if (m_scrollInfo.m_is)
return m_scrollInfo.getInputBuffer(text, len);
// 2010.06.09 - prodongi
return GetInputBufferOri(text, len);
/*
if( len < 0 ) return 0;
int copy_size = m_InputBuffer.size();
if( copy_size > len ) copy_size = len;
memcpy( text, m_InputBuffer.c_str(), copy_size*2 );
if( copy_size == len )
{
text[copy_size] = 0;
--copy_size;
}
return copy_size;
*/
}
// 2010.06.09 - prodongi
int CEditBoxInfo::GetInputBufferOri(wchar_t* text,int len)
{
if( len < 0 ) return 0;
int copy_size = m_InputBuffer.size();
if( copy_size > len ) copy_size = len;
memcpy( text, m_InputBuffer.c_str(), copy_size*2 );
if( copy_size == len )
{
text[copy_size] = 0;
--copy_size;
}
return copy_size;
}
bool CEditBoxInfo::OnChar(WPARAM wParam)
{
switch(wParam)
{
case '\r':
case '\n':
m_InputBuffer.resize(0);
m_nCursorPos=1;
// 2010.06.08 - prodongi
if (m_scrollInfo.m_is)
m_scrollInfo.setCursorPos(1);
break;
case '\b':
if(!DeleteSelectText())
{
if(m_nCursorPos>1)
{
if(m_InputBuffer.size())
m_InputBuffer.erase(m_nCursorPos-2,1);
--m_nCursorPos;
// 2010.06.07 - prodongi
if (m_scrollInfo.m_is)
{
m_scrollInfo.syncPosAtEnd(m_InputBuffer.size()+1, m_InputBuffer, m_pInput->GetCodePage());
m_scrollInfo.syncCursorPos(m_nCursorPos);
}
}
}
break;
default:
if(wParam>31)
DeleteSelectText();
break;
}
CurrentCursorPos();
return true;
}
void CEditBoxInfo::SetSelectIndexBegin(int i)
{
if( static_cast<int>( m_InputBuffer.size()+1) < i )
return ;
m_nSelectIndexBegin=i;
/*
if(m_nSelectIndexBegin>m_nSelectIndexEnd)
{
m_nSelectIndexBegin=m_nSelectIndexEnd;
m_nSelectIndexBegin=i;
}
*/
}
void CEditBoxInfo::SetSelectIndexEnd(int i)
{
if( static_cast<int>( m_InputBuffer.size()+1) < i )
return ;
m_nSelectIndexEnd=i;
}
int CEditBoxInfo:: DeleteSelectText()
{
int SelectStart, SelectEnd, SelectLen=0;
if(m_nSelectIndexBegin>m_nSelectIndexEnd)
{
SelectStart=m_nSelectIndexEnd;
SelectEnd=m_nSelectIndexBegin;
}
else
{
SelectStart=m_nSelectIndexBegin;
SelectEnd=m_nSelectIndexEnd;
}
SelectLen=SelectEnd-SelectStart;
if(!(SelectEnd-SelectStart))
return 0;
if( SelectStart==0 )
return 0;
m_InputBuffer.erase(SelectStart-1,SelectLen);
/*
if(m_nCursorPos>SelectEnd)
{
m_nCursorPos =SelectStart;
}
*/
m_nCursorPos =SelectStart;
SetSelectIndexBegin(0);
SetSelectIndexEnd(0);
// 2010.06.08 - prodongi
CurrentCursorPos();
if (m_scrollInfo.m_is)
{
m_scrollInfo.syncPosAtStart(m_scrollInfo.m_startPos, m_InputBuffer, m_pInput->GetCodePage());
/// 2010.12.14 - prodongi
m_scrollInfo.syncCursorPos(m_nCursorPos);
}
return SelectLen;
}
void CEditBoxInfo::SetLimitation(int nLimitation, bool bBufferLimit/*true*/)
{
assert( nLimitation > 0 );
m_nLimitation = nLimitation;
m_bBufferLimit = bBufferLimit;
}
int CEditBoxInfo::GetInputBufferSize( bool bMemSize )
{
if( bMemSize )
{
char text[1024] = {0, };
ConvertString(m_pInput->GetCodePage(), m_InputBuffer.c_str(), m_InputBuffer.size(), text, 1024);
return ::strlen( text );
}
return int( m_InputBuffer.size() );
}
bool CEditBoxInfo::IsMaxInput()
{
int nBufferSize = GetInputBufferSize( m_bBufferLimit );
if( nBufferSize >= m_nLimitation )
return true;
return false;
}
// 2010.06.08 - prodongi
int CEditBoxInfo::GetCursorPos()
{
if (m_scrollInfo.m_is)
return m_scrollInfo.m_cursorPos;
return m_nCursorPos;
}
void CEditBoxInfo::AddInputBuffer(wchar_t* buffer,int len)
{
#ifdef _COUNTRY_TL_
// 태국어 조합 처리... 불가능한 글자조합을 하려 하면 사전에 차단하는 부분.
if (m_nCursorPos > 1)
{
if (m_pInput->GetCodePage() == 874)
{
char prev[10] = {0, };
char buf[10] = {0, };
int nLength = ::WideCharToMultiByte(m_pInput->GetCodePage(), 0, &(m_InputBuffer[m_nCursorPos-2]), 1, NULL, 0, NULL, NULL); // 저장된 문자열 길이
::WideCharToMultiByte(m_pInput->GetCodePage(), 0, &(m_InputBuffer[m_nCursorPos-2]), 1, prev, nLength, NULL, NULL); // 입력하려는 문자열 길이
char* last = NULL;
if (strlen(prev) > 0)
last = &prev[strlen(prev)-1];
nLength = ::WideCharToMultiByte(m_pInput->GetCodePage(), 0, buffer, len, NULL, 0, NULL, NULL); // 저장된 문자열 길이
::WideCharToMultiByte(m_pInput->GetCodePage(), 0,buffer, len, buf, nLength, NULL, NULL); // 입력하려는 문자열 길이
char* current= NULL;
if (strlen(buf) > 0)
current = &buf[strlen(buf)-1];
if (current != NULL && last != NULL)
{
bool ch = LocalizationTL::IsComposible(*last, *current, 1);
if (!ch)
return;
}
}
}
#endif
//m_InputBuffer.push_back(buffer);
if (m_bBufferLimit) // multibyte 길이 기준 검사. NULL 문자 길이 계산은 포함? 비포함?
{
// AziaMafia CP_UTF8 / m_pInput->GetCodePage()
WORD wCodePage = m_pInput->GetCodePage();
int nLength = ::WideCharToMultiByte(wCodePage, 0, m_InputBuffer.c_str(), m_InputBuffer.size(), NULL, 0, NULL, NULL); // 저장된 문자열 길이
int nInputed = ::WideCharToMultiByte(wCodePage, 0, buffer, len, NULL, 0, NULL, NULL); // 입력하려는 문자열 길이
// 제한된 버퍼 크기보다 크다면 알맞은 크기만큼만...
if ((nLength + nInputed) >= m_nLimitation)
{
char *pszAnsi = new char[nInputed + 1];
::memset(pszAnsi, 0, sizeof(char) * (nInputed + 1));
::WideCharToMultiByte(wCodePage, 0, buffer, len, pszAnsi, nInputed, NULL, NULL);
// 버퍼 길이 제한에 맞는 크기 계산
nInputed = m_nLimitation - nLength;
// 유니코드에 맞는 길이로 변환
len = ::MultiByteToWideChar(wCodePage, 0, pszAnsi, nInputed, buffer, len);
delete []pszAnsi;
}
}
else
{
if( IsMaxInput() )
return;
}
m_InputBuffer.insert(m_nCursorPos - 1, buffer, len);
//++m_nCursorPos;
m_nCursorPos += len;
CurrentCursorPos();
if (m_scrollInfo.m_is && 1 <= len)
{
m_scrollInfo.syncPos(m_nCursorPos, m_InputBuffer, m_pInput->GetCodePage());
m_scrollInfo.modifyCursorPos(len);
}
}
void CEditBoxInfo::CursorPosUpdate(int i)
{
#ifdef _COUNTRY_TL_
// 젠장태국 -_-
char buf[20000] = {0, };
WORD wCodePage = 874;
int nLength = ::WideCharToMultiByte(wCodePage, 0, m_InputBuffer.c_str(), m_InputBuffer.size(), NULL, 0, NULL, NULL); // 저장된 문자열 길이
::WideCharToMultiByte(wCodePage, 0, m_InputBuffer.c_str(), m_InputBuffer.size(), buf, nLength, NULL, NULL);
if (i > 0)
{
for (int ii=0; ii < i; ii++)
{
const char* nextChar = LocalizationTL::CharNextTh(&(buf[m_nCursorPos-1]));
m_nCursorPos = nextChar - buf + 1;
}
}
else
{
for (int ii=0; ii < -i; ii++)
{
const char* nextChar = LocalizationTL::CharPrevTh(buf, &(buf[m_nCursorPos-1]));
m_nCursorPos = nextChar - buf + 1;
}
}
#else
m_nCursorPos+=i;
#endif
CurrentCursorPos();
}
void CEditBoxInfo::CurrentCursorPos()
{
if(m_nCursorPos < 1)
m_nCursorPos=1;
if(m_nCursorPos > static_cast<int>(m_InputBuffer.size()+1) )
m_nCursorPos=m_InputBuffer.size()+1;
}
void CEditBoxInfo::TextPaste(const wchar_t* buffer,int textlen, int pos)
{
if(!textlen|| !(buffer))
return;
if (m_bBufferLimit) // multibyte 길이 기준 검사. NULL 문자 길이 계산은 포함? 비포함?
{
// AziaMafia CP_UTF8
//WORD wCodePage = m_pInput->GetCodePage();
WORD wCodePage = m_pInput->GetCodePage();
int nLength = ::WideCharToMultiByte(wCodePage, 0, m_InputBuffer.c_str(), m_InputBuffer.size(), NULL, 0, NULL, NULL); // 저장된 문자열 길이
int nInputed = ::WideCharToMultiByte(wCodePage, 0, buffer, textlen, NULL, 0, NULL, NULL); // 입력하려는 문자열 길이
// 제한된 버퍼 크기보다 크다면 알맞은 크기만큼만...
if ((nLength + nInputed) >= m_nLimitation)
{
char *pszAnsi = new char[nInputed + 1];
::memset(pszAnsi, 0, sizeof(char) * (nInputed + 1));
::WideCharToMultiByte(wCodePage, 0, buffer, textlen, pszAnsi, nInputed, NULL, NULL);
// 버퍼 길이 제한에 맞는 크기 계산
nInputed = m_nLimitation - nLength;
// 유니코드에 맞는 길이로 변환
wchar_t *pszUnicode = new wchar_t[textlen + 1];
::memset(pszUnicode, 0, sizeof(wchar_t) * (textlen + 1));
textlen = ::MultiByteToWideChar(wCodePage, 0, pszAnsi, nInputed, pszUnicode, textlen);
delete []pszAnsi;
delete []pszUnicode;
}
}
else
{
if( IsMaxInput() )
return;
}
m_InputBuffer.insert(pos - 1, buffer, textlen);
m_nCursorPos += textlen;
// 2010.06.08 - prodongi
CurrentCursorPos();
/// 2010.12.15 - prodongi
if (m_scrollInfo.m_is)
{
m_scrollInfo.syncPos(m_nCursorPos, m_InputBuffer, m_pInput->GetCodePage());
m_scrollInfo.syncCursorPos(m_nCursorPos);
}
}
std::wstring CEditBoxInfo::TextCut()
{
std::wstring tmp = TextCopy();
DeleteSelectText();
return tmp;
}
std::wstring CEditBoxInfo::TextCopy()
{
int SelectStart, SelectEnd, CopyLen=0;
if(m_nSelectIndexBegin>m_nSelectIndexEnd)
{
SelectStart=m_nSelectIndexEnd;
SelectEnd=m_nSelectIndexBegin;
}
else
{
SelectStart=m_nSelectIndexBegin;
SelectEnd=m_nSelectIndexEnd;
}
std::wstring temp;
CopyLen=SelectEnd-SelectStart;
if(!CopyLen) return temp;
std::wstring tmp( m_InputBuffer.c_str()+(SelectStart-1),sizeof(wchar_t)*CopyLen );
return tmp;
}
static std::string GetFromClipBoard()
{
std::string strTmp;
extern HWND g_hWnd;
if (!IsClipboardFormatAvailable(CF_TEXT)) return"";
if ( OpenClipboard(g_hWnd) )
{
HANDLE hData = GetClipboardData( CF_TEXT );
if( hData )
{
strTmp = (char*)GlobalLock( hData );
GlobalUnlock( hData );
CloseClipboard();
}
}
return strTmp;
}
static void CopyToClipBoard( int codepage, const wchar_t* wbuf, size_t len )
{
extern HWND g_hWnd;
HGLOBAL clipbuffer;
std::wstring strTmp( wbuf, wbuf + len );
char buff[1024] = {0,};
WideCharToMultiByte(codepage,0,wbuf,len,buff,1024,NULL,NULL);
std::string source = buff;
char * buffer;
EmptyClipboard();
clipbuffer = GlobalAlloc(GMEM_SHARE, (source.size() + 1) );
if( clipbuffer )
{
if ( OpenClipboard(g_hWnd) )
{
EmptyClipboard();
buffer = (char*)GlobalLock(clipbuffer);
strcpy(buffer, source.c_str() );
GlobalUnlock( clipbuffer );
SetClipboardData(CF_TEXT,clipbuffer);
int nRtn = GetLastError();
CloseClipboard();
}
}
}
int CEditBoxInfo::FindNearSpace(int Pos, bool bRight)
{
if(Pos <= 0 || Pos > static_cast<int>( m_InputBuffer.size()+1) )
return -1;
int findpos=0;
wchar_t buffer[2]={' ',0};
if(bRight)//Pos의 오른쪽으로 검색
{
findpos= m_InputBuffer.find(buffer,Pos-1)+1;
if(findpos==Pos)
{
findpos=m_InputBuffer.rfind(buffer,Pos)+1;
}
if(findpos==0)
{
findpos=m_InputBuffer.size();
}
}
else
{
findpos=m_InputBuffer.rfind(buffer,Pos-1)+1;
if(findpos==Pos)
{
findpos=m_InputBuffer.rfind(buffer,Pos-2)+1;
}
}
return findpos;
}
bool CEditBoxInfo::OnKeyDown(WPARAM wParam)
{
wchar_t text[256] = {0,};
int textLen;
switch(wParam)
{
case VK_F1://디버깅용
CursorPosUpdate(0);
//DeleteSelectText();
break;
case VK_RETURN:
//m_InputBuffer.clear();
break;
case VK_LEFT:
// 2010.06.22 - prodongi
m_scrollInfo.setCompBuffer(NULL);
if(!m_bShiftOn)
{
SetSelectIndexBegin(0);
SetSelectIndexEnd(0);
}
textLen = m_pInput->GetInput(text, _countof(text));
if(textLen) // g_input의 input버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearInput();
}
textLen = m_pInput->GetComp(text, _countof(text));
if(textLen) // g_input의 comp버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearComp();
}
CursorPosUpdate(-1);
// 2010.06.07 - prodongi
if (m_scrollInfo.m_is)
{
if (m_nCursorPos < m_scrollInfo.m_startPos)
m_scrollInfo.syncPosAtStart(m_nCursorPos, m_InputBuffer, m_pInput->GetCodePage());
m_scrollInfo.modifyCursorPos(-1);
}
if(m_bShiftOn)
{
int cursorpos= GetCursorPos();
if(m_bCtrlOn)
{
int newcursorpos=FindNearSpace(cursorpos,false);
/*
if(newcursorpos<0)
{
MessageBox(hWnd,"VK_LEFT","에러",MB_OK);
}
*/
/*
if(newcursorpos==0)
{
newcursorpos=;
}
*/
CursorPosUpdate(newcursorpos-cursorpos+1);
cursorpos=newcursorpos+1;
}
if(!GetSelectIndexBegin())
{
SetSelectIndexBegin(m_OldCursorPos);
}
SetSelectIndexEnd(cursorpos);
}
break;
case VK_RIGHT:
// 2010.06.22 - prodongi
m_scrollInfo.setCompBuffer(NULL);
if(!m_bShiftOn)
{
SetSelectIndexBegin(0);
SetSelectIndexEnd(0);
}
textLen = m_pInput->GetInput(text, _countof(text));
if(textLen) // g_input의 input버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearInput();
}
textLen = m_pInput->GetComp(text, _countof(text));
if(textLen) // g_input의 input버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearComp();
}
//여기까지의 작업이 커서위치를 움직이기전에 g_input의 inputbuffer나 Compbuffer의 내용을 g_editboxinfo의 input버퍼에 넣어줘야 한다
//그렇지않고 그냥 커서 위치를 이동시키면...조합중인 문자의 위치가 바뀔수도잇다...
//예>조합중인 한글을 끝나진 않은 상태에서 커서 위치를 이동시키면 포인터가 이동된다음에 ShowInputText()에서 조합된 문자를
//g_editboxinfo의 input버퍼에 넣어주기 때문에 위치가 잘못됨...
CursorPosUpdate(1);
// 2010.06.07 - prodongi
if (m_scrollInfo.m_is)
{
m_scrollInfo.syncPos(m_nCursorPos, m_InputBuffer, m_pInput->GetCodePage());
m_scrollInfo.modifyCursorPos(1);
}
if(m_bShiftOn)
{
int cursorpos= GetCursorPos();
if(m_bCtrlOn)
{
int newcursorpos=FindNearSpace(cursorpos,true);
/*
if(newcursorpos<0)
{
MessageBox(hWnd,"VK_LEFT","에러",MB_OK);
}
*/
/*
if(newcursorpos==0)
{
newcursorpos=1;
}
*/
CursorPosUpdate(newcursorpos-cursorpos+1);
cursorpos=newcursorpos+1;
}
if(!GetSelectIndexBegin())
{
SetSelectIndexBegin(m_OldCursorPos);
}
SetSelectIndexEnd(cursorpos);
}
break;
case VK_SHIFT:
m_OldCursorPos=GetCursorPos();
m_bShiftOn=true;
break;
case VK_CONTROL:
m_bCtrlOn=true;
break;
case 0x56: //붙여넣기
if(!m_bShiftOn)
{
if(DeleteSelectText())
{
SetSelectIndexBegin(0);
SetSelectIndexEnd(0);
}
}
if(m_bCtrlOn)
{
int pos=GetCursorPos();
std::string strTmp = GetFromClipBoard();
std::wstring wStr;
if( IsUseClipException() )
{ //예외 문자열 삭제, 각종 스트링 특수 테그들
ClearExceptionList( strTmp );
}
wchar_t wbuff[1024] = {0,};
// AziaMafia CP_UTF8
// size_t len = ::MultiByteToWideChar(m_pInput->GetCodePage(), 0, strTmp.c_str(), strTmp.size(), wbuff, 1024);
size_t len = ::MultiByteToWideChar(m_pInput->GetCodePage(), 0, strTmp.c_str(), strTmp.size(), wbuff, 1024 );
TextPaste(wbuff,len,pos);
}
break;
case 0x58: //잘라내기
if(m_bCtrlOn)
{
std::wstring strString = TextCut();
CopyToClipBoard( m_pInput->GetCodePage(), strString.c_str(), strString.size() );
}
break;
case 0x43://복사
if(m_bCtrlOn)
{
std::wstring strString = TextCopy();
CopyToClipBoard( m_pInput->GetCodePage(), strString.c_str(), strString.size() );
}
break;
case VK_HOME:
// 2010.06.22 - prodongi
m_scrollInfo.setCompBuffer(NULL);
m_nSelectIndexBegin=0;
m_nSelectIndexEnd=0;
textLen = m_pInput->GetInput(text, _countof(text));
if(textLen) // g_input의 input버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearInput();
}
textLen = m_pInput->GetComp(text, _countof(text));
if(textLen) // g_input의 input버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearComp();
}
m_nCursorPos=1;
// 2010.06.08 - prodongi
CurrentCursorPos();
// 2010.06.07 - prodongi
if (m_scrollInfo.m_is)
{
m_scrollInfo.syncPosAtStart(m_nCursorPos, m_InputBuffer, m_pInput->GetCodePage());
m_scrollInfo.setCursorPos(m_nCursorPos);
}
break;
case VK_END:
// 2010.06.22 - prodongi
m_scrollInfo.setCompBuffer(NULL);
m_nSelectIndexBegin=0;
m_nSelectIndexEnd=0;
textLen = m_pInput->GetInput(text, _countof(text));
if(textLen) // g_input의 input버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearInput();
}
textLen = m_pInput->GetComp(text, _countof(text));
if(textLen) // g_input의 input버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearComp();
}
m_nCursorPos=m_InputBuffer.size()+1;
// 2010.06.08 - prodongi
CurrentCursorPos();
// 2010.06.07 - prodongi
if (m_scrollInfo.m_is)
{
m_scrollInfo.syncPosAtEnd(m_nCursorPos, m_InputBuffer, m_pInput->GetCodePage());
m_scrollInfo.setCursorPos(m_nCursorPos);
}
break;
case VK_DELETE:
if(!DeleteSelectText())
{
if(!(m_nCursorPos==m_InputBuffer.size()+1))
{
if(m_InputBuffer.size())
{
#ifdef _COUNTRY_TL_
int cursorlen= LocalizationTL::GetCursorLength(m_InputBuffer.c_str(), m_InputBuffer.size(), m_nCursorPos);
m_InputBuffer.erase(m_nCursorPos-1,cursorlen);
#else
m_InputBuffer.erase(m_nCursorPos-1,1);
#endif
// 2010.06.04 - prodongi
if (m_scrollInfo.m_is)
m_scrollInfo.syncPosAtStart(m_scrollInfo.m_startPos, m_InputBuffer, m_pInput->GetCodePage());
//m_scrollInfo.syncPos(m_nCursorPos, m_InputBuffer, m_pInput->GetCodePage());
}
}
}
return false;
break;
}
return true;
}
bool CEditBoxInfo::OnKeyUp(WPARAM wParam)
{
switch(wParam)
{
case VK_SHIFT:
m_OldCursorPos=0;
m_bShiftOn=false;
break;
case VK_CONTROL:
m_bCtrlOn=false;
break;
}
return true;
}
bool CEditBoxInfo::OnMouseMessage( DWORD dwMessage, int x, int y )
{
int cursorpos;
static bool bLButttonDown=false;
static int StartxPos=0;
wchar_t text[256] = {0,};
int textLen;
switch(dwMessage)
{
case WM_MOUSEMOVE:
if(bLButttonDown)
{
cursorpos=FindMouseTextPos(x);
if(!GetSelectIndexBegin())
{
if(StartxPos>=0)
{
SetSelectIndexBegin(StartxPos+1);
}
else
{
bLButttonDown=false;
}
}
if(cursorpos>=0&&bLButttonDown)
{
SetSelectIndexEnd(cursorpos+1);
#ifdef _COUNTRY_TL_
// 태국의 경우 cursorpos 가 이미 몇byte째로 가야 하는지 나와버림
m_nCursorPos = cursorpos + 1;
#else
CursorPosUpdate((cursorpos+1)-GetCursorPos());
#endif
// 2010.06.08 - prodongi
if (m_scrollInfo.m_is)
m_scrollInfo.setCursorPos(m_nCursorPos);
}
else
{
textLen=0;
}
}
break;
case WM_LBUTTONDOWN:
SetSelectIndexBegin(0);
SetSelectIndexEnd(0);
textLen = m_pInput->GetInput(text, _countof(text));
if(textLen) // If there is even one item left in g_inputs input buffer, immediately put it into g_editboxinfos input buffer and then clear it.
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearInput();
}
textLen = m_pInput->GetComp(text, _countof(text));
if(textLen) // g_input의 comp버퍼에 하나라도 남아잇음 바로 g_editboxinfo의 input버퍼에 바로 넣어주고 비워줌
{
wchar_t temp;
memcpy(&temp,text,sizeof(temp));
AddInputBuffer(text,textLen);
m_pInput->ClearComp();
}
cursorpos=FindMouseTextPos(x);
if(cursorpos>=0)
{
#ifdef _COUNTRY_TL_
// 태국의 경우 cursorpos 가 이미 몇byte째로 가야 하는지 나와버림
m_nCursorPos = cursorpos + 1;
#else
CursorPosUpdate((cursorpos+1)-GetCursorPos());
#endif
StartxPos=cursorpos;
bLButttonDown=true;
// 2010.06.08 - prodongi
if (m_scrollInfo.m_is)
m_scrollInfo.setCursorPos(m_nCursorPos);
}
// 2010.06.23 커서가 에디트 박스의 끝으로 가도록 한다- prodongi
else if (m_scrollInfo.m_is)
{
DWORD clipStringWidth = m_scrollInfo.getClipStringWidth(m_pInput->GetCodePage());
if (x >= (int)clipStringWidth)
{
#ifdef _COUNTRY_TL_
// 태국의 경우 cursorpos 가 이미 몇byte째로 가야 하는지 나와버림
m_nCursorPos = m_scrollInfo.m_endPos;
#else
CursorPosUpdate(m_scrollInfo.m_endPos);
#endif
StartxPos=m_scrollInfo.m_endPos;
bLButttonDown=true;
// 2010.06.08 - prodongi
if (m_scrollInfo.m_is)
m_scrollInfo.setCursorPos(m_nCursorPos);
}
}
break;
case WM_LBUTTONUP:
bLButttonDown=false;
break;
case WM_LBUTTONDBLCLK:
cursorpos=FindMouseTextPos(x);
int start,end;
start=FindNearSpace(cursorpos+1,false);
end=FindNearSpace(cursorpos+1,true);
SetSelectIndexBegin(start+1);
SetSelectIndexEnd(end+1);
CursorPosUpdate(end+1-(GetCursorPos()));
// 2010.06.16 - prodongi
if (m_scrollInfo.m_is)
m_scrollInfo.setCursorPos(m_nCursorPos);
break;
}
return true;
}
int CEditBoxInfo::FindMouseTextPos(int pos)
{
if( m_InputBuffer.empty() ) return 0;
//문자열의 맨뒤에 공백 문자도 추가해서 검색해야 함...
//m_InputBuffer[m_InputBuffer.size()]=L' ';
//m_InputBuffer[m_InputBuffer.size()+1]=0;
//m_InputBuffer += L" ";
#ifdef _COUNTRY_TL_
// 젠장 태국-_-
char buf[20000] = {0, };
WORD wCodePage = 874;
int nLength = ::WideCharToMultiByte(wCodePage, 0, m_InputBuffer.c_str(), m_InputBuffer.size(), NULL, 0, NULL, NULL); // 저장된 문자열 길이
::WideCharToMultiByte(wCodePage, 0, m_InputBuffer.c_str(), m_InputBuffer.size(), buf, nLength, NULL, NULL);
const char* p = buf;
std::string sLine;
int nCharCount = 0, curPos = m_InputBuffer.size();
for (; *p != 0; )
{ // 무식하게 1글짜씩 넣어보면서 사이즈 오버되는 부분을 찾는다..
nCharCount++;
DWORD nWidth, nHeight;
char nowChar[10] = {0, };
const char* p1 = LocalizationTL::CharNextTh(p);
memcpy(nowChar, p, p1-p);
sLine += nowChar;
KTextRender::GetStringSize("Tahoma", 10, false, sLine.c_str(),(int)sLine.size(),&nWidth, &nHeight);
if (nWidth > pos)
{
if (curPos == m_InputBuffer.size())
curPos = p - buf;
}
p = p1;
}
// 이걸로 찾은 pos는 문자열의 몇 byte 위치에 커서가 가야 하는가이다. 즉 CursorPosUpdate에서 할일을 했음 이미
return curPos;
#else
return KTextRender::CalcCarretPos("Default",m_InputBuffer.c_str(),pos);
#endif
}
void CEditBoxInfo::AddClipException( const char * pWord, const char * pLastWord )
{
_EXCEPTION_WORD_ exception_word;
exception_word.strWord = pWord;
exception_word.strLastWord = pLastWord;
s_ClipExceptionList.push_back( exception_word );
}
void CEditBoxInfo::SetUseClipException( bool bFlag )
{
s_bUseClipException = bFlag;
}
bool EraseWord( std::string & string, const char * pWord, const char * pLastWord )
{
while( true )
{
std::string::size_type pos = string.find( pWord );
if( std::string::npos != pos )
{
std::string::size_type pos2 = string.find( pLastWord, pos );
if( std::string::npos != pos )
{
string.erase( pos, pos2+1 );
}
}
else
break;
}
return true;
}
void CEditBoxInfo::ClearExceptionList( std::string & string )
{
for( unsigned int i(0); s_ClipExceptionList.size()>i; i++ )
{
EraseWord( string, s_ClipExceptionList[i].strWord.c_str(), s_ClipExceptionList[i].strLastWord.c_str() );
}
}
bool CEditBoxInfo::IsCandidate()
{
return m_pInput->IsCandidate();
}
void CEditBoxInfo::setFontFlag(DWORD fontFlag)
{
m_scrollInfo.setFontFlag(fontFlag);
}
// 2010.06.17 - prodongi
void CEditBoxInfo::setBold(bool bold)
{
m_scrollInfo.setBold(bold);
}
void CEditBoxInfo::setFontName(std::string const& fontName)
{
m_scrollInfo.setFontName(fontName);
}
void CEditBoxInfo::setFontSize(int fontSize)
{
m_scrollInfo.setFontSize(fontSize);
}
void CEditBoxInfo::setMaxWidth(int width)
{
m_scrollInfo.setMaxWidth(width);
}
// 2010.06.07 - prodongi
// JTool에서 Edit Box에 캡션이 저장이 안되서, 현재 여기는 is = true로 되지 않고 있다.
void CEditBoxInfo::setCaption(std::string const& caption)
{
bool scroll = false;
if (!caption.empty())
{
size_t pos = caption.find(sScrollInfo::token);
if (std::string::npos != pos)
scroll = true;
}
setScroll(scroll);
}
void CEditBoxInfo::setScroll(bool scroll)
{
m_scrollInfo.setIs(scroll);
}
// 2010.06.23 - prodongi
void CEditBoxInfo::setCompBuffer(wchar_t const* compBuffer)
{
m_scrollInfo.setCompBuffer(compBuffer);
}
// 2010.06.24 - prodongi
void CEditBoxInfo::setAlign(DWORD align)
{
m_scrollInfo.setAlign(align);
}
// 2010.06.24 - prodongi
void CEditBoxInfo::setSpacing(int spacing)
{
m_scrollInfo.setSpacing(spacing);
}
/// 2012.02.16 - prodongi
bool CEditBoxInfo::isEndComposing() const
{
return m_pInput->isEndComposing();
}