#include "stdafx.h" #include "ceditboxinfo.h" #include "CInput.h" #include // 2010.08.24 - prodongi #include "KTextPhrase.h" #ifdef _COUNTRY_TL_ #include "./Localization/Thailand.h" #endif // 2010.06.08 - prodongi char* CEditBoxInfo::sScrollInfo::token = ""; // 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(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::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( 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( 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(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( 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_input’s input buffer, immediately put it into g_editboxinfo’s 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(); }