Piotr Caban : user32: Set IMM active context on focus change.

Alexandre Julliard julliard at winehq.org
Mon Oct 18 16:16:30 CDT 2021


Module: wine
Branch: master
Commit: 374ad339048e73269d9590ed3438e959179fee09
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=374ad339048e73269d9590ed3438e959179fee09

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Sat Oct 16 21:21:13 2021 +0200

user32: Set IMM active context on focus change.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/imm32/tests/imm32.c   | 11 +++++++++--
 dlls/user32/focus.c        | 13 ++++++++++++-
 dlls/user32/misc.c         | 30 ++++++++++++++++++++++++++++++
 dlls/user32/user_private.h |  3 +++
 4 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c
index 9e0e59d384d..1d2ae6dd0a1 100644
--- a/dlls/imm32/tests/imm32.c
+++ b/dlls/imm32/tests/imm32.c
@@ -720,12 +720,12 @@ static void test_ImmAssociateContextEx(void)
         ok(focus != NULL, "CreateWindow failed\n");
         SET_EXPECT(WM_IME_SETCONTEXT_DEACTIVATE);
         SetFocus(focus);
-        todo_wine CHECK_CALLED(WM_IME_SETCONTEXT_DEACTIVATE);
+        CHECK_CALLED(WM_IME_SETCONTEXT_DEACTIVATE);
         rc = pImmAssociateContextEx(hwnd, imc, 0);
         ok(rc, "ImmAssociateContextEx failed\n");
         SET_EXPECT(WM_IME_SETCONTEXT_ACTIVATE);
         DestroyWindow(focus);
-        todo_wine CHECK_CALLED(WM_IME_SETCONTEXT_ACTIVATE);
+        CHECK_CALLED(WM_IME_SETCONTEXT_ACTIVATE);
         SetFocus(hwnd);
 
         rc = pImmAssociateContextEx(hwnd, NULL, IACE_DEFAULT);
@@ -2239,6 +2239,13 @@ static void test_com_initialization(void)
     test_apttype(APTTYPE_MTA);
     DestroyWindow(wnd);
     test_apttype(-1);
+
+    wnd = CreateWindowA("static", "static", WS_POPUP, 0, 0, 100, 100, 0, 0, 0, 0);
+    ok(wnd != NULL, "CreateWindow failed\n");
+    ShowWindow(wnd, SW_SHOW);
+    test_apttype(APTTYPE_MAINSTA);
+    DestroyWindow(wnd);
+    test_apttype(-1);
 }
 
 static DWORD WINAPI disable_ime_thread(void *arg)
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c
index 4c18238a98b..34cc3880cc9 100644
--- a/dlls/user32/focus.c
+++ b/dlls/user32/focus.c
@@ -27,6 +27,7 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "win.h"
+#include "imm.h"
 #include "user_private.h"
 #include "wine/server.h"
 #include "wine/debug.h"
@@ -41,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
  */
 static HWND set_focus_window( HWND hwnd )
 {
-    HWND previous = 0;
+    HWND previous = 0, ime_default;
     BOOL ret;
 
     SERVER_START_REQ( set_focus_window )
@@ -57,11 +58,21 @@ static HWND set_focus_window( HWND hwnd )
     if (previous)
     {
         SendMessageW( previous, WM_KILLFOCUS, (WPARAM)hwnd, 0 );
+
+        ime_default = ImmGetDefaultIMEWnd( previous );
+        if (ime_default)
+            SendMessageW( ime_default, WM_IME_INTERNAL, IME_INTERNAL_DEACTIVATE, (LPARAM)previous );
+
         if (hwnd != GetFocus()) return previous;  /* changed by the message */
     }
     if (IsWindow(hwnd))
     {
         USER_Driver->pSetFocus(hwnd);
+
+        ime_default = ImmGetDefaultIMEWnd( hwnd );
+        if (ime_default)
+            SendMessageW( ime_default, WM_IME_INTERNAL, IME_INTERNAL_ACTIVATE, (LPARAM)hwnd );
+
         SendMessageW( hwnd, WM_SETFOCUS, (WPARAM)previous, 0 );
     }
     return previous;
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c
index e12a1af5571..9051e30f0f8 100644
--- a/dlls/user32/misc.c
+++ b/dlls/user32/misc.c
@@ -28,12 +28,15 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "controls.h"
+#include "imm.h"
 #include "user_private.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(win);
 
+BOOL WINAPI ImmSetActiveContext(HWND, HIMC, BOOL);
+
 #define IMM_INIT_MAGIC 0x19650412
 static HWND (WINAPI *imm_get_ui_window)(HKL);
 BOOL (WINAPI *imm_register_window)(HWND) = NULL;
@@ -570,6 +573,27 @@ static BOOL is_ime_ui_msg( UINT msg )
     }
 }
 
+static LRESULT ime_internal_msg( WPARAM wParam, LPARAM lParam)
+{
+    HWND hwnd = (HWND)lParam;
+    HIMC himc;
+
+    switch(wParam)
+    {
+    case IME_INTERNAL_ACTIVATE:
+    case IME_INTERNAL_DEACTIVATE:
+        himc = ImmGetContext(hwnd);
+        ImmSetActiveContext(hwnd, himc, wParam == IME_INTERNAL_ACTIVATE);
+        ImmReleaseContext(hwnd, himc);
+        break;
+    default:
+        FIXME("wParam = %lx\n", wParam);
+        break;
+    }
+
+    return 0;
+}
+
 LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
 {
     HWND uiwnd;
@@ -577,6 +601,9 @@ LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
     if (msg==WM_CREATE)
         return TRUE;
 
+    if (msg==WM_IME_INTERNAL)
+        return ime_internal_msg(wParam, lParam);
+
     if (imm_get_ui_window && is_ime_ui_msg(msg))
     {
         if ((uiwnd = imm_get_ui_window(GetKeyboardLayout(0))))
@@ -594,6 +621,9 @@ LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
     if (msg==WM_CREATE)
         return TRUE;
 
+    if (msg==WM_IME_INTERNAL)
+        return ime_internal_msg(wParam, lParam);
+
     if (imm_get_ui_window && is_ime_ui_msg(msg))
     {
         if ((uiwnd = imm_get_ui_window(GetKeyboardLayout(0))))
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index a30b9ce8734..2b0a09d4931 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -208,6 +208,9 @@ C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo)
 extern INT global_key_state_counter DECLSPEC_HIDDEN;
 extern BOOL (WINAPI *imm_register_window)(HWND) DECLSPEC_HIDDEN;
 extern void (WINAPI *imm_unregister_window)(HWND) DECLSPEC_HIDDEN;
+#define WM_IME_INTERNAL 0x287
+#define IME_INTERNAL_ACTIVATE 0x17
+#define IME_INTERNAL_DEACTIVATE 0x18
 
 struct user_key_state_info
 {




More information about the wine-cvs mailing list