From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 35 ++++++++++++++++++++++++++--------- dlls/win32u/imm.c | 10 ++++++++++ include/ntuser.h | 1 + 3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index d29684f34a2..42a6a568c1a 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -87,8 +87,6 @@ struct imc
struct ime *ime; UINT lastVK; - - HWND ui_hwnd; /* IME UI window, on the default input context */ };
#define WINE_IMC_VALID_MAGIC 0x56434D49 @@ -623,12 +621,25 @@ static INPUTCONTEXT *ime_find_input_context( struct ime *ime, HIMC himc ) return &entry->context; }
+static BOOL CALLBACK enum_set_ui_window( HIMC himc, LPARAM lparam ) +{ + NtUserUpdateInputContext( himc, NtUserInputContextUIHwnd, lparam ); + return TRUE; +} + static void imc_release_ime( struct imc *imc, struct ime *ime ) { + HIMC default_himc = UlongToHandle( NtUserGetThreadInfo()->default_imc ); INPUTCONTEXT *ctx; + HWND hwnd; + + if (imc->handle != default_himc) NtUserUpdateInputContext( imc->handle, NtUserInputContextUIHwnd, 0 ); + else if ((hwnd = (HWND)NtUserQueryInputContext( default_himc, NtUserInputContextUIHwnd ))) + { + DestroyWindow( hwnd ); + ImmEnumInputContext( 0, enum_set_ui_window, 0 ); + }
- if (imc->ui_hwnd) DestroyWindow( imc->ui_hwnd ); - imc->ui_hwnd = NULL; ime->pImeSelect( imc->handle, FALSE );
if ((ctx = ime_find_input_context( ime, imc->handle ))) *ctx = imc->IMC; @@ -651,11 +662,14 @@ static struct ime *imc_select_ime( struct imc *imc ) WARN( "Failed to acquire IME for HKL %p\n", hkl ); else { + HIMC default_himc = UlongToHandle( NtUserGetThreadInfo()->default_imc ); + HWND hwnd = (HWND)NtUserQueryInputContext( default_himc, NtUserInputContextUIHwnd ); INPUTCONTEXT *ctx;
if ((ctx = ime_find_input_context( imc->ime, imc->handle ))) imc->IMC = *ctx; else ime_save_input_context( imc->ime, imc->handle, &imc->IMC );
+ NtUserUpdateInputContext( imc->handle, NtUserInputContextUIHwnd, (LPARAM)hwnd ); imc->ime->pImeSelect( imc->handle, TRUE ); }
@@ -1010,16 +1024,19 @@ static HWND get_ime_ui_window(void) { struct imc *imc = default_input_context(); struct ime *ime; + HWND hwnd;
if (!(ime = imc_select_ime( imc ))) return 0;
- if (!imc->ui_hwnd) + if (!(hwnd = (HWND)NtUserQueryInputContext( imc->handle, NtUserInputContextUIHwnd ))) { - imc->ui_hwnd = CreateWindowExW( WS_EX_TOOLWINDOW, ime->ui_class, NULL, WS_POPUP, 0, 0, 1, 1, - ImmGetDefaultIMEWnd( 0 ), 0, ime->module, 0 ); - SetWindowLongPtrW( imc->ui_hwnd, IMMGWL_IMC, (LONG_PTR)imc->handle ); + hwnd = CreateWindowExW( WS_EX_TOOLWINDOW, ime->ui_class, NULL, WS_POPUP, 0, 0, 1, 1, + ImmGetDefaultIMEWnd( 0 ), 0, ime->module, 0 ); + SetWindowLongPtrW( hwnd, IMMGWL_IMC, (LONG_PTR)imc->handle ); + ImmEnumInputContext( 0, enum_set_ui_window, (LPARAM)hwnd ); } - return imc->ui_hwnd; + + return hwnd; }
/*********************************************************************** diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index 7dee4912e27..7be44306dda 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -40,6 +40,7 @@ struct imc struct user_object obj; DWORD thread_id; UINT_PTR client_ptr; + HWND ui_hwnd; };
struct imm_thread_data @@ -80,6 +81,7 @@ HIMC WINAPI NtUserCreateInputContext( UINT_PTR client_ptr ) if (!(imc = malloc( sizeof(*imc) ))) return 0; imc->client_ptr = client_ptr; imc->thread_id = GetCurrentThreadId(); + imc->ui_hwnd = 0; if (!(handle = alloc_user_handle( &imc->obj, NTUSER_OBJ_IMC ))) { free( imc ); @@ -127,6 +129,10 @@ BOOL WINAPI NtUserUpdateInputContext( HIMC handle, UINT attr, UINT_PTR value ) imc->client_ptr = value; break;
+ case NtUserInputContextUIHwnd: + imc->ui_hwnd = (HWND)value; + break; + default: FIXME( "unknown attr %u\n", attr ); ret = FALSE; @@ -156,6 +162,10 @@ UINT_PTR WINAPI NtUserQueryInputContext( HIMC handle, UINT attr ) ret = imc->thread_id; break;
+ case NtUserInputContextUIHwnd: + ret = (UINT_PTR)imc->ui_hwnd; + break; + default: FIXME( "unknown attr %u\n", attr ); ret = 0; diff --git a/include/ntuser.h b/include/ntuser.h index 3d43eb476e4..7356c6096e9 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -453,6 +453,7 @@ struct draw_scroll_bar_params /* NtUserUpdateInputContext param, not compatible with Window */ enum input_context_attr { + NtUserInputContextUIHwnd = -1, NtUserInputContextClientPtr, NtUserInputContextThreadId, };