Rawinput messages are not received anymore if the foreground window is from another process. Using RIDEV_INPUTSINK makes it possible to receive them again, but with RIM_INPUTSINK flag.
Currently the messages may be received correctly, but that depends on where the input events are generated, so add another test case with messages sent from the test process, and validate that nothing should be received.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/tests/input.c | 113 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index af44d3e8b4d..ac6a2476785 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1881,8 +1881,70 @@ struct rawinput_test rawinput_tests[] = /* same-process foreground tests */ { TRUE, FALSE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE }, { TRUE, TRUE, 0, FALSE, TRUE, TRUE, /* todos: */ FALSE, FALSE, FALSE }, + + /* cross-process foreground tests */ + { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE }, + { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, TRUE, FALSE }, + { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, TRUE, TRUE }, };
+static void rawinput_test_process(void) +{ + HANDLE ready, start, done; + POINT pt; + HWND hwnd = NULL; + int i; + + ready = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_ready"); + ok(ready != 0, "OpenEventA failed, error: %u\n", GetLastError()); + + start = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_start"); + ok(start != 0, "OpenEventA failed, error: %u\n", GetLastError()); + + done = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_done"); + ok(done != 0, "OpenEventA failed, error: %u\n", GetLastError()); + + for (i = 0; i < ARRAY_SIZE(rawinput_tests); ++i) + { + WaitForSingleObject(ready, INFINITE); + ResetEvent(ready); + + switch (i) + { + case 6: + case 7: + case 8: + GetCursorPos(&pt); + + hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, + pt.x - 50, pt.y - 50, 100, 100, 0, NULL, NULL, NULL); + ok(hwnd != 0, "CreateWindow failed\n"); + empty_message_queue(); + + ShowWindow(hwnd, SW_SHOW); + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); + SetForegroundWindow(hwnd); + UpdateWindow(hwnd); + empty_message_queue(); + + if (i != 8) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0); + empty_message_queue(); + break; + } + + SetEvent(start); + + WaitForSingleObject(done, INFINITE); + ResetEvent(done); + if (hwnd) DestroyWindow(hwnd); + } + + WaitForSingleObject(ready, INFINITE); + CloseHandle(done); + CloseHandle(start); + CloseHandle(ready); +} + struct rawinput_test_thread_params { HANDLE ready; @@ -1934,14 +1996,17 @@ static DWORD WINAPI rawinput_test_thread(void *arg) return 0; }
-static void test_rawinput(void) +static void test_rawinput(const char* argv0) { struct rawinput_test_thread_params params; + PROCESS_INFORMATION process_info; RAWINPUTDEVICE raw_devices[1]; - HANDLE thread; + STARTUPINFOA startup_info; + HANDLE thread, process_ready, process_start, process_done; DWORD ret; POINT pt, newpt; HWND hwnd; + char path[MAX_PATH]; int i;
params.ready = CreateEventA(NULL, FALSE, FALSE, NULL); @@ -1956,6 +2021,24 @@ static void test_rawinput(void) thread = CreateThread(NULL, 0, rawinput_test_thread, ¶ms, 0, NULL); ok(thread != NULL, "CreateThread failed\n");
+ process_ready = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_ready"); + ok(process_ready != NULL, "CreateEventA failed\n"); + + process_start = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_start"); + ok(process_start != NULL, "CreateEventA failed\n"); + + process_done = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_done"); + ok(process_done != NULL, "CreateEventA failed\n"); + + memset(&startup_info, 0, sizeof(startup_info)); + startup_info.cb = sizeof(startup_info); + startup_info.dwFlags = STARTF_USESHOWWINDOW; + startup_info.wShowWindow = SW_SHOWNORMAL; + + sprintf(path, "%s input rawinput_test", argv0); + ret = CreateProcessA(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info ); + ok(ret, "CreateProcess "%s" failed err %u.\n", path, GetLastError()); + SetCursorPos(100, 100); empty_message_queue();
@@ -1992,13 +2075,18 @@ static void test_rawinput(void) ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08x\n", i, GetLastError()); }
+ SetEvent(process_ready); + WaitForSingleObject(process_start, INFINITE); + ResetEvent(process_start); + SetEvent(params.ready); WaitForSingleObject(params.start, INFINITE); ResetEvent(params.start);
- if (i <= 3) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0); + if (i <= 3 || i == 8) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0); empty_message_queue();
+ SetEvent(process_done); SetEvent(params.done);
todo_wine_if(rawinput_tests[i].todo_legacy) @@ -2028,6 +2116,14 @@ static void test_rawinput(void) DestroyWindow(hwnd); }
+ SetEvent(process_ready); + winetest_wait_child_process(process_info.hProcess); + CloseHandle(process_info.hProcess); + CloseHandle(process_info.hThread); + CloseHandle(process_done); + CloseHandle(process_start); + CloseHandle(process_ready); + WaitForSingleObject(thread, INFINITE);
CloseHandle(params.done); @@ -3229,11 +3325,20 @@ static void test_UnregisterDeviceNotification(void)
START_TEST(input) { + char **argv; + int argc; POINT pos;
init_function_pointers(); GetCursorPos( &pos );
+ argc = winetest_get_mainargs(&argv); + if (argc >= 3 && strcmp(argv[2], "rawinput_test") == 0) + { + rawinput_test_process(); + return; + } + test_Input_blackbox(); test_Input_whitebox(); test_Input_unicode(); @@ -3251,7 +3356,7 @@ START_TEST(input) test_OemKeyScan(); test_GetRawInputData(); test_RegisterRawInputDevices(); - test_rawinput(); + test_rawinput(argv[0]);
if(pGetMouseMovePointsEx) test_GetMouseMovePointsEx();