imm32: Destroy default IME windows in ImmDisableIME.

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-15 15:27:24 +02:00 committed by Alexandre Julliard
parent ea0c992fa5
commit 684d023faa
2 changed files with 97 additions and 7 deletions

View file

@ -992,18 +992,58 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
return FALSE;
}
static HWND imm_detach_default_window(IMMThreadData *thread_data)
{
HWND to_destroy;
imm_couninit_thread(thread_data, TRUE);
to_destroy = thread_data->hwndDefault;
thread_data->hwndDefault = NULL;
thread_data->windowRefs = 0;
return to_destroy;
}
/***********************************************************************
* ImmDisableIME (IMM32.@)
*/
BOOL WINAPI ImmDisableIME(DWORD idThread)
{
IMMThreadData *thread_data;
HWND to_destroy;
if (idThread == (DWORD)-1)
{
disable_ime = TRUE;
else {
IMMThreadData *thread_data = IMM_GetThreadData(NULL, idThread);
while (1)
{
to_destroy = 0;
EnterCriticalSection(&threaddata_cs);
LIST_FOR_EACH_ENTRY(thread_data, &ImmThreadDataList, IMMThreadData, entry)
{
if (thread_data->hwndDefault)
{
to_destroy = imm_detach_default_window(thread_data);
break;
}
}
LeaveCriticalSection(&threaddata_cs);
if (!to_destroy)
break;
DestroyWindow(to_destroy);
}
}
else
{
thread_data = IMM_GetThreadData(NULL, idThread);
if (!thread_data) return FALSE;
thread_data->disableIME = TRUE;
to_destroy = imm_detach_default_window(thread_data);
LeaveCriticalSection(&threaddata_cs);
if (to_destroy)
DestroyWindow(to_destroy);
}
return TRUE;
}
@ -1878,11 +1918,7 @@ void WINAPI __wine_unregister_window(HWND hwnd)
/* Destroy default IME window */
if (thread_data->windowRefs == 0)
{
imm_couninit_thread(thread_data, TRUE);
to_destroy = thread_data->hwndDefault;
thread_data->hwndDefault = NULL;
}
to_destroy = imm_detach_default_window(thread_data);
LeaveCriticalSection(&threaddata_cs);
if (to_destroy) DestroyWindow( to_destroy );

View file

@ -2241,6 +2241,57 @@ static void test_com_initialization(void)
test_apttype(-1);
}
static DWORD WINAPI disable_ime_thread(void *arg)
{
HWND h, def;
MSG msg;
BOOL r;
h = CreateWindowA("static", "static", 0, 0, 0, 0, 0, 0, 0, 0, 0);
ok(h != NULL, "CreateWindow failed\n");
def = ImmGetDefaultIMEWnd(h);
ok(def != NULL, "ImmGetDefaultIMEWnd returned NULL\n");
r = ImmDisableIME(arg ? GetCurrentThreadId() : 0);
ok(r, "ImmDisableIME failed\n");
if (arg)
{
def = ImmGetDefaultIMEWnd(h);
todo_wine ok(def != NULL, "ImmGetDefaultIMEWnd returned NULL\n");
while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
DispatchMessageA(&msg);
}
def = ImmGetDefaultIMEWnd(h);
ok(!def, "ImmGetDefaultIMEWnd returned %p\n", def);
return 0;
}
static void test_ImmDisableIME(void)
{
HANDLE thread;
HWND def;
BOOL r;
def = ImmGetDefaultIMEWnd(hwnd);
ok(def != NULL, "ImmGetDefaultIMEWnd(hwnd) returned NULL\n");
thread = CreateThread(NULL, 0, disable_ime_thread, 0, 0, NULL);
ok(thread != NULL, "CreateThread failed\n");
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
thread = CreateThread(NULL, 0, disable_ime_thread, (void*)1, 0, NULL);
ok(thread != NULL, "CreateThread failed\n");
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
r = ImmDisableIME(-1);
ok(r, "ImmDisableIME(-1) failed\n");
def = ImmGetDefaultIMEWnd(hwnd);
ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def);
}
START_TEST(imm32) {
if (!is_ime_enabled())
{
@ -2276,6 +2327,9 @@ START_TEST(imm32) {
if (pSendInput)
test_ime_processkey();
else win_skip("SendInput is not available\n");
/* there's no way of enabling IME - keep the test last */
test_ImmDisableIME();
}
cleanup();
}