From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 738 +++++++++++++++++++-------------------- 1 file changed, 369 insertions(+), 369 deletions(-)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 093b79ff86b..d06ad1fae3d 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -263,6 +263,299 @@ static void process_messages(void) } }
+#define ime_trace( msg, ... ) if (winetest_debug > 1) trace( "%04lx:%s " msg, GetCurrentThreadId(), __func__, ## __VA_ARGS__ ) + +static BOOL ImeSelect_init_status; +static BOOL todo_ImeInquire; +DEFINE_EXPECT( ImeInquire ); +static BOOL todo_ImeDestroy; +DEFINE_EXPECT( ImeDestroy ); +DEFINE_EXPECT( ImeEscape ); +DEFINE_EXPECT( ImeEnumRegisterWord ); +DEFINE_EXPECT( ImeRegisterWord ); +DEFINE_EXPECT( ImeGetRegisterWordStyle ); +DEFINE_EXPECT( ImeUnregisterWord ); +static BOOL todo_ImeSetCompositionString; +DEFINE_EXPECT( ImeSetCompositionString ); +static BOOL todo_IME_DLL_PROCESS_ATTACH; +DEFINE_EXPECT( IME_DLL_PROCESS_ATTACH ); +static BOOL todo_IME_DLL_PROCESS_DETACH; +DEFINE_EXPECT( IME_DLL_PROCESS_DETACH ); + +static IMEINFO ime_info; +static UINT ime_count; +static WCHAR ime_path[MAX_PATH]; +static HIMC default_himc; +static HKL default_hkl, wineime_hkl; +static HKL expect_ime = (HKL)(int)0xe020047f; + +enum ime_function +{ + IME_SELECT = 1, + IME_NOTIFY, + IME_PROCESS_KEY, + IME_SET_ACTIVE_CONTEXT, + MSG_IME_UI, + MSG_TEST_WIN, +}; + +struct ime_call +{ + HKL hkl; + HIMC himc; + enum ime_function func; + + union + { + int select; + struct + { + int action; + int index; + int value; + } notify; + struct + { + WORD vkey; + LPARAM lparam; + } process_key; + struct + { + int flag; + } set_active_context; + struct + { + UINT msg; + WPARAM wparam; + LPARAM lparam; + } message; + }; + + BOOL todo; + BOOL broken; + BOOL flaky_himc; +}; + +struct ime_call empty_sequence[] = {{0}}; +static struct ime_call ime_calls[1024]; +static ULONG ime_call_count; + +#define ok_call( a, b ) ok_call_( __FILE__, __LINE__, a, b ) +static int ok_call_( const char *file, int line, const struct ime_call *expected, const struct ime_call *received ) +{ + int ret; + + if ((ret = expected->func - received->func)) goto done; + /* Wine doesn't allocate HIMC in a deterministic order, ignore them when they are enumerated */ + if (expected->flaky_himc && (ret = !!(UINT_PTR)expected->himc - !!(UINT_PTR)received->himc)) goto done; + if (!expected->flaky_himc && (ret = (UINT_PTR)expected->himc - (UINT_PTR)received->himc)) goto done; + if ((ret = (UINT)(UINT_PTR)expected->hkl - (UINT)(UINT_PTR)received->hkl)) goto done; + switch (expected->func) + { + case IME_SELECT: + if ((ret = expected->select - received->select)) goto done; + break; + case IME_NOTIFY: + if ((ret = expected->notify.action - received->notify.action)) goto done; + if ((ret = expected->notify.index - received->notify.index)) goto done; + if ((ret = expected->notify.value - received->notify.value)) goto done; + break; + case IME_PROCESS_KEY: + if ((ret = expected->process_key.vkey - received->process_key.vkey)) goto done; + if ((ret = expected->process_key.lparam - received->process_key.lparam)) goto done; + break; + case IME_SET_ACTIVE_CONTEXT: + if ((ret = expected->set_active_context.flag - received->set_active_context.flag)) goto done; + break; + case MSG_IME_UI: + case MSG_TEST_WIN: + if ((ret = expected->message.msg - received->message.msg)) goto done; + if ((ret = (expected->message.wparam - received->message.wparam))) goto done; + if ((ret = (expected->message.lparam - received->message.lparam))) goto done; + break; + } + +done: + if (ret && broken( expected->broken )) return ret; + + switch (received->func) + { + case IME_SELECT: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got hkl %p, himc %p, IME_SELECT select %u\n", received->hkl, received->himc, received->select ); + return ret; + case IME_NOTIFY: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got hkl %p, himc %p, IME_NOTIFY action %#x, index %#x, value %#x\n", + received->hkl, received->himc, received->notify.action, received->notify.index, + received->notify.value ); + return ret; + case IME_PROCESS_KEY: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got hkl %p, himc %p, IME_PROCESS_KEY vkey %#x, lparam %#Ix\n", + received->hkl, received->himc, received->process_key.vkey, received->process_key.lparam ); + return ret; + case IME_SET_ACTIVE_CONTEXT: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got hkl %p, himc %p, IME_SET_ACTIVE_CONTEXT flag %u\n", received->hkl, received->himc, + received->set_active_context.flag ); + return ret; + case MSG_IME_UI: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got hkl %p, himc %p, MSG_IME_UI msg %#x, wparam %#Ix, lparam %#Ix\n", received->hkl, + received->himc, received->message.msg, received->message.wparam, received->message.lparam ); + return ret; + case MSG_TEST_WIN: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got hkl %p, himc %p, MSG_TEST_WIN msg %#x, wparam %#Ix, lparam %#Ix\n", received->hkl, + received->himc, received->message.msg, received->message.wparam, received->message.lparam ); + return ret; + } + + switch (expected->func) + { + case IME_SELECT: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "hkl %p, himc %p, IME_SELECT select %u\n", expected->hkl, expected->himc, expected->select ); + break; + case IME_NOTIFY: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "hkl %p, himc %p, IME_NOTIFY action %#x, index %#x, value %#x\n", + expected->hkl, expected->himc, expected->notify.action, expected->notify.index, + expected->notify.value ); + break; + case IME_PROCESS_KEY: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "hkl %p, himc %p, IME_PROCESS_KEY vkey %#x, lparam %#Ix\n", + expected->hkl, expected->himc, expected->process_key.vkey, expected->process_key.lparam ); + break; + case IME_SET_ACTIVE_CONTEXT: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "hkl %p, himc %p, IME_SET_ACTIVE_CONTEXT flag %u\n", expected->hkl, expected->himc, + expected->set_active_context.flag ); + break; + case MSG_IME_UI: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "hkl %p, himc %p, MSG_IME_UI msg %#x, wparam %#Ix, lparam %#Ix\n", expected->hkl, + expected->himc, expected->message.msg, expected->message.wparam, expected->message.lparam ); + break; + case MSG_TEST_WIN: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "hkl %p, himc %p, MSG_TEST_WIN msg %#x, wparam %#Ix, lparam %#Ix\n", expected->hkl, + expected->himc, expected->message.msg, expected->message.wparam, expected->message.lparam ); + break; + } + + return 0; +} + +#define ok_seq( a ) ok_seq_( __FILE__, __LINE__, a, #a ) +static void ok_seq_( const char *file, int line, const struct ime_call *expected, const char *context ) +{ + const struct ime_call *received = ime_calls; + UINT i = 0, ret; + + while (expected->func || received->func) + { + winetest_push_context( "%u%s%s", i++, !expected->func ? " (spurious)" : "", + !received->func ? " (missing)" : "" ); + ret = ok_call_( file, line, expected, received ); + if (ret && expected->todo && expected->func && + !strcmp( winetest_platform, "wine" )) + expected++; + else if (ret && broken(expected->broken)) + expected++; + else + { + if (expected->func) expected++; + if (received->func) received++; + } + winetest_pop_context(); + } + + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; +} + +static BOOL check_WM_SHOWWINDOW; + +static BOOL ignore_message( UINT msg ) +{ + switch (msg) + { + case WM_IME_STARTCOMPOSITION: + case WM_IME_ENDCOMPOSITION: + case WM_IME_COMPOSITION: + case WM_IME_SETCONTEXT: + case WM_IME_NOTIFY: + case WM_IME_CONTROL: + case WM_IME_COMPOSITIONFULL: + case WM_IME_SELECT: + case WM_IME_CHAR: + case 0x287: + case WM_IME_REQUEST: + case WM_IME_KEYDOWN: + case WM_IME_KEYUP: + return FALSE; + case WM_SHOWWINDOW: + return !check_WM_SHOWWINDOW; + default: + return TRUE; + } +} + +static LRESULT CALLBACK ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + struct ime_call call = + { + .hkl = GetKeyboardLayout( 0 ), .himc = (HIMC)GetWindowLongPtrW( hwnd, IMMGWL_IMC ), + .func = MSG_IME_UI, .message = {.msg = msg, .wparam = wparam, .lparam = lparam} + }; + LONG_PTR ptr; + + ime_trace( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + + if (ignore_message( msg )) return DefWindowProcW( hwnd, msg, wparam, lparam ); + + ptr = GetWindowLongPtrW( hwnd, IMMGWL_PRIVATE ); + ok( !ptr, "got IMMGWL_PRIVATE %#Ix\n", ptr ); + + ime_calls[ime_call_count++] = call; + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static LRESULT CALLBACK test_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + struct ime_call call = + { + .hkl = GetKeyboardLayout( 0 ), .himc = ImmGetContext( hwnd ), + .func = MSG_TEST_WIN, .message = {.msg = msg, .wparam = wparam, .lparam = lparam} + }; + + ime_trace( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + + if (ignore_message( msg )) return DefWindowProcW( hwnd, msg, wparam, lparam ); + + ime_calls[ime_call_count++] = call; + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static WNDCLASSEXW ime_ui_class = +{ + .cbSize = sizeof(WNDCLASSEXW), + .style = CS_IME, + .lpfnWndProc = ime_ui_window_proc, + .cbWndExtra = 2 * sizeof(LONG_PTR), + .lpszClassName = L"WineTestIME", +}; + +static WNDCLASSEXW test_class = +{ + .cbSize = sizeof(WNDCLASSEXW), + .lpfnWndProc = test_window_proc, + .lpszClassName = L"WineTest", +}; + /* * msgspy - record and analyse message traces sent to a certain window */ @@ -2595,397 +2888,104 @@ static void test_com_initialization(void) test_apttype(hr == S_OK ? APTTYPE_MTA : APTTYPE_MAINSTA); DestroyWindow(wnd); 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 DWORD WINAPI check_not_disabled_ime_thread(void *arg) -{ - HWND def, hwnd; - - WaitForSingleObject(arg, INFINITE); - hwnd = CreateWindowA("static", "static", 0, 0, 0, 0, 0, 0, 0, 0, 0); - ok(hwnd != NULL, "CreateWindow failed\n"); - def = ImmGetDefaultIMEWnd(hwnd); - ok(def != NULL, "ImmGetDefaultIMEWnd returned %p\n", def); - return 0; -} - -static DWORD WINAPI disable_ime_process(void *arg) -{ - BOOL r = ImmDisableIME(-1); - ok(r, "ImmDisableIME failed\n"); - return 0; -} - -static void test_ImmDisableIME(void) -{ - HANDLE thread, event; - DWORD tid; - HWND def, def2; - BOOL r; - - def = ImmGetDefaultIMEWnd(hwnd); - ok(def != NULL, "ImmGetDefaultIMEWnd(hwnd) returned NULL\n"); - - event = CreateEventW(NULL, TRUE, FALSE, FALSE); - thread = CreateThread(NULL, 0, check_not_disabled_ime_thread, event, 0, &tid); - ok(thread != NULL, "CreateThread failed\n"); - r = ImmDisableIME(tid); - ok(!r, "ImmDisableIME(tid) succeeded\n"); - SetEvent(event); - WaitForSingleObject(thread, INFINITE); - CloseHandle(thread); - CloseHandle(event); - - 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); - - msg_spy_pump_msg_queue(); - thread = CreateThread(NULL, 0, disable_ime_process, 0, 0, NULL); - ok(thread != NULL, "CreateThread failed\n"); - WaitForSingleObject(thread, INFINITE); - CloseHandle(thread); - - ok(IsWindow(def), "not a window\n"); - def2 = ImmGetDefaultIMEWnd(hwnd); - ok(def2 == def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def2); - ok(IsWindow(def), "not a window\n"); - msg_spy_pump_msg_queue(); - ok(!IsWindow(def), "window is still valid\n"); - def = ImmGetDefaultIMEWnd(hwnd); - ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def); - - r = ImmDisableIME(-1); - ok(r, "ImmDisableIME(-1) failed\n"); - def = ImmGetDefaultIMEWnd(hwnd); - ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def); -} - -#define ime_trace( msg, ... ) if (winetest_debug > 1) trace( "%04lx:%s " msg, GetCurrentThreadId(), __func__, ## __VA_ARGS__ ) - -static BOOL ImeSelect_init_status; -static BOOL todo_ImeInquire; -DEFINE_EXPECT( ImeInquire ); -static BOOL todo_ImeDestroy; -DEFINE_EXPECT( ImeDestroy ); -DEFINE_EXPECT( ImeEscape ); -DEFINE_EXPECT( ImeEnumRegisterWord ); -DEFINE_EXPECT( ImeRegisterWord ); -DEFINE_EXPECT( ImeGetRegisterWordStyle ); -DEFINE_EXPECT( ImeUnregisterWord ); -static BOOL todo_ImeSetCompositionString; -DEFINE_EXPECT( ImeSetCompositionString ); -static BOOL todo_IME_DLL_PROCESS_ATTACH; -DEFINE_EXPECT( IME_DLL_PROCESS_ATTACH ); -static BOOL todo_IME_DLL_PROCESS_DETACH; -DEFINE_EXPECT( IME_DLL_PROCESS_DETACH ); - -static IMEINFO ime_info; -static UINT ime_count; -static WCHAR ime_path[MAX_PATH]; -static HIMC default_himc; -static HKL default_hkl, wineime_hkl; -static HKL expect_ime = (HKL)(int)0xe020047f; - -enum ime_function -{ - IME_SELECT = 1, - IME_NOTIFY, - IME_PROCESS_KEY, - IME_SET_ACTIVE_CONTEXT, - MSG_IME_UI, - MSG_TEST_WIN, -}; - -struct ime_call -{ - HKL hkl; - HIMC himc; - enum ime_function func; - - union - { - int select; - struct - { - int action; - int index; - int value; - } notify; - struct - { - WORD vkey; - LPARAM key_data; - } process_key; - struct - { - int flag; - } set_active_context; - struct - { - UINT msg; - WPARAM wparam; - LPARAM lparam; - } message; - }; - - BOOL todo; - BOOL broken; - BOOL flaky_himc; -}; - -struct ime_call empty_sequence[] = {{0}}; -static struct ime_call ime_calls[1024]; -static ULONG ime_call_count; +}
-#define ok_call( a, b ) ok_call_( __FILE__, __LINE__, a, b ) -static int ok_call_( const char *file, int line, const struct ime_call *expected, const struct ime_call *received ) +static DWORD WINAPI disable_ime_thread(void *arg) { - int ret; - - if ((ret = expected->func - received->func)) goto done; - /* Wine doesn't allocate HIMC in a deterministic order, ignore them when they are enumerated */ - if (expected->flaky_himc && (ret = !!(UINT_PTR)expected->himc - !!(UINT_PTR)received->himc)) goto done; - if (!expected->flaky_himc && (ret = (UINT_PTR)expected->himc - (UINT_PTR)received->himc)) goto done; - if ((ret = (UINT)(UINT_PTR)expected->hkl - (UINT)(UINT_PTR)received->hkl)) goto done; - switch (expected->func) - { - case IME_SELECT: - if ((ret = expected->select - received->select)) goto done; - break; - case IME_NOTIFY: - if ((ret = expected->notify.action - received->notify.action)) goto done; - if ((ret = expected->notify.index - received->notify.index)) goto done; - if ((ret = expected->notify.value - received->notify.value)) goto done; - break; - case IME_PROCESS_KEY: - if ((ret = expected->process_key.vkey - received->process_key.vkey)) goto done; - if ((ret = expected->process_key.key_data - received->process_key.key_data)) goto done; - break; - case IME_SET_ACTIVE_CONTEXT: - if ((ret = expected->set_active_context.flag - received->set_active_context.flag)) goto done; - break; - case MSG_IME_UI: - case MSG_TEST_WIN: - if ((ret = expected->message.msg - received->message.msg)) goto done; - if ((ret = (expected->message.wparam - received->message.wparam))) goto done; - if ((ret = (expected->message.lparam - received->message.lparam))) goto done; - break; - } + HWND h, def; + MSG msg; + BOOL r;
-done: - if (ret && broken( expected->broken )) return ret; + 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");
- switch (received->func) - { - case IME_SELECT: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "got hkl %p, himc %p, IME_SELECT select %u\n", received->hkl, received->himc, received->select ); - return ret; - case IME_NOTIFY: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "got hkl %p, himc %p, IME_NOTIFY action %#x, index %#x, value %#x\n", - received->hkl, received->himc, received->notify.action, received->notify.index, - received->notify.value ); - return ret; - case IME_PROCESS_KEY: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "got hkl %p, himc %p, IME_PROCESS_KEY vkey %#x, key_data %#Ix\n", - received->hkl, received->himc, received->process_key.vkey, received->process_key.key_data ); - return ret; - case IME_SET_ACTIVE_CONTEXT: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "got hkl %p, himc %p, IME_SET_ACTIVE_CONTEXT flag %u\n", received->hkl, received->himc, - received->set_active_context.flag ); - return ret; - case MSG_IME_UI: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "got hkl %p, himc %p, MSG_IME_UI msg %#x, wparam %#Ix, lparam %#Ix\n", received->hkl, - received->himc, received->message.msg, received->message.wparam, received->message.lparam ); - return ret; - case MSG_TEST_WIN: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "got hkl %p, himc %p, MSG_TEST_WIN msg %#x, wparam %#Ix, lparam %#Ix\n", received->hkl, - received->himc, received->message.msg, received->message.wparam, received->message.lparam ); - return ret; - } + r = ImmDisableIME(arg ? GetCurrentThreadId() : 0); + ok(r, "ImmDisableIME failed\n");
- switch (expected->func) + if (arg) { - case IME_SELECT: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "hkl %p, himc %p, IME_SELECT select %u\n", expected->hkl, expected->himc, expected->select ); - break; - case IME_NOTIFY: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "hkl %p, himc %p, IME_NOTIFY action %#x, index %#x, value %#x\n", - expected->hkl, expected->himc, expected->notify.action, expected->notify.index, - expected->notify.value ); - break; - case IME_PROCESS_KEY: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "hkl %p, himc %p, IME_PROCESS_KEY vkey %#x, key_data %#Ix\n", - expected->hkl, expected->himc, expected->process_key.vkey, expected->process_key.key_data ); - break; - case IME_SET_ACTIVE_CONTEXT: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "hkl %p, himc %p, IME_SET_ACTIVE_CONTEXT flag %u\n", expected->hkl, expected->himc, - expected->set_active_context.flag ); - break; - case MSG_IME_UI: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "hkl %p, himc %p, MSG_IME_UI msg %#x, wparam %#Ix, lparam %#Ix\n", expected->hkl, - expected->himc, expected->message.msg, expected->message.wparam, expected->message.lparam ); - break; - case MSG_TEST_WIN: - todo_wine_if( expected->todo ) - ok_(file, line)( !ret, "hkl %p, himc %p, MSG_TEST_WIN msg %#x, wparam %#Ix, lparam %#Ix\n", expected->hkl, - expected->himc, expected->message.msg, expected->message.wparam, expected->message.lparam ); - break; + 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; }
-#define ok_seq( a ) ok_seq_( __FILE__, __LINE__, a, #a ) -static void ok_seq_( const char *file, int line, const struct ime_call *expected, const char *context ) +static DWORD WINAPI check_not_disabled_ime_thread(void *arg) { - const struct ime_call *received = ime_calls; - UINT i = 0, ret; - - while (expected->func || received->func) - { - winetest_push_context( "%u%s%s", i++, !expected->func ? " (spurious)" : "", - !received->func ? " (missing)" : "" ); - ret = ok_call_( file, line, expected, received ); - if (ret && expected->todo && expected->func && - !strcmp( winetest_platform, "wine" )) - expected++; - else if (ret && broken(expected->broken)) - expected++; - else - { - if (expected->func) expected++; - if (received->func) received++; - } - winetest_pop_context(); - } + HWND def, hwnd;
- memset( ime_calls, 0, sizeof(ime_calls) ); - ime_call_count = 0; + WaitForSingleObject(arg, INFINITE); + hwnd = CreateWindowA("static", "static", 0, 0, 0, 0, 0, 0, 0, 0, 0); + ok(hwnd != NULL, "CreateWindow failed\n"); + def = ImmGetDefaultIMEWnd(hwnd); + ok(def != NULL, "ImmGetDefaultIMEWnd returned %p\n", def); + return 0; }
-static BOOL check_WM_SHOWWINDOW; - -static BOOL ignore_message( UINT msg ) +static DWORD WINAPI disable_ime_process(void *arg) { - switch (msg) - { - case WM_IME_STARTCOMPOSITION: - case WM_IME_ENDCOMPOSITION: - case WM_IME_COMPOSITION: - case WM_IME_SETCONTEXT: - case WM_IME_NOTIFY: - case WM_IME_CONTROL: - case WM_IME_COMPOSITIONFULL: - case WM_IME_SELECT: - case WM_IME_CHAR: - case 0x287: - case WM_IME_REQUEST: - case WM_IME_KEYDOWN: - case WM_IME_KEYUP: - return FALSE; - case WM_SHOWWINDOW: - return !check_WM_SHOWWINDOW; - default: - return TRUE; - } + BOOL r = ImmDisableIME(-1); + ok(r, "ImmDisableIME failed\n"); + return 0; }
-static LRESULT CALLBACK ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +static void test_ImmDisableIME(void) { - struct ime_call call = - { - .hkl = GetKeyboardLayout( 0 ), .himc = (HIMC)GetWindowLongPtrW( hwnd, IMMGWL_IMC ), - .func = MSG_IME_UI, .message = {.msg = msg, .wparam = wparam, .lparam = lparam} - }; - LONG_PTR ptr; - - ime_trace( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + HANDLE thread, event; + DWORD tid; + HWND def, def2; + BOOL r;
- if (ignore_message( msg )) return DefWindowProcW( hwnd, msg, wparam, lparam ); + def = ImmGetDefaultIMEWnd(hwnd); + ok(def != NULL, "ImmGetDefaultIMEWnd(hwnd) returned NULL\n");
- ptr = GetWindowLongPtrW( hwnd, IMMGWL_PRIVATE ); - ok( !ptr, "got IMMGWL_PRIVATE %#Ix\n", ptr ); + event = CreateEventW(NULL, TRUE, FALSE, FALSE); + thread = CreateThread(NULL, 0, check_not_disabled_ime_thread, event, 0, &tid); + ok(thread != NULL, "CreateThread failed\n"); + r = ImmDisableIME(tid); + ok(!r, "ImmDisableIME(tid) succeeded\n"); + SetEvent(event); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + CloseHandle(event);
- ime_calls[ime_call_count++] = call; - return DefWindowProcW( hwnd, msg, wparam, lparam ); -} + thread = CreateThread(NULL, 0, disable_ime_thread, 0, 0, NULL); + ok(thread != NULL, "CreateThread failed\n"); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread);
-static LRESULT CALLBACK test_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) -{ - struct ime_call call = - { - .hkl = GetKeyboardLayout( 0 ), .himc = ImmGetContext( hwnd ), - .func = MSG_TEST_WIN, .message = {.msg = msg, .wparam = wparam, .lparam = lparam} - }; + thread = CreateThread(NULL, 0, disable_ime_thread, (void*)1, 0, NULL); + ok(thread != NULL, "CreateThread failed\n"); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread);
- ime_trace( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + msg_spy_pump_msg_queue(); + thread = CreateThread(NULL, 0, disable_ime_process, 0, 0, NULL); + ok(thread != NULL, "CreateThread failed\n"); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread);
- if (ignore_message( msg )) return DefWindowProcW( hwnd, msg, wparam, lparam ); + ok(IsWindow(def), "not a window\n"); + def2 = ImmGetDefaultIMEWnd(hwnd); + ok(def2 == def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def2); + ok(IsWindow(def), "not a window\n"); + msg_spy_pump_msg_queue(); + ok(!IsWindow(def), "window is still valid\n"); + def = ImmGetDefaultIMEWnd(hwnd); + ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def);
- ime_calls[ime_call_count++] = call; - return DefWindowProcW( hwnd, msg, wparam, lparam ); + r = ImmDisableIME(-1); + ok(r, "ImmDisableIME(-1) failed\n"); + def = ImmGetDefaultIMEWnd(hwnd); + ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def); }
-static WNDCLASSEXW ime_ui_class = -{ - .cbSize = sizeof(WNDCLASSEXW), - .style = CS_IME, - .lpfnWndProc = ime_ui_window_proc, - .cbWndExtra = 2 * sizeof(LONG_PTR), - .lpszClassName = L"WineTestIME", -}; - -static WNDCLASSEXW test_class = -{ - .cbSize = sizeof(WNDCLASSEXW), - .lpfnWndProc = test_window_proc, - .lpszClassName = L"WineTest", -}; - static BOOL WINAPI ime_ImeConfigure( HKL hkl, HWND hwnd, DWORD mode, void *data ) { ime_trace( "hkl %p, hwnd %p, mode %lu, data %p\n", hkl, hwnd, mode, data ); @@ -3136,15 +3136,15 @@ static BOOL WINAPI ime_ImeInquire( IMEINFO *info, WCHAR *ui_class, DWORD flags ) return TRUE; }
-static BOOL WINAPI ime_ImeProcessKey( HIMC himc, UINT vkey, LPARAM key_data, BYTE *key_state ) +static BOOL WINAPI ime_ImeProcessKey( HIMC himc, UINT vkey, LPARAM lparam, BYTE *state ) { struct ime_call call = { .hkl = GetKeyboardLayout( 0 ), .himc = himc, - .func = IME_PROCESS_KEY, .process_key = {.vkey = vkey, .key_data = key_data} + .func = IME_PROCESS_KEY, .process_key = {.vkey = vkey, .lparam = lparam} }; - ime_trace( "himc %p, vkey %u, key_data %#Ix, key_state %p\n", - himc, vkey, key_data, key_state ); + ime_trace( "himc %p, vkey %u, lparam %#Ix, state %p\n", + himc, vkey, lparam, state ); ime_calls[ime_call_count++] = call; return TRUE; } @@ -4644,7 +4644,7 @@ static void test_ImmProcessKey(void) { { .hkl = expect_ime, .himc = default_himc, - .func = IME_PROCESS_KEY, .process_key = {.vkey = 'A', .key_data = 0}, + .func = IME_PROCESS_KEY, .process_key = {.vkey = 'A', .lparam = 0}, }, {0}, };