https://git.reactos.org/?p=reactos.git;a=commitdiff;h=febb589e00375868302fe…
commit febb589e00375868302fe8d5abb3e801bc6af5b5
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Feb 23 19:58:21 2024 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Fri Feb 23 19:58:21 2024 +0900
[MSCTFIME] Finish msctfime.cpp (#6523)
Supporting TIPs...
JIRA issue: CORE-19360
- Add some CicBridge methods (stub).
- Implement ImeProcessKey,
ImeToAsciiEx, ImeSetCompositionString,
CtfImeEscapeEx, and CtfImeIsIME
functions.
---
dll/ime/msctfime/bridge.cpp | 62 ++++++++++
dll/ime/msctfime/bridge.h | 38 +++++++
dll/ime/msctfime/inputcontext.cpp | 71 ------------
dll/ime/msctfime/inputcontext.h | 7 --
dll/ime/msctfime/misc.cpp | 28 ++++-
dll/ime/msctfime/misc.h | 5 +-
dll/ime/msctfime/msctfime.cpp | 233 ++++++++++++++++++++++++++++++++------
dll/ime/msctfime/msctfime.h | 10 +-
dll/ime/msctfime/profile.cpp | 7 ++
dll/ime/msctfime/profile.h | 2 +
10 files changed, 344 insertions(+), 119 deletions(-)
diff --git a/dll/ime/msctfime/bridge.cpp b/dll/ime/msctfime/bridge.cpp
index cd966083264..9fdc8c4cc39 100644
--- a/dll/ime/msctfime/bridge.cpp
+++ b/dll/ime/msctfime/bridge.cpp
@@ -689,3 +689,65 @@ HRESULT CicBridge::Notify(
{
return E_NOTIMPL; // FIXME
}
+
+/// @unimplemented
+BOOL CicBridge::ProcessKey(
+ TLS *pTLS,
+ ITfThreadMgr_P *pThreadMgr,
+ HIMC hIMC,
+ WPARAM wParam,
+ LPARAM lParam,
+ CONST LPBYTE lpbKeyState,
+ INT *pnUnknown60)
+{
+ return FALSE; // FIXME
+}
+
+/// @unimplemented
+HRESULT
+CicBridge::ToAsciiEx(
+ TLS *pTLS,
+ ITfThreadMgr_P *pThreadMgr,
+ UINT uVirtKey,
+ UINT uScanCode,
+ CONST LPBYTE lpbKeyState,
+ LPTRANSMSGLIST lpTransBuf,
+ UINT fuState,
+ HIMC hIMC,
+ UINT *pResult)
+{
+ return E_NOTIMPL; // FIXME
+}
+
+/// @unimplemented
+BOOL
+CicBridge::SetCompositionString(
+ TLS *pTLS,
+ ITfThreadMgr_P *pThreadMgr,
+ HIMC hIMC,
+ DWORD dwIndex,
+ LPCVOID lpComp,
+ DWORD dwCompLen,
+ LPCVOID lpRead,
+ DWORD dwReadLen)
+{
+ return FALSE; // FIXME
+}
+
+/// @unimplemented
+LRESULT
+CicBridge::EscapeKorean(TLS *pTLS, HIMC hIMC, UINT uSubFunc, LPVOID lpData)
+{
+ return 0; // FIXME
+}
+
+/// @implemented
+BOOL CicBridge::IsOwnDim(ITfDocumentMgr *pDocMgr)
+{
+ DWORD dwDimFlags = 0;
+ HRESULT hr = ::GetCompartmentDWORD(pDocMgr, GUID_COMPARTMENT_CTFIME_DIMFLAGS,
+ &dwDimFlags, FALSE);
+ if (FAILED(hr))
+ return FALSE;
+ return !!(dwDimFlags & 0x1);
+}
diff --git a/dll/ime/msctfime/bridge.h b/dll/ime/msctfime/bridge.h
index fa3919f6953..6e0853ccb7e 100644
--- a/dll/ime/msctfime/bridge.h
+++ b/dll/ime/msctfime/bridge.h
@@ -94,4 +94,42 @@ public:
DWORD dwAction,
DWORD dwIndex,
DWORD_PTR dwValue);
+
+ BOOL ProcessKey(
+ TLS *pTLS,
+ ITfThreadMgr_P *pThreadMgr,
+ HIMC hIMC,
+ WPARAM wParam,
+ LPARAM lParam,
+ CONST LPBYTE lpbKeyState,
+ INT *pnUnknown60);
+
+ HRESULT ToAsciiEx(
+ TLS *pTLS,
+ ITfThreadMgr_P *pThreadMgr,
+ UINT uVirtKey,
+ UINT uScanCode,
+ CONST LPBYTE lpbKeyState,
+ LPTRANSMSGLIST lpTransBuf,
+ UINT fuState,
+ HIMC hIMC,
+ UINT *pResult);
+
+ BOOL SetCompositionString(
+ TLS *pTLS,
+ ITfThreadMgr_P *pThreadMgr,
+ HIMC hIMC,
+ DWORD dwIndex,
+ LPCVOID lpComp,
+ DWORD dwCompLen,
+ LPCVOID lpRead,
+ DWORD dwReadLen);
+
+ LRESULT EscapeKorean(
+ TLS *pTLS,
+ HIMC hIMC,
+ UINT uSubFunc,
+ LPVOID lpData);
+
+ static BOOL IsOwnDim(ITfDocumentMgr *pDocMgr);
};
diff --git a/dll/ime/msctfime/inputcontext.cpp b/dll/ime/msctfime/inputcontext.cpp
index a208fe8885a..86ffb1f5627 100644
--- a/dll/ime/msctfime/inputcontext.cpp
+++ b/dll/ime/msctfime/inputcontext.cpp
@@ -308,74 +308,3 @@ HRESULT CicInputContext::EndReconvertString(CicIMCLock& imcLock)
{
return E_NOTIMPL;
}
-
-/// Retrieves the IME information.
-/// @implemented
-HRESULT
-Inquire(
- _Out_ LPIMEINFO lpIMEInfo,
- _Out_ LPWSTR lpszWndClass,
- _In_ DWORD dwSystemInfoFlags,
- _In_ HKL hKL)
-{
- if (!lpIMEInfo)
- return E_OUTOFMEMORY;
-
- StringCchCopyW(lpszWndClass, 64, L"MSCTFIME UI");
- lpIMEInfo->dwPrivateDataSize = 0;
-
- switch (LOWORD(hKL)) // Language ID
- {
- case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese
- {
- lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT |
IME_PROP_SPECIAL_UI |
- IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY |
- IME_PROP_KBD_CHAR_FIRST;
- lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_KATAKANA |
- IME_CMODE_NATIVE;
- lpIMEInfo->fdwSentenceCaps = IME_SMODE_CONVERSATION |
IME_SMODE_PLAURALCLAUSE;
- lpIMEInfo->fdwSelectCaps = SELECT_CAP_SENTENCE | SELECT_CAP_CONVERSION;
- lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD |
- SCS_CAP_COMPSTR;
- lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
- break;
- }
- case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean
- {
- lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT |
IME_PROP_SPECIAL_UI |
- IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY |
- IME_PROP_KBD_CHAR_FIRST;
- lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
- lpIMEInfo->fdwSentenceCaps = 0;
- lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_COMPSTR;
- lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;
- lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
- break;
- }
- case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Simplified Chinese
- case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Traditional
Chinese
- {
- lpIMEInfo->fdwProperty = IME_PROP_SPECIAL_UI | IME_PROP_AT_CARET |
- IME_PROP_NEED_ALTKEY | IME_PROP_KBD_CHAR_FIRST;
- lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
- lpIMEInfo->fdwSentenceCaps = SELECT_CAP_CONVERSION;
- lpIMEInfo->fdwSelectCaps = 0;
- lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD |
- SCS_CAP_COMPSTR;
- lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
- break;
- }
- default: // Otherwise
- {
- lpIMEInfo->fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET;
- lpIMEInfo->fdwConversionCaps = 0;
- lpIMEInfo->fdwSentenceCaps = 0;
- lpIMEInfo->fdwSCSCaps = 0;
- lpIMEInfo->fdwUICaps = 0;
- lpIMEInfo->fdwSelectCaps = 0;
- break;
- }
- }
-
- return S_OK;
-}
diff --git a/dll/ime/msctfime/inputcontext.h b/dll/ime/msctfime/inputcontext.h
index 695aa5a158c..7ae33906fd5 100644
--- a/dll/ime/msctfime/inputcontext.h
+++ b/dll/ime/msctfime/inputcontext.h
@@ -13,13 +13,6 @@
class CInputContextOwnerCallBack;
class CInputContextOwner;
-HRESULT
-Inquire(
- _Out_ LPIMEINFO lpIMEInfo,
- _Out_ LPWSTR lpszWndClass,
- _In_ DWORD dwSystemInfoFlags,
- _In_ HKL hKL);
-
/***********************************************************************
* CicInputContext
*
diff --git a/dll/ime/msctfime/misc.cpp b/dll/ime/msctfime/misc.cpp
index 5b899c2ccfc..5e8ae5003f6 100644
--- a/dll/ime/msctfime/misc.cpp
+++ b/dll/ime/msctfime/misc.cpp
@@ -11,7 +11,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
/// East-Asian language?
/// @implemented
-BOOL IsEALang(LANGID LangID)
+BOOL IsEALang(_In_opt_ LANGID LangID)
{
if (LangID == 0)
{
@@ -99,6 +99,32 @@ HIMC GetActiveContext(VOID)
return ::ImmGetContext(hwndFocus);
}
+// MSIMTF.dll!MsimtfIsGuidMapEnable
+typedef BOOL (WINAPI *FN_MsimtfIsGuidMapEnable)(HIMC hIMC, LPBOOL pbValue);
+HINSTANCE g_hMSIMTF = NULL;
+
+/// @implemented
+BOOL MsimtfIsGuidMapEnable(_In_ HIMC hIMC, _Out_opt_ LPBOOL pbValue)
+{
+ static FN_MsimtfIsGuidMapEnable s_fn = NULL;
+ if (!cicGetFN(g_hMSIMTF, s_fn, L"msimtf.dll",
"MsimtfIsGuidMapEnable"))
+ return FALSE;
+ return s_fn(hIMC, pbValue);
+}
+
+/// @implemented
+BOOL IsVKDBEKey(_In_ UINT uVirtKey)
+{
+ switch (uVirtKey)
+ {
+ case VK_KANJI:
+ case VK_CONVERT:
+ return TRUE;
+ default:
+ return (VK_OEM_ATTN <= uVirtKey && uVirtKey <= VK_PA1);
+ }
+}
+
/// @implemented
ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread)
{
diff --git a/dll/ime/msctfime/misc.h b/dll/ime/msctfime/misc.h
index d5d17f15f53..1e7ba0d716b 100644
--- a/dll/ime/msctfime/misc.h
+++ b/dll/ime/msctfime/misc.h
@@ -8,10 +8,13 @@
#pragma once
BOOLEAN DllShutdownInProgress(VOID);
-BOOL IsEALang(LANGID LangID);
+BOOL IsEALang(_In_opt_ LANGID LangID);
BOOL IsInteractiveUserLogon(VOID);
BYTE GetCharsetFromLangId(_In_ DWORD dwValue);
HIMC GetActiveContext(VOID);
+BOOL MsimtfIsGuidMapEnable(_In_ HIMC hIMC, _Out_opt_ LPBOOL pbValue);
+BOOL IsVKDBEKey(_In_ UINT uVirtKey);
+
ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread);
HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread);
HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread);
diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp
index cd4b4af212c..60176204374 100644
--- a/dll/ime/msctfime/msctfime.cpp
+++ b/dll/ime/msctfime/msctfime.cpp
@@ -24,7 +24,7 @@ EXTERN_C void __cxa_pure_virtual(void)
/// Selects or unselects the input context.
/// @implemented
-HRESULT
+static HRESULT
InternalSelectEx(
_In_ HIMC hIMC,
_In_ BOOL fSelect,
@@ -77,7 +77,7 @@ InternalSelectEx(
// Get logical font
LOGFONTW lf;
HDC hDC = ::GetDC(imcLock.get().hWnd);
- HGDIOBJ hFont = GetCurrentObject(hDC, OBJ_FONT);
+ HGDIOBJ hFont = ::GetCurrentObject(hDC, OBJ_FONT);
::GetObjectW(hFont, sizeof(LOGFONTW), &lf);
::ReleaseDC(imcLock.get().hWnd, hDC);
@@ -91,6 +91,77 @@ InternalSelectEx(
return imcLock.m_hr;
}
+/// Retrieves the IME information.
+/// @implemented
+HRESULT
+Inquire(
+ _Out_ LPIMEINFO lpIMEInfo,
+ _Out_ LPWSTR lpszWndClass,
+ _In_ DWORD dwSystemInfoFlags,
+ _In_ HKL hKL)
+{
+ if (!lpIMEInfo)
+ return E_OUTOFMEMORY;
+
+ StringCchCopyW(lpszWndClass, 64, L"MSCTFIME UI");
+ lpIMEInfo->dwPrivateDataSize = 0;
+
+ switch (LOWORD(hKL)) // Language ID
+ {
+ case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese
+ {
+ lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT |
IME_PROP_SPECIAL_UI |
+ IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY |
+ IME_PROP_KBD_CHAR_FIRST;
+ lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_KATAKANA |
+ IME_CMODE_NATIVE;
+ lpIMEInfo->fdwSentenceCaps = IME_SMODE_CONVERSATION |
IME_SMODE_PLAURALCLAUSE;
+ lpIMEInfo->fdwSelectCaps = SELECT_CAP_SENTENCE | SELECT_CAP_CONVERSION;
+ lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD |
+ SCS_CAP_COMPSTR;
+ lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
+ break;
+ }
+ case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean
+ {
+ lpIMEInfo->fdwProperty = IME_PROP_COMPLETE_ON_UNSELECT |
IME_PROP_SPECIAL_UI |
+ IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY |
+ IME_PROP_KBD_CHAR_FIRST;
+ lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
+ lpIMEInfo->fdwSentenceCaps = 0;
+ lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_COMPSTR;
+ lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;
+ lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
+ break;
+ }
+ case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Simplified Chinese
+ case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Traditional
Chinese
+ {
+ lpIMEInfo->fdwProperty = IME_PROP_SPECIAL_UI | IME_PROP_AT_CARET |
+ IME_PROP_NEED_ALTKEY | IME_PROP_KBD_CHAR_FIRST;
+ lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
+ lpIMEInfo->fdwSentenceCaps = SELECT_CAP_CONVERSION;
+ lpIMEInfo->fdwSelectCaps = 0;
+ lpIMEInfo->fdwSCSCaps = SCS_CAP_SETRECONVERTSTRING | SCS_CAP_MAKEREAD |
+ SCS_CAP_COMPSTR;
+ lpIMEInfo->fdwUICaps = UI_CAP_ROT90;
+ break;
+ }
+ default: // Otherwise
+ {
+ lpIMEInfo->fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET;
+ lpIMEInfo->fdwConversionCaps = 0;
+ lpIMEInfo->fdwSentenceCaps = 0;
+ lpIMEInfo->fdwSCSCaps = 0;
+ lpIMEInfo->fdwUICaps = 0;
+ lpIMEInfo->fdwSelectCaps = 0;
+ break;
+ }
+ }
+
+ return S_OK;
+}
+
/***********************************************************************
* ImeInquire (MSCTFIME.@)
*
@@ -229,13 +300,13 @@ ImeConfigure(
if (!pTLS || !pTLS->m_pBridge || !pTLS->m_pThreadMgr)
return FALSE;
- CicBridge *pBridge = pTLS->m_pBridge;
- ITfThreadMgr *pThreadMgr = pTLS->m_pThreadMgr;
+ auto pBridge = pTLS->m_pBridge;
+ auto pThreadMgr = pTLS->m_pThreadMgr;
- if (dwMode & 1)
+ if (dwMode & 0x1)
return (pBridge->ConfigureGeneral(pTLS, pThreadMgr, hKL, hWnd) == S_OK);
- if (dwMode & 2)
+ if (dwMode & 0x2)
return (pBridge->ConfigureRegisterWord(pTLS, pThreadMgr, hKL, hWnd, lpData) ==
S_OK);
return FALSE;
@@ -288,15 +359,55 @@ ImeEscape(
return 0;
}
+/***********************************************************************
+ * ImeProcessKey (MSCTFIME.@)
+ *
+ * @implemented
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeProcessKey.html
+ */
EXTERN_C BOOL WINAPI
ImeProcessKey(
_In_ HIMC hIMC,
- _In_ UINT uVirKey,
+ _In_ UINT uVirtKey,
_In_ LPARAM lParam,
_In_ CONST LPBYTE lpbKeyState)
{
- FIXME("stub:(%p, %u, %p, lpbKeyState)\n", hIMC, uVirKey, lParam,
lpbKeyState);
- return FALSE;
+ TRACE("(%p, %u, %p, lpbKeyState)\n", hIMC, uVirtKey, lParam, lpbKeyState);
+
+ TLS *pTLS = TLS::GetTLS();
+ if (!pTLS)
+ return FALSE;
+
+ auto pBridge = pTLS->m_pBridge;
+ auto pThreadMgr = pTLS->m_pThreadMgr;
+ if (!pBridge || !pThreadMgr)
+ return FALSE;
+
+ if (pTLS->m_dwFlags1 & 0x1)
+ {
+ ITfDocumentMgr *pDocMgr = NULL;
+ pThreadMgr->GetFocus(&pDocMgr);
+ if (pDocMgr && !CicBridge::IsOwnDim(pDocMgr))
+ {
+ pDocMgr->Release();
+ return FALSE;
+ }
+
+ if (pDocMgr)
+ pDocMgr->Release();
+ }
+
+ LANGID LangID = LOWORD(::GetKeyboardLayout(0));
+ if (((pTLS->m_dwFlags2 & 1) && MsimtfIsGuidMapEnable(hIMC, NULL)) ||
+ ((lParam & (KF_ALTDOWN << 16)) &&
+ (LangID == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) &&
+ IsVKDBEKey(uVirtKey)))
+ {
+ return FALSE;
+ }
+
+ INT nUnknown60 = 0;
+ return pBridge->ProcessKey(pTLS, pThreadMgr, hIMC, uVirtKey, lParam, lpbKeyState,
&nUnknown60);
}
/***********************************************************************
@@ -335,18 +446,37 @@ ImeSetActiveContext(
return FALSE;
}
+/***********************************************************************
+ * ImeToAsciiEx (MSCTFIME.@)
+ *
+ * @implemented
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeToAsciiEx.html
+ */
EXTERN_C UINT WINAPI
ImeToAsciiEx(
- _In_ UINT uVirKey,
+ _In_ UINT uVirtKey,
_In_ UINT uScanCode,
_In_ CONST LPBYTE lpbKeyState,
_Out_ LPTRANSMSGLIST lpTransMsgList,
_In_ UINT fuState,
_In_ HIMC hIMC)
{
- FIXME("stub:(%u, %u, %p, %p, %u, %p)\n", uVirKey, uScanCode, lpbKeyState,
lpTransMsgList,
+ TRACE("(%u, %u, %p, %p, %u, %p)\n", uVirtKey, uScanCode, lpbKeyState,
lpTransMsgList,
fuState, hIMC);
- return 0;
+
+ TLS *pTLS = TLS::GetTLS();
+ if (!pTLS)
+ return 0;
+
+ auto pBridge = pTLS->m_pBridge;
+ auto pThreadMgr = pTLS->m_pThreadMgr;
+ if (!pBridge || !pThreadMgr)
+ return 0;
+
+ UINT ret = 0;
+ HRESULT hr = pBridge->ToAsciiEx(pTLS, pThreadMgr, uVirtKey, uScanCode,
lpbKeyState,
+ lpTransMsgList, fuState, hIMC, &ret);
+ return ((hr == S_OK) ? ret : 0);
}
/***********************************************************************
@@ -377,6 +507,12 @@ NotifyIME(
return (hr == S_OK);
}
+/***********************************************************************
+ * ImeSetCompositionString (MSCTFIME.@)
+ *
+ * @implemented
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeSetCompositionStr…
+ */
EXTERN_C BOOL WINAPI
ImeSetCompositionString(
_In_ HIMC hIMC,
@@ -386,23 +522,20 @@ ImeSetCompositionString(
_In_opt_ LPCVOID lpRead,
_In_ DWORD dwReadLen)
{
- FIXME("stub:(%p, 0x%lX, %p, 0x%lX, %p, 0x%lX)\n", hIMC, dwIndex, lpComp,
dwCompLen,
+ TRACE("(%p, 0x%lX, %p, 0x%lX, %p, 0x%lX)\n", hIMC, dwIndex, lpComp,
dwCompLen,
lpRead, dwReadLen);
- return FALSE;
-}
-EXTERN_C DWORD WINAPI
-ImeGetImeMenuItems(
- _In_ HIMC hIMC,
- _In_ DWORD dwFlags,
- _In_ DWORD dwType,
- _Inout_opt_ LPIMEMENUITEMINFOW lpImeParentMenu,
- _Inout_opt_ LPIMEMENUITEMINFOW lpImeMenu,
- _In_ DWORD dwSize)
-{
- FIXME("stub:(%p, 0x%lX, 0x%lX, %p, %p, 0x%lX)\n", hIMC, dwFlags, dwType,
lpImeParentMenu,
- lpImeMenu, dwSize);
- return 0;
+ TLS *pTLS = TLS::GetTLS();
+ if (!pTLS)
+ return FALSE;
+
+ auto pBridge = pTLS->m_pBridge;
+ auto pThreadMgr = pTLS->m_pThreadMgr;
+ if (!pBridge || !pThreadMgr)
+ return FALSE;
+
+ return pBridge->SetCompositionString(pTLS, pThreadMgr, hIMC, dwIndex,
+ lpComp, dwCompLen, lpRead, dwReadLen);
}
/***********************************************************************
@@ -459,6 +592,11 @@ CtfImeSelectEx(
return pTLS->m_pBridge->SelectEx(pTLS, pTLS->m_pThreadMgr, hIMC, fSelect,
hKL);
}
+/***********************************************************************
+ * CtfImeEscapeEx (MSCTFIME.@)
+ *
+ * @implemented
+ */
EXTERN_C LRESULT WINAPI
CtfImeEscapeEx(
_In_ HIMC hIMC,
@@ -466,8 +604,16 @@ CtfImeEscapeEx(
_Inout_opt_ LPVOID lpData,
_In_ HKL hKL)
{
- FIXME("stub:(%p, %u, %p, %p)\n", hIMC, uSubFunc, lpData, hKL);
- return 0;
+ TRACE("(%p, %u, %p, %p)\n", hIMC, uSubFunc, lpData, hKL);
+
+ if (LOWORD(hKL) != MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT))
+ return 0;
+
+ TLS *pTLS = TLS::GetTLS();
+ if (!pTLS || !pTLS->m_pBridge)
+ return 0;
+
+ return pTLS->m_pBridge->EscapeKorean(pTLS, hIMC, uSubFunc, lpData);
}
/***********************************************************************
@@ -555,7 +701,6 @@ CtfImeCreateThreadMgr(VOID)
return hr;
}
-
/***********************************************************************
* CtfImeDestroyThreadMgr (MSCTFIME.@)
*
@@ -709,23 +854,37 @@ CtfImeDispatchDefImeMessage(
if (!IsMsImeMessage(uMsg))
return 0;
- HKL hKL = GetKeyboardLayout(0);
+ HKL hKL = ::GetKeyboardLayout(0);
if (IS_IME_HKL(hKL))
return 0;
- HWND hImeWnd = (HWND)SendMessageW(hWnd, WM_IME_NOTIFY, 0x17, 0);
+ HWND hImeWnd = (HWND)::SendMessageW(hWnd, WM_IME_NOTIFY, 0x17, 0);
if (!IsWindow(hImeWnd))
return 0;
- return SendMessageW(hImeWnd, uMsg, wParam, lParam);
+ return ::SendMessageW(hImeWnd, uMsg, wParam, lParam);
}
+/***********************************************************************
+ * CtfImeIsIME (MSCTFIME.@)
+ *
+ * @implemented
+ */
EXTERN_C BOOL WINAPI
CtfImeIsIME(
_In_ HKL hKL)
{
- FIXME("stub:(%p)\n", hKL);
- return FALSE;
+ TRACE("(%p)\n", hKL);
+
+ if (IS_IME_HKL(hKL))
+ return TRUE;
+
+ TLS *pTLS = TLS::GetTLS();
+ if (!pTLS || !pTLS->m_pProfile)
+ return FALSE;
+
+ // The return value of CicProfile::IsIME is brain-damaged
+ return !pTLS->m_pProfile->IsIME(hKL);
}
/***********************************************************************
@@ -766,7 +925,7 @@ BOOL ProcessAttach(HINSTANCE hinstDLL)
{
g_hInst = hinstDLL;
- InitializeCriticalSectionAndSpinCount(&g_csLock, 0);
+ ::InitializeCriticalSectionAndSpinCount(&g_csLock, 0);
if (!TLS::Initialize())
return FALSE;
@@ -793,7 +952,7 @@ VOID ProcessDetach(HINSTANCE hinstDLL)
TFUninitLib();
}
- DeleteCriticalSection(&g_csLock);
+ ::DeleteCriticalSection(&g_csLock);
TLS::InternalDestroyTLS();
TLS::Uninitialize();
cicDoneUIFLib();
diff --git a/dll/ime/msctfime/msctfime.h b/dll/ime/msctfime/msctfime.h
index 48b184940df..60440f5a92e 100644
--- a/dll/ime/msctfime/msctfime.h
+++ b/dll/ime/msctfime/msctfime.h
@@ -35,11 +35,19 @@
#include <wine/debug.h>
+extern HINSTANCE g_hInst;
extern CRITICAL_SECTION g_csLock;
typedef CicArray<GUID> CDispAttrPropCache;
extern CDispAttrPropCache *g_pPropCache;
+HRESULT
+Inquire(
+ _Out_ LPIMEINFO lpIMEInfo,
+ _Out_ LPWSTR lpszWndClass,
+ _In_ DWORD dwSystemInfoFlags,
+ _In_ HKL hKL);
+
DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95,
0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9);
DEFINE_GUID(GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0x85A688F7, 0x6DC8, 0x4F17, 0xA8,
0x3A, 0xB1, 0x1C, 0x09, 0xCD, 0xD7, 0xBF);
DEFINE_GUID(GUID_MODEBIAS_FILENAME, 0xD7F707FE, 0x44C6, 0x4FCA, 0x8E,
0x76, 0x86, 0xAB, 0x50, 0xC7, 0x93, 0x1B);
@@ -58,5 +66,3 @@ DEFINE_GUID(GUID_PROP_MODEBIAS, 0x372E0716, 0x974F,
0x40AC,
#include "sinks.h"
#include "tls.h"
#include "ui.h"
-
-extern HINSTANCE g_hInst;
diff --git a/dll/ime/msctfime/profile.cpp b/dll/ime/msctfime/profile.cpp
index 9ec7cd12ff3..d8a512987e9 100644
--- a/dll/ime/msctfime/profile.cpp
+++ b/dll/ime/msctfime/profile.cpp
@@ -171,3 +171,10 @@ CicProfile::GetActiveLanguageProfile(
{
return E_NOTIMPL;
}
+
+/// The return value of CicProfile::IsIME is brain-damaged.
+/// @unimplemented
+BOOL CicProfile::IsIME(HKL hKL)
+{
+ return TRUE;
+}
diff --git a/dll/ime/msctfime/profile.h b/dll/ime/msctfime/profile.h
index 2943750ad46..88c277c4b4d 100644
--- a/dll/ime/msctfime/profile.h
+++ b/dll/ime/msctfime/profile.h
@@ -48,4 +48,6 @@ public:
HRESULT GetCodePageA(_Out_ UINT *puCodePage);
HRESULT InitProfileInstance(_Inout_ TLS *pTLS);
+
+ BOOL IsIME(HKL hKL);
};