user32: Set IMM active context on focus change.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2021-10-16 21:21:13 +02:00 committed by Alexandre Julliard
parent a3c6e5c843
commit 374ad33904
4 changed files with 54 additions and 3 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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))))

View file

@ -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
{