[IMM32] Rewrite ImmAssociateContextEx (#3961)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Thu, 16 Sep 2021 10:29:49 +0000 (19:29 +0900)
committerGitHub <noreply@github.com>
Thu, 16 Sep 2021 10:29:49 +0000 (19:29 +0900)
- Rewrite ImmAssociateContextEx function.
- Modify NtUserAssociateInputContext prototype.
CORE-11700

dll/win32/imm32/imm.c
sdk/include/psdk/imm.h
win32ss/include/ntuser.h
win32ss/user/ntuser/ntstubs.c

index 21832a5..6092b35 100644 (file)
@@ -254,48 +254,50 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
     return old;
 }
 
-/*
- * Helper function for ImmAssociateContextEx
- */
-static BOOL CALLBACK _ImmAssociateContextExEnumProc(HWND hwnd, LPARAM lParam)
-{
-    HIMC hImc = (HIMC)lParam;
-    ImmAssociateContext(hwnd,hImc);
-    return TRUE;
-}
-
 /***********************************************************************
  *              ImmAssociateContextEx (IMM32.@)
  */
 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
 {
-    TRACE("(%p, %p, 0x%x):\n", hWnd, hIMC, dwFlags);
+    HWND hwndFocus;
+    PWND pFocusWnd;
+    HIMC hOldIMC = NULL;
+    DWORD dwValue;
 
-    if (!hWnd)
+    TRACE("(%p, %p, 0x%lX)\n", hWnd, hIMC, dwFlags);
+
+    if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_IMM32))
         return FALSE;
 
-    switch (dwFlags)
-    {
-    case 0:
-        ImmAssociateContext(hWnd,hIMC);
-        return TRUE;
-    case IACE_DEFAULT:
-    {
-        HIMC defaultContext = get_default_context( hWnd );
-        if (!defaultContext) return FALSE;
-        ImmAssociateContext(hWnd,defaultContext);
-        return TRUE;
-    }
-    case IACE_IGNORENOCONTEXT:
-        if (GetPropW(hWnd,szwWineIMCProperty))
-            ImmAssociateContext(hWnd,hIMC);
-        return TRUE;
-    case IACE_CHILDREN:
-        EnumChildWindows(hWnd,_ImmAssociateContextExEnumProc,(LPARAM)hIMC);
-        return TRUE;
-    default:
-        FIXME("Unknown dwFlags 0x%x\n",dwFlags);
+    if (hIMC && !(dwFlags & IACE_DEFAULT) && Imm32IsCrossThreadAccess(hIMC))
         return FALSE;
+
+    hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
+    pFocusWnd = ValidateHwndNoErr(hwndFocus);
+    if (pFocusWnd)
+        hOldIMC = pFocusWnd->hImc;
+
+    dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
+    switch (dwValue)
+    {
+        case 0:
+            return TRUE;
+
+        case 1:
+            pFocusWnd = ValidateHwndNoErr(hwndFocus);
+            if (pFocusWnd)
+            {
+                hIMC = pFocusWnd->hImc;
+                if (hIMC != hOldIMC)
+                {
+                    ImmSetActiveContext(hwndFocus, hOldIMC, FALSE);
+                    ImmSetActiveContext(hwndFocus, hIMC, TRUE);
+                }
+            }
+            return TRUE;
+
+        default:
+            return FALSE;
     }
 }
 
index f28b8e6..6232ee1 100644 (file)
@@ -627,6 +627,7 @@ BOOL WINAPI ImmConfigureIMEW(_In_ HKL, _In_ HWND, _In_ DWORD, _In_ LPVOID);
 #define ImmConfigureIME WINELIB_NAME_AW(ImmConfigureIME)
 
 HIMC WINAPI ImmCreateContext(void);
+BOOL WINAPI ImmSetActiveContext(HWND hwnd, HIMC hIMC, BOOL fFlag);
 BOOL WINAPI ImmDestroyContext(_In_ HIMC hIMC);
 BOOL WINAPI ImmDisableIME(_In_ DWORD idThread);
 BOOL WINAPI ImmEnumInputContext(_In_ DWORD, _In_ IMCENUMPROC, _In_ LPARAM);
index 6363923..6d463dd 100644 (file)
@@ -1317,10 +1317,7 @@ C_ASSERT(sizeof(CLIENTIMC) == 0x34);
 
 DWORD
 NTAPI
-NtUserAssociateInputContext(
-    DWORD dwUnknown1,
-    DWORD dwUnknown2,
-    DWORD dwUnknown3);
+NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags);
 
 NTSTATUS
 NTAPI
index 4de9ea3..6a1b3c4 100644 (file)
@@ -11,10 +11,7 @@ DBG_DEFAULT_CHANNEL(UserMisc);
 
 DWORD
 APIENTRY
-NtUserAssociateInputContext(
-    DWORD dwUnknown1,
-    DWORD dwUnknown2,
-    DWORD dwUnknown3)
+NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags)
 {
     STUB
     return 0;