[USER32][IMM32][INCLUDE] Empower WM_IME_SYSTEM handling (#4603)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Fri, 12 Aug 2022 22:08:18 +0000 (07:08 +0900)
committerGitHub <noreply@github.com>
Fri, 12 Aug 2022 22:08:18 +0000 (07:08 +0900)
- Add code to ImeWnd_OnImeSystem function.
- Add CtfLoadThreadLayout and User32DoImeHelp helper functions.
- Define IMS_... constants (for WM_IME_SYSTEM wParam) and fix some magic numbers.
CORE-11700

dll/win32/imm32/keymsg.c
sdk/include/ddk/immdev.h
win32ss/user/user32/misc/imm.c

index e2d4114..8abd8a5 100644 (file)
@@ -264,14 +264,15 @@ ImmIsUIMessageAW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAns
 typedef struct IMM_DELAY_SET_LANG_BAND
 {
     HWND hWnd;
-    BOOL fFlag;
+    BOOL fSet;
 } IMM_DELAY_SET_LANG_BAND, *PIMM_DELAY_SET_LANG_BAND;
 
+/* Sends a message to set the language band with delay. */
 /* Win: DelaySetLangBand */
 static DWORD APIENTRY Imm32DelaySetLangBandProc(LPVOID arg)
 {
     HWND hwndDefIME;
-    UINT uValue;
+    WPARAM wParam;
     DWORD_PTR lResult;
     PIMM_DELAY_SET_LANG_BAND pSetBand = arg;
 
@@ -280,16 +281,17 @@ static DWORD APIENTRY Imm32DelaySetLangBandProc(LPVOID arg)
     hwndDefIME = ImmGetDefaultIMEWnd(pSetBand->hWnd);
     if (hwndDefIME)
     {
-        uValue = (pSetBand->fFlag ? 0x23 : 0x24);
-        SendMessageTimeoutW(hwndDefIME, WM_IME_SYSTEM, uValue, (LPARAM)pSetBand->hWnd,
+        wParam = (pSetBand->fSet ? IMS_SETLANGBAND : IMS_UNSETLANGBAND);
+        SendMessageTimeoutW(hwndDefIME, WM_IME_SYSTEM, wParam, (LPARAM)pSetBand->hWnd,
                             SMTO_BLOCK | SMTO_ABORTIFHUNG, 5000, &lResult);
     }
     ImmLocalFree(pSetBand);
     return FALSE;
 }
 
+/* Updates the language band. */
 /* Win: CtfImmSetLangBand */
-LRESULT APIENTRY CtfImmSetLangBand(HWND hWnd, BOOL fFlag)
+LRESULT APIENTRY CtfImmSetLangBand(HWND hWnd, BOOL fSet)
 {
     HANDLE hThread;
     PWND pWnd = NULL;
@@ -304,7 +306,7 @@ LRESULT APIENTRY CtfImmSetLangBand(HWND hWnd, BOOL fFlag)
 
     if (pWnd->state2 & WNDS2_WMCREATEMSGPROCESSED)
     {
-        SendMessageTimeoutW(hWnd, 0x505, 0, fFlag, 3, 5000, &lResult);
+        SendMessageTimeoutW(hWnd, 0x505, 0, fSet, 3, 5000, &lResult);
         return lResult;
     }
 
@@ -313,7 +315,7 @@ LRESULT APIENTRY CtfImmSetLangBand(HWND hWnd, BOOL fFlag)
         return 0;
 
     pSetBand->hWnd = hWnd;
-    pSetBand->fFlag = fFlag;
+    pSetBand->fSet = fSet;
 
     hThread = CreateThread(NULL, 0, Imm32DelaySetLangBandProc, pSetBand, 0, NULL);
     if (hThread)
@@ -762,16 +764,17 @@ LRESULT WINAPI ImmSystemHandler(HIMC hIMC, WPARAM wParam, LPARAM lParam)
 
     switch (wParam)
     {
-        case 0x1f:
+        case IMS_SENDNOTIFICATION:
             Imm32SendNotification((BOOL)lParam);
             return 0;
 
-        case 0x20:
+        case IMS_COMPLETECOMPSTR:
             ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
             return 0;
 
-        case 0x23: case 0x24:
-            return CtfImmSetLangBand((HWND)lParam, (wParam == 0x23));
+        case IMS_SETLANGBAND:
+        case IMS_UNSETLANGBAND:
+            return CtfImmSetLangBand((HWND)lParam, (wParam == IMS_SETLANGBAND));
 
         default:
             return 0;
index 33146de..a239dcd 100644 (file)
@@ -25,10 +25,26 @@ extern "C" {
 #define IMC_SETSOFTKBDPOS               0x0014
 
 /* wParam for WM_IME_SYSTEM */
+#define IMS_NOTIFYIMESHOW       0x05
+#define IMS_UPDATEIMEUI         0x06
+#define IMS_SETCANDFORM         0x09
+#define IMS_SETCOMPFONT         0x0A
+#define IMS_SETCOMPFORM         0x0B
+#define IMS_CONFIGURE           0x0D
+#define IMS_SETOPENSTATUS       0x0F
+#define IMS_FREELAYOUT          0x11
+#define IMS_GETCONVSTATUS       0x14
+#define IMS_IMEHELP             0x15
 #define IMS_IMEACTIVATE         0x17
 #define IMS_IMEDEACTIVATE       0x18
 #define IMS_ACTIVATELAYOUT      0x19
 #define IMS_GETIMEMENU          0x1C
+#define IMS_GETCONTEXT          0x1E
+#define IMS_SENDNOTIFICATION    0x1F
+#define IMS_COMPLETECOMPSTR     0x20
+#define IMS_LOADTHREADLAYOUT    0x21
+#define IMS_SETLANGBAND         0x23
+#define IMS_UNSETLANGBAND       0x24
 
 #define IMMGWL_IMC       0
 #define IMMGWL_PRIVATE   (sizeof(LONG))
index 4cfe094..2f1a122 100644 (file)
@@ -164,7 +164,8 @@ static BOOL User32GetImeShowStatus(VOID)
     return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_GETIMESHOWSTATUS);
 }
 
-// Win: SendMessageToUI(pimeui, uMsg, wParam, lParam, !unicode)
+/* Sends a message to the IME UI window. */
+/* Win: SendMessageToUI(pimeui, uMsg, wParam, lParam, !unicode) */
 static LRESULT
 User32SendImeUIMessage(PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode)
 {
@@ -240,7 +241,8 @@ static VOID User32UpdateImcOfImeUI(PIMEUI pimeui, HIMC hNewIMC)
         User32SetImeWindowOfImc(hNewIMC, hImeWnd);
 }
 
-// Win: ImeNotifyHandler
+/* Handles WM_IME_NOTIFY message of the default IME window. */
+/* Win: ImeNotifyHandler */
 static LRESULT ImeWnd_OnImeNotify(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
 {
     LRESULT ret = 0;
@@ -290,7 +292,8 @@ static LRESULT ImeWnd_OnImeNotify(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
     return ret;
 }
 
-// Win: CreateIMEUI
+/* Creates the IME UI window. */
+/* Win: CreateIMEUI */
 static HWND User32CreateImeUIWindow(PIMEUI pimeui, HKL hKL)
 {
     IMEINFOEX ImeInfoEx;
@@ -335,7 +338,8 @@ Quit:
     return hwndUI;
 }
 
-// Win: ImeWndCreateHandler
+/* Initializes the default IME window. */
+/* Win: ImeWndCreateHandler */
 static BOOL ImeWnd_OnCreate(PIMEUI pimeui, LPCREATESTRUCT lpCS)
 {
     PWND pParentWnd, pWnd = pimeui->spwnd;
@@ -369,7 +373,8 @@ static BOOL ImeWnd_OnCreate(PIMEUI pimeui, LPCREATESTRUCT lpCS)
     return TRUE;
 }
 
-// Win: DestroyIMEUI
+/* Destroys the IME UI window. */
+/* Win: DestroyIMEUI */
 static VOID User32DestroyImeUIWindow(PIMEUI pimeui)
 {
     HWND hwndUI = pimeui->hwndUI;
@@ -384,7 +389,8 @@ static VOID User32DestroyImeUIWindow(PIMEUI pimeui)
     pimeui->hwndUI = NULL;
 }
 
-// Win: ImeSelectHandler
+/* Handles WM_IME_SELECT message of the default IME window. */
+/* Win: ImeSelectHandler */
 static VOID ImeWnd_OnImeSelect(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
 {
     HKL hKL;
@@ -414,7 +420,8 @@ static VOID ImeWnd_OnImeSelect(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
     }
 }
 
-// Win: ImeControlHandler(pimeui, wParam, lParam, !unicode)
+/* Handles WM_IME_CONTROL message of the default IME window. */
+/* Win: ImeControlHandler(pimeui, wParam, lParam, !unicode) */
 static LRESULT
 ImeWnd_OnImeControl(PIMEUI pimeui, WPARAM wParam, LPARAM lParam, BOOL unicode)
 {
@@ -536,7 +543,8 @@ ImeWnd_OnImeControl(PIMEUI pimeui, WPARAM wParam, LPARAM lParam, BOOL unicode)
     return 0;
 }
 
-// Win: FocusSetIMCContext
+/* Modify the IME activation status. */
+/* Win: FocusSetIMCContext */
 static VOID FASTCALL User32SetImeActivenessOfWindow(HWND hWnd, BOOL bActive)
 {
     HIMC hIMC;
@@ -552,7 +560,52 @@ static VOID FASTCALL User32SetImeActivenessOfWindow(HWND hWnd, BOOL bActive)
     IMM_FN(ImmReleaseContext)(hWnd, hIMC);
 }
 
-// Win: ImeSystemHandler
+/* Win: CtfLoadThreadLayout */
+VOID FASTCALL CtfLoadThreadLayout(PIMEUI pimeui)
+{
+    IMM_FN(CtfImmTIMActivate)(pimeui->hKL);
+    pimeui->hKL = GetWin32ClientInfo()->hKL;
+    IMM_FN(ImmLoadIME)(pimeui->hKL);
+    pimeui->hwndUI = NULL;
+}
+
+/* Open the IME help or check the existence of the IME help. */
+static LRESULT FASTCALL
+User32DoImeHelp(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
+{
+    WCHAR szHelpFile[MAX_PATH];
+    DWORD ret, dwEsc = IME_ESC_GETHELPFILENAME;
+    size_t cch;
+
+    /* Is there any IME help file? */
+    ret = IMM_FN(ImmEscapeW)(pimeui->hKL, pimeui->hIMC, IME_ESC_QUERY_SUPPORT, &dwEsc);
+    if (!ret || !lParam)
+        return ret;
+
+    /* Get the help filename */
+    if (IMM_FN(ImmEscapeW)(pimeui->hKL, pimeui->hIMC, IME_ESC_GETHELPFILENAME, szHelpFile))
+    {
+        /* Check filename extension */
+        cch = wcslen(szHelpFile);
+        if (cch > 4 && _wcsicmp(&szHelpFile[cch - 4], L".HLP") == 0)
+        {
+            /* Open the old-style help */
+            TRACE("szHelpFile: %s\n", debugstr_w(szHelpFile));
+            WinHelpW(NULL, szHelpFile, HELP_FINDER, 0);
+        }
+        else
+        {
+            /* Open the new-style help */
+            FIXME("(%p, %p, %p): %s\n", pimeui, wParam, lParam, debugstr_w(szHelpFile));
+            ret = FALSE;
+        }
+    }
+
+    return ret;
+}
+
+/* Handles WM_IME_SYSTEM message of the default IME window. */
+/* Win: ImeSystemHandler */
 static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
 {
     LRESULT ret = 0;
@@ -571,7 +624,7 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
 
     switch (wParam)
     {
-        case 0x05:
+        case IMS_NOTIFYIMESHOW:
             if (User32GetImeShowStatus() == !lParam)
             {
                 hImeWnd = UserHMGetHandle(pimeui->spwnd);
@@ -579,7 +632,7 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
             }
             break;
 
-        case 0x06:
+        case IMS_UPDATEIMEUI:
             if (!hIMC)
                 break;
 
@@ -610,7 +663,7 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
             }
             break;
 
-        case 0x09:
+        case IMS_SETCANDFORM:
             pIC = IMM_FN(ImmLockIMC)(hIMC);
             if (!pIC)
                 break;
@@ -620,7 +673,7 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
             IMM_FN(ImmUnlockIMC)(hIMC);
             break;
 
-        case 0x0A:
+        case IMS_SETCOMPFONT:
             pIC = IMM_FN(ImmLockIMC)(hIMC);
             if (!pIC)
                 break;
@@ -629,7 +682,7 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
             IMM_FN(ImmUnlockIMC)(hIMC);
             break;
 
-        case 0x0B:
+        case IMS_SETCOMPFORM:
             pIC = IMM_FN(ImmLockIMC)(hIMC);
             if (!pIC)
                 break;
@@ -640,31 +693,30 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
             IMM_FN(ImmUnlockIMC)(hIMC);
             break;
 
-        case 0x0D:
+        case IMS_CONFIGURE:
             IMM_FN(ImmConfigureIMEW)((HKL)lParam, pimeui->hwndIMC, IME_CONFIG_GENERAL, NULL);
             break;
 
-        case 0x0F:
+        case IMS_SETOPENSTATUS:
             if (hIMC)
                 IMM_FN(ImmSetOpenStatus)(hIMC, (BOOL)lParam);
             break;
 
-        case 0x11:
+        case IMS_FREELAYOUT:
             ret = IMM_FN(ImmFreeLayout)((DWORD)lParam);
             break;
 
         case 0x13:
-            // TODO:
+            FIXME("\n");
             break;
 
-        case 0x14:
+        case IMS_GETCONVSTATUS:
             IMM_FN(ImmGetConversionStatus)(hIMC, &dwConversion, &dwSentence);
             ret = dwConversion;
             break;
 
-        case 0x15:
-            // TODO:
-            break;
+        case IMS_IMEHELP:
+            return User32DoImeHelp(pimeui, wParam, lParam);
 
         case IMS_IMEACTIVATE:
             User32SetImeActivenessOfWindow((HWND)lParam, TRUE);
@@ -683,18 +735,24 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
             break;
 
         case 0x1D:
-            // TODO:
+            FIXME("\n");
             break;
 
-        case 0x1E:
+        case IMS_GETCONTEXT:
             ret = (ULONG_PTR)IMM_FN(ImmGetContext)((HWND)lParam);
             break;
 
-        case 0x1F:
-        case 0x20:
+        case IMS_SENDNOTIFICATION:
+        case IMS_COMPLETECOMPSTR:
+        case IMS_SETLANGBAND:
+        case IMS_UNSETLANGBAND:
             ret = IMM_FN(ImmSystemHandler)(hIMC, wParam, lParam);
             break;
 
+        case IMS_LOADTHREADLAYOUT:
+            CtfLoadThreadLayout(pimeui);
+            break;
+
         default:
             break;
     }
@@ -702,7 +760,8 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
     return ret;
 }
 
-// Win: ImeSetContextHandler
+/* Handles WM_IME_SETCONTEXT message of the default IME window. */
+/* Win: ImeSetContextHandler */
 LRESULT ImeWnd_OnImeSetContext(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
 {
     LRESULT ret;
@@ -856,7 +915,8 @@ LRESULT ImeWnd_OnImeSetContext(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
     return ret;
 }
 
-// Win: ImeWndProcWorker(hwnd, msg, wParam, lParam, !unicode)
+/* The window procedure of the default IME window */
+/* Win: ImeWndProcWorker(hwnd, msg, wParam, lParam, !unicode) */
 LRESULT WINAPI
 ImeWndProc_common(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode) // ReactOS
 {