https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e6fd41d07802715d99d62…
commit e6fd41d07802715d99d623a4e62f22e71fedc65b
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Oct 5 21:31:53 2021 +0900
Commit: GitHub <noreply(a)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.@)
*/