- UserInterface/PythonIME(+Module) ported verbatim; ime module stubs removed, initime() after initdbg() - EterLib/IME.cpp in platform/: 40250 buffer/WMChar bodies, IMM/TSF processors no-op; committed multi-byte text via PythonBoot::UIChar emulating GCS_RESULTSTR - GameApplicationAdapter RunIME* -> CWindowManager; Godot keys -> ui_ime_key/ui_char - port.login_flow/login_live type the account through the IME; chat CG_CHAT round-trip on the fake server - python_game_render_test logs in with Godot key events Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
753 lines
17 KiB
C++
753 lines
17 KiB
C++
// Platform implementation of EterLib/IME.h (40250 EterLib/IME.cpp).
|
|
// The edit buffer (m_wText, cursor, SetText/GetText, OnChar/InsertString, IsMax, the colour-tag aware cursor
|
|
// moves) and WMChar are the 40250 bodies verbatim. What 40250 gets from Win32 IMM/TSF — composition strings,
|
|
// the candidate list, the reading window, keyboard-layout code pages — has no counterpart under Godot: the
|
|
// host delivers committed characters only (Metin2PythonHost.ui_char -> WMChar, or InsertString for text the
|
|
// input code page cannot hold, which is what 40250's ResultProcess does with a GCS_RESULTSTR). Those entry
|
|
// points keep 40250's "no IME present" behaviour: no composition, empty candidate/reading lists.
|
|
#include "EterLib/StdAfx.h"
|
|
#include "EterLib/IME.h"
|
|
#include "EterLib/TextTag.h"
|
|
#include "EterLib/GrpTextInstance.h"
|
|
#include "EterLib/Util.h"
|
|
|
|
#include <algorithm>
|
|
#include <cwctype>
|
|
|
|
namespace
|
|
{
|
|
// 40250 s_aszIndicator[INDICATOR_NON_IME] (IME.cpp:67); CheckInputLocale overwrites it with the locale's
|
|
// two-letter abbreviation, which here is the locale code page's language.
|
|
wchar_t s_aszNonImeIndicator[3] = L"En";
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/ /* Public */
|
|
CIME::CIME()
|
|
{
|
|
ms_hWnd = NULL;
|
|
|
|
ms_bCandidateList = false;
|
|
ms_bReadingInformation = false;
|
|
|
|
Clear();
|
|
|
|
m_max = 0;
|
|
m_userMax = 0;
|
|
|
|
m_bOnlyNumberMode = FALSE;
|
|
m_hOrgIMC = NULL;
|
|
|
|
m_bEnablePaste = false;
|
|
m_bUseDefaultIME = false;
|
|
}
|
|
|
|
CIME::~CIME()
|
|
{
|
|
}
|
|
|
|
// PORT: 40250 loads imm32.dll, disables Cicero, reads the keyboard layout and sets up the TSF sinks. The
|
|
// Godot host has no IMM context; only the part the edit buffer depends on — the input/output code page from
|
|
// CheckInputLocale and SetSupportLevel(2) — is kept.
|
|
bool CIME::Initialize(HWND hWnd)
|
|
{
|
|
if(ms_bInitialized)
|
|
return true;
|
|
ms_hWnd = hWnd;
|
|
|
|
ms_bDisableIMECompletely = true;
|
|
ms_bInitialized = true;
|
|
|
|
CheckInputLocale();
|
|
ChangeInputLanguageWorker();
|
|
SetSupportLevel(2);
|
|
|
|
ms_bUILessMode = false;
|
|
CheckToggleState();
|
|
|
|
return true;
|
|
}
|
|
|
|
void CIME::Uninitialize()
|
|
{
|
|
if ( !ms_bInitialized )
|
|
return;
|
|
ms_hWnd = NULL;
|
|
m_hOrgIMC = NULL;
|
|
ms_bInitialized = false;
|
|
}
|
|
|
|
void CIME::UseDefaultIME()
|
|
{
|
|
m_bUseDefaultIME = true;
|
|
}
|
|
|
|
bool CIME::IsIMEEnabled()
|
|
{
|
|
return ms_bImeEnabled;
|
|
}
|
|
|
|
// PORT: 40250 ImmAssociateContext()s the window; ms_bDisableIMECompletely (no imm32) forces bEnable=false,
|
|
// which is always the case here.
|
|
void CIME::EnableIME(bool bEnable)
|
|
{
|
|
if (!ms_bInitialized || !ms_hWnd)
|
|
return;
|
|
if (ms_bDisableIMECompletely)
|
|
bEnable = false;
|
|
ms_bImeEnabled = bEnable;
|
|
if (bEnable)
|
|
CheckToggleState();
|
|
}
|
|
|
|
void CIME::DisableIME()
|
|
{
|
|
EnableIME(false);
|
|
}
|
|
|
|
void CIME::EnableCaptureInput()
|
|
{
|
|
ms_bCaptureInput = true;
|
|
}
|
|
|
|
void CIME::DisableCaptureInput()
|
|
{
|
|
ms_bCaptureInput = false;
|
|
}
|
|
|
|
bool CIME::IsCaptureEnabled()
|
|
{
|
|
return ms_bCaptureInput;
|
|
}
|
|
|
|
void CIME::Clear()
|
|
{
|
|
ms_lastpos = 0;
|
|
ms_curpos = 0;
|
|
|
|
ms_compLen = 0;
|
|
ms_ulbegin = 0;
|
|
ms_ulend = 0;
|
|
}
|
|
|
|
int CIME::GetReading(std::string & rstrText)
|
|
{
|
|
char reading[IMEREADING_MAXLEN];
|
|
|
|
if(ms_wstrReading.size() == 0)
|
|
return 0;
|
|
int readingLen = WideCharToMultiByte(ms_uOutputCodePage, 0, &ms_wstrReading[0], ms_wstrReading.size(), reading, sizeof(reading), NULL, NULL);
|
|
|
|
rstrText.append(GetCodePageText());
|
|
rstrText.append(reading, reading + readingLen);
|
|
|
|
return rstrText.size();
|
|
}
|
|
|
|
int CIME::GetReadingError()
|
|
{
|
|
return ms_iReadingError;
|
|
}
|
|
|
|
void CIME::SetMax(int iMax)
|
|
{
|
|
m_max = iMax;
|
|
}
|
|
|
|
void CIME::SetUserMax(int iMax)
|
|
{
|
|
m_userMax = iMax;
|
|
}
|
|
|
|
void CIME::SetText(const char* szText, int len)
|
|
{
|
|
ms_compLen = 0;
|
|
ms_ulbegin = 0;
|
|
ms_ulend = 0;
|
|
|
|
const char* begin = szText;
|
|
const char* end = begin + len;
|
|
const char* iter = FindToken(begin, end);
|
|
|
|
int m_wTextLen = sizeof(m_wText)/sizeof(wchar_t);
|
|
|
|
ms_lastpos = MultiByteToWideChar(ms_uInputCodePage, 0, begin, iter-begin, m_wText, m_wTextLen);
|
|
|
|
if (iter < end)
|
|
ms_lastpos += MultiByteToWideChar(ReadToken(iter), 0, (iter+5), end-(iter+5), m_wText+ms_lastpos, m_wTextLen-ms_lastpos);
|
|
|
|
ms_curpos = std::min(ms_curpos, ms_lastpos);
|
|
}
|
|
|
|
int CIME::GetText(std::string & rstrText, bool addCodePage)
|
|
{
|
|
int outCodePage = ms_uOutputCodePage;
|
|
int dataCodePage;
|
|
switch (outCodePage)
|
|
{
|
|
//case 1256: // ARABIC
|
|
case 1268: // VIETNAM
|
|
dataCodePage = CP_UTF8;
|
|
break;
|
|
default:
|
|
dataCodePage = outCodePage;
|
|
}
|
|
|
|
int len = 0;
|
|
char text[IMESTR_MAXLEN];
|
|
|
|
len += WideCharToMultiByte(dataCodePage, 0, m_wText, ms_curpos, text, sizeof(text)-len, NULL, NULL);
|
|
len += WideCharToMultiByte(dataCodePage, 0, m_wszComposition, ms_compLen, text+len, sizeof(text)-len, NULL, NULL);
|
|
len += WideCharToMultiByte(dataCodePage, 0, m_wText+ms_curpos, ms_lastpos-ms_curpos, text+len, sizeof(text)-len, NULL, NULL);
|
|
|
|
int i;
|
|
for(i=0; i<len; ++i)
|
|
if((BYTE)text[i] > 0x7F) break;
|
|
|
|
if(i == len)
|
|
{
|
|
rstrText.append(text, text+len);
|
|
}
|
|
else
|
|
{
|
|
rstrText.append(text, text+i);
|
|
|
|
//if (addCodePage)
|
|
// rstrText.append(GetCodePageText());
|
|
|
|
rstrText.append(text+i, text+len);
|
|
}
|
|
|
|
return rstrText.size();
|
|
}
|
|
|
|
const char* CIME::GetCodePageText()
|
|
{
|
|
static char szCodePage[16];
|
|
|
|
const int defCodePage = GetDefaultCodePage();
|
|
const int outCodePage = ms_uOutputCodePage;
|
|
|
|
if (outCodePage != defCodePage)
|
|
{
|
|
sprintf(szCodePage, "@%04d", outCodePage);
|
|
}
|
|
else
|
|
{
|
|
szCodePage[0] = 0;
|
|
}
|
|
|
|
return szCodePage;
|
|
}
|
|
|
|
int CIME::GetCodePage()
|
|
{
|
|
return ms_uOutputCodePage;
|
|
}
|
|
|
|
int CIME::GetCandidatePageCount()
|
|
{
|
|
return ms_dwCandidatePageSize;
|
|
}
|
|
|
|
int CIME::GetCandidateCount()
|
|
{
|
|
return ms_dwCandidateCount;
|
|
}
|
|
|
|
int CIME::GetCandidate(DWORD index, std::string & rstrText)
|
|
{
|
|
if(index >= MAX_CANDLIST)
|
|
return 0;
|
|
|
|
LPCWSTR wszText = ms_wszCandidate[index];
|
|
if(wszText == NULL)
|
|
return 0;
|
|
|
|
int wTextLen = wcslen(wszText);
|
|
if(wTextLen == 0)
|
|
return 0;
|
|
|
|
char text[IMESTR_MAXLEN];
|
|
int len = ::WideCharToMultiByte(CP_UTF8, 0, wszText, wTextLen, text, sizeof(text), 0, 0);
|
|
|
|
rstrText.append("@9999");
|
|
rstrText.append(text, text+len);
|
|
|
|
return wTextLen;
|
|
}
|
|
|
|
int CIME::GetCandidateSelection()
|
|
{
|
|
return ms_dwCandidateSelection;
|
|
}
|
|
|
|
// PORT: 40250 ImmSetConversionStatus / ImmGetConversionStatus. Without an IMM context the conversion mode is
|
|
// the alphanumeric one (IME_CMODE_ALPHANUMERIC == 0) and cannot be changed.
|
|
void CIME::SetInputMode(DWORD)
|
|
{
|
|
}
|
|
|
|
DWORD CIME::GetInputMode()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void CIME::SetNumberMode()
|
|
{
|
|
m_bOnlyNumberMode = TRUE;
|
|
}
|
|
|
|
void CIME::SetStringMode()
|
|
{
|
|
m_bOnlyNumberMode = FALSE;
|
|
}
|
|
|
|
void CIME::AddExceptKey(wchar_t key)
|
|
{
|
|
m_exceptKey.push_back(key);
|
|
}
|
|
|
|
void CIME::ClearExceptKey()
|
|
{
|
|
m_exceptKey.clear();
|
|
}
|
|
|
|
bool CIME::__IsWritable(wchar_t key)
|
|
{
|
|
if ( m_exceptKey.end() == std::find(m_exceptKey.begin(),m_exceptKey.end(),key) )
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void CIME::EnablePaste(bool bFlag)
|
|
{
|
|
m_bEnablePaste = bFlag;
|
|
}
|
|
|
|
// PORT: 40250 reads CF_TEXT from the Win32 clipboard. The host clipboard is not wired to the extension yet,
|
|
// so this pastes nothing (the same as an empty clipboard).
|
|
void CIME::PasteTextFromClipBoard()
|
|
{
|
|
if (!m_bEnablePaste)
|
|
return;
|
|
}
|
|
|
|
// PORT: 40250 cancels the IMM composition string and closes the candidate list. There is no composition
|
|
// here; the candidate-list close (and its event) is kept.
|
|
void CIME::FinalizeString(bool)
|
|
{
|
|
static bool s_bProcessing = false; // to avoid infinite recursion
|
|
if ( !ms_bInitialized || s_bProcessing )
|
|
return;
|
|
s_bProcessing = true;
|
|
CloseCandidateList();
|
|
s_bProcessing = false;
|
|
}
|
|
|
|
int CIME::GetCompLen()
|
|
{
|
|
return ms_compLen;
|
|
}
|
|
|
|
int CIME::GetULBegin()
|
|
{
|
|
return ms_ulbegin;
|
|
}
|
|
|
|
int CIME::GetULEnd()
|
|
{
|
|
return ms_ulend;
|
|
}
|
|
|
|
void CIME::CloseCandidateList()
|
|
{
|
|
ms_bCandidateList = false;
|
|
ms_dwCandidateCount = 0;
|
|
memset(&ms_wszCandidate, 0, sizeof(ms_wszCandidate));
|
|
if(ms_pEvent)
|
|
ms_pEvent->OnCloseCandidateList();
|
|
}
|
|
|
|
void CIME::CloseReadingInformation()
|
|
{
|
|
CIME::ms_bReadingInformation = false;
|
|
if(CIME::ms_pEvent)
|
|
CIME::ms_pEvent->OnCloseReadingWnd();
|
|
}
|
|
|
|
// PORT: 40250 re-reads the keyboard layout (GETLANG) and re-applies the IME support level when the language
|
|
// changed. The host has one fixed input locale, so only the toggle check and the code-page event remain.
|
|
void CIME::ChangeInputLanguage()
|
|
{
|
|
CheckToggleState();
|
|
ChangeInputLanguageWorker();
|
|
|
|
if(ms_pEvent)
|
|
ms_pEvent->OnChangeCodePage();
|
|
}
|
|
|
|
void CIME::ChangeInputLanguageWorker()
|
|
{
|
|
if ( !ms_bUILessMode )
|
|
ms_iCandListIndexBase = 1;
|
|
SetupImeApi();
|
|
}
|
|
|
|
// PORT: 40250 forces level 3 for the Korean keyboard layout; there is no keyboard layout here.
|
|
void CIME::SetSupportLevel( DWORD dwImeLevel )
|
|
{
|
|
if ( dwImeLevel < 2 || 3 < dwImeLevel )
|
|
return;
|
|
ms_dwIMELevel = dwImeLevel;
|
|
// cancel current composition string.
|
|
FinalizeString();
|
|
}
|
|
|
|
LRESULT CIME::WMInputLanguage(HWND, UINT, WPARAM, LPARAM)
|
|
{
|
|
ChangeInputLanguage();
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CIME::WMStartComposition(HWND, UINT, WPARAM, LPARAM)
|
|
{
|
|
return 1L;
|
|
}
|
|
|
|
// PORT: 40250 pulls GCS_RESULTSTR/GCS_COMPSTR out of the IMM context. The host never sends compositions.
|
|
LRESULT CIME::WMComposition(HWND, UINT, WPARAM, LPARAM)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CIME::WMEndComposition(HWND, UINT, WPARAM, LPARAM)
|
|
{
|
|
ms_compLen = 0;
|
|
ms_ulbegin = 0;
|
|
ms_ulend = 0;
|
|
|
|
if(ms_pEvent)
|
|
ms_pEvent->OnUpdate();
|
|
|
|
return 0L;
|
|
}
|
|
|
|
// PORT: 40250 handles IMN_* candidate/reading/toggle notifications from IMM; none are sent here.
|
|
LRESULT CIME::WMNotify(HWND, UINT, WPARAM, LPARAM)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CIME::WMChar(HWND /*hWnd*/, UINT /*uiMsg*/, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
unsigned char c = (unsigned char)(wParam & 0xff);
|
|
|
|
switch (c)
|
|
{
|
|
case 8:
|
|
if(ms_bCaptureInput == false)
|
|
return 0;
|
|
if (ms_curpos > 0)
|
|
{
|
|
DecCurPos();
|
|
DelCurPos();
|
|
}
|
|
if(ms_pEvent)
|
|
ms_pEvent->OnUpdate();
|
|
return 0;
|
|
break;
|
|
|
|
default:
|
|
if(ms_pEvent) {
|
|
if (ms_pEvent->OnWM_CHAR(wParam, lParam))
|
|
break;
|
|
}
|
|
if(ms_bCaptureInput == false)
|
|
return 0;
|
|
wchar_t w[10];
|
|
MultiByteToWideChar(ms_uInputCodePage, 0, (char*)&c, 1, w, 1);
|
|
|
|
OnChar(w[0]);
|
|
if (w[0] == L'|')
|
|
OnChar(w[0]);
|
|
if(ms_pEvent)
|
|
ms_pEvent->OnUpdate();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/ /* Protected */
|
|
void CIME::IncCurPos()
|
|
{
|
|
if (ms_curpos < ms_lastpos)
|
|
{
|
|
int pos = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos);
|
|
|
|
if (pos > 0)
|
|
ms_curpos = std::min(ms_lastpos, std::max(0, ms_curpos + (pos + 1)));
|
|
else
|
|
++ms_curpos;
|
|
//++ms_curpos;
|
|
}
|
|
}
|
|
|
|
void CIME::DecCurPos()
|
|
{
|
|
if (ms_curpos > 0)
|
|
{
|
|
int pos = FindColorTagStartPosition(m_wText + ms_curpos - 1, ms_curpos);
|
|
|
|
if (pos > 0)
|
|
ms_curpos = std::min(ms_lastpos, std::max(0, ms_curpos - (pos + 1)));
|
|
else
|
|
--ms_curpos;
|
|
//--ms_curpos;
|
|
}
|
|
}
|
|
|
|
int CIME::GetCurPos()
|
|
{
|
|
int pos = GetTextTagOutputLen(m_wText, ms_curpos);
|
|
return pos;
|
|
//return ms_curpos;
|
|
}
|
|
|
|
void CIME::SetCurPos(int offset)
|
|
{
|
|
if (offset < 0 || offset > ms_lastpos)
|
|
{
|
|
ms_curpos = ms_lastpos;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// offset is a position in the rendered text, so it has to be mapped back to the buffer.
|
|
//ms_curpos = min(ms_lastpos, offset);
|
|
ms_curpos = std::min(ms_lastpos, GetTextTagInternalPosFromRenderPos(m_wText, ms_lastpos, offset));
|
|
}
|
|
}
|
|
|
|
void CIME::DelCurPos()
|
|
{
|
|
if (ms_curpos < ms_lastpos)
|
|
{
|
|
int eraseCount = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos) + 1;
|
|
// PORT: 40250 wcscpy()s the overlapping tail down; that is undefined for overlapping buffers, and the
|
|
// buffer is not guaranteed NUL-terminated at ms_lastpos, so move exactly the live tail.
|
|
memmove(m_wText + ms_curpos, m_wText + ms_curpos + eraseCount, sizeof(wchar_t) * (ms_lastpos - ms_curpos - eraseCount));
|
|
ms_lastpos -= eraseCount;
|
|
ms_curpos = std::min(ms_lastpos, ms_curpos);
|
|
}
|
|
}
|
|
|
|
void CIME::PasteString(const char * str)
|
|
{
|
|
const char * begin = str;
|
|
const char * end = str + strlen(str);
|
|
wchar_t m_wText[IMESTR_MAXLEN];
|
|
int wstrLen = MultiByteToWideChar(ms_uInputCodePage, 0, begin, end - begin, m_wText, IMESTR_MAXLEN);
|
|
InsertString(m_wText, wstrLen);
|
|
if(ms_pEvent)
|
|
ms_pEvent->OnUpdate();
|
|
}
|
|
|
|
// PORT: 40250 reads the keyboard layout's default ANSI code page (GetLocaleInfoA LOCALE_IDEFAULTANSICODEPAGE).
|
|
// The host's input locale is the client locale, so its code page (SetDefaultCodePage from locale.cfg) is used.
|
|
void CIME::CheckInputLocale()
|
|
{
|
|
static UINT s_uPrevCodePage = 0xFFFF;
|
|
|
|
ms_uInputCodePage = GetDefaultCodePage();
|
|
if ( s_uPrevCodePage == ms_uInputCodePage )
|
|
return;
|
|
s_uPrevCodePage = ms_uInputCodePage;
|
|
|
|
ms_bVerticalCandidate = false;
|
|
ms_wszCurrentIndicator = s_aszNonImeIndicator;
|
|
|
|
if(ms_uOutputCodePage != 1256) {
|
|
ms_uOutputCodePage = ms_uInputCodePage;
|
|
Clear();
|
|
}
|
|
}
|
|
|
|
// PORT: 40250 asks IMM whether an IME is open; there is none, so the state is IMEUI_STATE_OFF (0).
|
|
void CIME::CheckToggleState()
|
|
{
|
|
CheckInputLocale();
|
|
ms_bChineseIME = false;
|
|
ms_dwImeState = 0;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/ /* Private */
|
|
void CIME::InsertString(wchar_t* wString, int iSize)
|
|
{
|
|
if (IsMax(wString, iSize))
|
|
return;
|
|
|
|
if (ms_curpos < ms_lastpos)
|
|
memmove(m_wText+ms_curpos+iSize, m_wText+ms_curpos, sizeof(wchar_t)*(ms_lastpos-ms_curpos));
|
|
|
|
memcpy(m_wText+ms_curpos, wString, sizeof(wchar_t)*iSize);
|
|
|
|
ms_curpos += iSize;
|
|
ms_lastpos += iSize;
|
|
}
|
|
|
|
void CIME::OnChar(wchar_t c)
|
|
{
|
|
if (m_bOnlyNumberMode)
|
|
if (!iswdigit(c))
|
|
return;
|
|
|
|
if (!__IsWritable(c))
|
|
return;
|
|
|
|
InsertString(&c, 1);
|
|
}
|
|
|
|
// PORT: 40250 maps a keyboard-layout LANGID to its ANSI code page. Only CheckInputLocale's code page is used
|
|
// here (see there), so this answers with it.
|
|
UINT CIME::GetCodePageFromLang(LANGID)
|
|
{
|
|
return GetDefaultCodePage();
|
|
}
|
|
|
|
// PORT: the IMM composition/candidate/reading processors (40250 IME.cpp:951-1227). No IMM context exists.
|
|
void CIME::ResultProcess(HIMC) {}
|
|
void CIME::CompositionProcessBuilding(HIMC) {}
|
|
void CIME::CompositionProcess(HIMC) {}
|
|
void CIME::AttributeProcess(HIMC) {}
|
|
void CIME::CandidateProcess(HIMC) {}
|
|
void CIME::ReadingProcess(HIMC) {}
|
|
|
|
bool CIME::IsMax(const wchar_t* wInput, int len)
|
|
{
|
|
if (ms_lastpos + len > IMESTR_MAXLEN)
|
|
return true;
|
|
|
|
int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, m_wText, ms_lastpos, 0, 0, NULL, NULL);
|
|
int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, wInput, len, 0, 0, NULL, NULL);
|
|
//return textLen + inputLen > m_max;
|
|
|
|
if (textLen + inputLen > m_max)
|
|
return true;
|
|
else if (m_userMax != 0 && m_max != m_userMax)
|
|
{
|
|
std::wstring str = GetTextTagOutputString(m_wText, ms_lastpos);
|
|
std::wstring input = GetTextTagOutputString(wInput, len);
|
|
int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, str.c_str(), str.length(), 0, 0, NULL, NULL);
|
|
int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, input.c_str(), input.length(), 0, 0, NULL, NULL);
|
|
return textLen + inputLen > m_userMax;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// PORT: 40250 identifies the CHT/CHS IME DLL version and the reading-window orientation. No IME DLL here.
|
|
DWORD CIME::GetImeId(UINT)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
bool CIME::GetReadingWindowOrientation()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void CIME::SetupImeApi()
|
|
{
|
|
_GetReadingString = NULL;
|
|
_ShowReadingWindow = NULL;
|
|
}
|
|
|
|
decltype(CIME::_ImmLockIMC) CIME::_ImmLockIMC{};
|
|
|
|
decltype(CIME::_ImmUnlockIMC) CIME::_ImmUnlockIMC{};
|
|
|
|
decltype(CIME::_ImmLockIMCC) CIME::_ImmLockIMCC{};
|
|
|
|
decltype(CIME::_ImmUnlockIMCC) CIME::_ImmUnlockIMCC{};
|
|
|
|
decltype(CIME::_GetReadingString) CIME::_GetReadingString{};
|
|
|
|
decltype(CIME::_ShowReadingWindow) CIME::_ShowReadingWindow{};
|
|
|
|
decltype(CIME::ms_bInitialized) CIME::ms_bInitialized{};
|
|
|
|
decltype(CIME::ms_bDisableIMECompletely) CIME::ms_bDisableIMECompletely{};
|
|
|
|
decltype(CIME::ms_bUILessMode) CIME::ms_bUILessMode{};
|
|
|
|
decltype(CIME::ms_bImeEnabled) CIME::ms_bImeEnabled{};
|
|
|
|
decltype(CIME::ms_bCaptureInput) CIME::ms_bCaptureInput{};
|
|
|
|
decltype(CIME::ms_bChineseIME) CIME::ms_bChineseIME{};
|
|
|
|
decltype(CIME::ms_bUseIMMCandidate) CIME::ms_bUseIMMCandidate{};
|
|
|
|
decltype(CIME::ms_hWnd) CIME::ms_hWnd{};
|
|
|
|
decltype(CIME::ms_hklCurrent) CIME::ms_hklCurrent{};
|
|
|
|
decltype(CIME::ms_szKeyboardLayout) CIME::ms_szKeyboardLayout{};
|
|
|
|
decltype(CIME::ms_stOSVI) CIME::ms_stOSVI{};
|
|
|
|
decltype(CIME::ms_hImm32Dll) CIME::ms_hImm32Dll{};
|
|
|
|
decltype(CIME::ms_hCurrentImeDll) CIME::ms_hCurrentImeDll{};
|
|
|
|
decltype(CIME::ms_dwImeState) CIME::ms_dwImeState{};
|
|
|
|
decltype(CIME::ms_adwId) CIME::ms_adwId{};
|
|
|
|
decltype(CIME::ms_dwIMELevel) CIME::ms_dwIMELevel{};
|
|
|
|
decltype(CIME::ms_dwIMELevelSaved) CIME::ms_dwIMELevelSaved{};
|
|
|
|
decltype(CIME::ms_bCandidateList) CIME::ms_bCandidateList{};
|
|
|
|
decltype(CIME::ms_dwCandidateCount) CIME::ms_dwCandidateCount{};
|
|
|
|
decltype(CIME::ms_bVerticalCandidate) CIME::ms_bVerticalCandidate{};
|
|
|
|
decltype(CIME::ms_iCandListIndexBase) CIME::ms_iCandListIndexBase{};
|
|
|
|
decltype(CIME::ms_wszCandidate) CIME::ms_wszCandidate{};
|
|
|
|
decltype(CIME::ms_dwCandidateSelection) CIME::ms_dwCandidateSelection{};
|
|
|
|
decltype(CIME::ms_dwCandidatePageSize) CIME::ms_dwCandidatePageSize{};
|
|
|
|
decltype(CIME::ms_bReadingInformation) CIME::ms_bReadingInformation{};
|
|
|
|
decltype(CIME::ms_iReadingError) CIME::ms_iReadingError{};
|
|
|
|
decltype(CIME::ms_bHorizontalReading) CIME::ms_bHorizontalReading{};
|
|
|
|
decltype(CIME::ms_wstrReading) CIME::ms_wstrReading{};
|
|
|
|
decltype(CIME::ms_wszCurrentIndicator) CIME::ms_wszCurrentIndicator{};
|
|
|
|
decltype(CIME::ms_pEvent) CIME::ms_pEvent{};
|
|
|
|
decltype(CIME::m_wText) CIME::m_wText{};
|
|
|
|
decltype(CIME::ms_compLen) CIME::ms_compLen{};
|
|
|
|
decltype(CIME::ms_curpos) CIME::ms_curpos{};
|
|
|
|
decltype(CIME::ms_lastpos) CIME::ms_lastpos{};
|
|
|
|
decltype(CIME::ms_ulbegin) CIME::ms_ulbegin{};
|
|
|
|
decltype(CIME::ms_ulend) CIME::ms_ulend{};
|
|
|
|
decltype(CIME::ms_uOutputCodePage) CIME::ms_uOutputCodePage{};
|
|
|
|
decltype(CIME::ms_uInputCodePage) CIME::ms_uInputCodePage{};
|