https://git.reactos.org/?p=reactos.git;a=commitdiff;h=febb589e00375868302fe8d5abb3e801bc6af5b5

commit febb589e00375868302fe8d5abb3e801bc6af5b5
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Fri Feb 23 19:58:21 2024 +0900
Commit:     GitHub <nore...@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/ImeSetCompositionString.html
+ */
 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);
 };

Reply via email to