https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e6fd41d07802715d99d623...
commit e6fd41d07802715d99d623a4e62f22e71fedc65b Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Tue Oct 5 21:31:53 2021 +0900 Commit: GitHub noreply@github.com CommitDate: Tue Oct 5 21:31:53 2021 +0900
[IMM32] Implement ImmSystemHandler (#3998)
- Implement ImmSystemHandler function. - Add Imm32UnknownProcess1 and Imm32SendChange helper functions. CORE-11700 --- dll/win32/imm32/imm32.spec | 2 +- dll/win32/imm32/keymsg.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec index 1ee3a2c8cb0..09ca424fdc0 100644 --- a/dll/win32/imm32/imm32.spec +++ b/dll/win32/imm32/imm32.spec @@ -106,7 +106,7 @@ @ stdcall ImmSetStatusWindowPos(ptr ptr) @ stdcall ImmShowSoftKeyboard(ptr long) @ stdcall ImmSimulateHotKey(ptr long) -@ stdcall -stub ImmSystemHandler(ptr long long) +@ stdcall ImmSystemHandler(ptr ptr ptr) @ stdcall ImmTranslateMessage(ptr long ptr ptr) @ stdcall ImmUnlockClientImc(ptr) @ stdcall ImmUnlockIMC(ptr) diff --git a/dll/win32/imm32/keymsg.c b/dll/win32/imm32/keymsg.c index 6e35ae685f6..c8dc8670158 100644 --- a/dll/win32/imm32/keymsg.c +++ b/dll/win32/imm32/keymsg.c @@ -260,6 +260,95 @@ ImmIsUIMessageAW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAns return TRUE; }
+typedef struct IMM_UNKNOWN_PROCESS1 +{ + HWND hWnd; + BOOL fFlag; +} IMM_UNKNOWN_PROCESS1, *PIMM_UNKNOWN_PROCESS1; + +static DWORD WINAPI Imm32UnknownProcess1Proc(LPVOID arg) +{ + HWND hwndDefIME; + UINT uValue; + DWORD_PTR lResult; + PIMM_UNKNOWN_PROCESS1 pUnknown = arg; + + Sleep(3000); + hwndDefIME = ImmGetDefaultIMEWnd(pUnknown->hWnd); + if (hwndDefIME) + { + uValue = (pUnknown->fFlag ? 0x23 : 0x24); + SendMessageTimeoutW(hwndDefIME, WM_IME_SYSTEM, uValue, (LPARAM)pUnknown->hWnd, + SMTO_BLOCK | SMTO_ABORTIFHUNG, 5000, &lResult); + } + Imm32HeapFree(pUnknown); + return FALSE; +} + +LRESULT APIENTRY Imm32UnknownProcess1(HWND hWnd, BOOL fFlag) +{ + HANDLE hThread; + PWND pWnd = NULL; + PIMM_UNKNOWN_PROCESS1 pUnknown1; + DWORD_PTR lResult = 0; + + if (hWnd && g_psi) + pWnd = ValidateHwndNoErr(hWnd); + + if (!pWnd) + return 0; + + if (pWnd->state2 & WNDS2_WMCREATEMSGPROCESSED) + { + SendMessageTimeoutW(hWnd, 0x505, 0, fFlag, 3, 5000, &lResult); + return lResult; + } + + pUnknown1 = Imm32HeapAlloc(0, sizeof(IMM_UNKNOWN_PROCESS1)); + if (!pUnknown1) + return 0; + + pUnknown1->hWnd = hWnd; + pUnknown1->fFlag = fFlag; + + hThread = CreateThread(NULL, 0, Imm32UnknownProcess1Proc, pUnknown1, 0, NULL); + if (hThread) + CloseHandle(hThread); + return 0; +} + +static BOOL CALLBACK Imm32SendChangeProc(HIMC hIMC, LPARAM lParam) +{ + HWND hWnd; + LPINPUTCONTEXTDX pIC; + + pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); + if (!pIC) + return TRUE; + + hWnd = pIC->hWnd; + if (!IsWindow(hWnd)) + goto Quit; + + if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_OPEN) + SendMessageW(hWnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0); + if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_CONVERSION) + SendMessageW(hWnd, WM_IME_NOTIFY, IMN_SETCONVERSIONMODE, 0); + if (pIC->dwChange & (INPUTCONTEXTDX_CHANGE_OPEN | INPUTCONTEXTDX_CHANGE_CONVERSION)) + NtUserNotifyIMEStatus(hWnd, pIC->fOpen, pIC->fdwConversion); + if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_SENTENCE) + SendMessageW(hWnd, WM_IME_NOTIFY, IMN_SETSENTENCEMODE, 0); +Quit: + pIC->dwChange = 0; + ImmUnlockIMC(hIMC); // ??? Windows doesn't unlock here + return TRUE; +} + +BOOL APIENTRY Imm32SendChange(BOOL bProcess) +{ + return ImmEnumInputContext((bProcess ? -1 : 0), Imm32SendChangeProc, 0); +} + /*********************************************************************** * ImmIsUIMessageA (IMM32.@) */ @@ -425,6 +514,31 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID) return ret; }
+/*********************************************************************** + * ImmSystemHandler(IMM32.@) + */ +LRESULT WINAPI ImmSystemHandler(HIMC hIMC, WPARAM wParam, LPARAM lParam) +{ + TRACE("(%p, %p, %p)\n", hIMC, wParam, lParam); + + switch (wParam) + { + case 0x1f: + Imm32SendChange((BOOL)lParam); + return 0; + + case 0x20: + ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); + return 0; + + case 0x23: case 0x24: + return Imm32UnknownProcess1((HWND)lParam, (wParam == 0x23)); + + default: + return 0; + } +} + /*********************************************************************** * ImmGenerateMessage(IMM32.@) */