From 25fcdc5c2bbb3e745764614d4942dc286848af7d Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 13 Aug 2022 07:08:18 +0900 Subject: [PATCH] [USER32][IMM32][INCLUDE] Empower WM_IME_SYSTEM handling (#4603) - 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 | 25 +++---- sdk/include/ddk/immdev.h | 16 +++++ win32ss/user/user32/misc/imm.c | 116 +++++++++++++++++++++++++-------- 3 files changed, 118 insertions(+), 39 deletions(-) diff --git a/dll/win32/imm32/keymsg.c b/dll/win32/imm32/keymsg.c index e2d41141063..8abd8a5c8ae 100644 --- a/dll/win32/imm32/keymsg.c +++ b/dll/win32/imm32/keymsg.c @@ -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; diff --git a/sdk/include/ddk/immdev.h b/sdk/include/ddk/immdev.h index 33146de3c95..a239dcda3ec 100644 --- a/sdk/include/ddk/immdev.h +++ b/sdk/include/ddk/immdev.h @@ -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)) diff --git a/win32ss/user/user32/misc/imm.c b/win32ss/user/user32/misc/imm.c index 4cfe094b066..2f1a1227b18 100644 --- a/win32ss/user/user32/misc/imm.c +++ b/win32ss/user/user32/misc/imm.c @@ -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 {