Piotr Caban : user32/tests: Add mouse SendInput tests.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Oct 17 05:00:41 CDT 2014
Module: wine
Branch: master
Commit: 65b09537b34fc5b153057a37996c40b8b4f5d8ee
URL: http://source.winehq.org/git/wine.git/?a=commit;h=65b09537b34fc5b153057a37996c40b8b4f5d8ee
Author: Piotr Caban <piotr at codeweavers.com>
Date: Tue Oct 14 13:28:12 2014 +0200
user32/tests: Add mouse SendInput tests.
---
dlls/user32/tests/input.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 253 insertions(+)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 8f24a4c..e60ee27 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -1643,6 +1643,258 @@ static void test_key_names(void)
ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) );
}
+static void simulate_click(BOOL left, int x, int y)
+{
+ INPUT input[2];
+ UINT events_no;
+
+ SetCursorPos(x, y);
+ memset(input, 0, sizeof(input));
+ input[0].type = INPUT_MOUSE;
+ U(input[0]).mi.dx = x;
+ U(input[0]).mi.dy = y;
+ U(input[0]).mi.dwFlags = left ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
+ input[1].type = INPUT_MOUSE;
+ U(input[1]).mi.dx = x;
+ U(input[1]).mi.dy = y;
+ U(input[1]).mi.dwFlags = left ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
+ events_no = SendInput(2, input, sizeof(input[0]));
+ ok(events_no == 2, "SendInput returned %d\n", events_no);
+}
+
+static BOOL wait_for_message( MSG *msg )
+{
+ BOOL ret;
+
+ for (;;)
+ {
+ ret = PeekMessageA(msg, 0, 0, 0, PM_REMOVE);
+ if (ret)
+ {
+ if (msg->message == WM_PAINT) DispatchMessageA(msg);
+ else break;
+ }
+ else if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT) break;
+ }
+ if (!ret) msg->message = 0;
+ return ret;
+}
+
+static BOOL wait_for_event(HANDLE event, int timeout)
+{
+ DWORD end_time = GetTickCount() + timeout;
+ MSG msg;
+
+ do {
+ if(MsgWaitForMultipleObjects(1, &event, FALSE, timeout, QS_ALLINPUT) == WAIT_OBJECT_0)
+ return TRUE;
+ while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
+ DispatchMessageA(&msg);
+ timeout = end_time - GetTickCount();
+ }while(timeout > 0);
+
+ return FALSE;
+}
+
+static WNDPROC def_static_proc;
+static DWORD hittest_no;
+static LRESULT WINAPI static_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+ if (msg == WM_NCHITTEST)
+ {
+ /* break infinite hittest loop */
+ if(hittest_no > 50) return HTCLIENT;
+ hittest_no++;
+ }
+
+ return def_static_proc(hwnd, msg, wp, lp);
+}
+
+struct thread_data
+{
+ HANDLE start_event;
+ HANDLE end_event;
+ HWND win;
+};
+
+static DWORD WINAPI create_static_win(void *arg)
+{
+ struct thread_data *thread_data = arg;
+ HWND win;
+
+ win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
+ 100, 100, 100, 100, 0, NULL, NULL, NULL);
+ ok(win != 0, "CreateWindow failed\n");
+ def_static_proc = (void*)SetWindowLongPtrA(win,
+ GWLP_WNDPROC, (LONG_PTR)static_hook_proc);
+ thread_data->win = win;
+
+ SetEvent(thread_data->start_event);
+ wait_for_event(thread_data->end_event, 5000);
+ return 0;
+}
+
+static void test_Input_mouse(void)
+{
+ BOOL got_button_down, got_button_up;
+ HWND hwnd, button_win, static_win;
+ struct thread_data thread_data;
+ HANDLE thread;
+ DWORD thread_id;
+ POINT pt;
+ MSG msg;
+
+ button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
+ 100, 100, 100, 100, 0, NULL, NULL, NULL);
+ ok(button_win != 0, "CreateWindow failed\n");
+
+ pt.x = pt.y = 150;
+ hwnd = WindowFromPoint(pt);
+ if (hwnd != button_win)
+ {
+ skip("there's another window covering test window\n");
+ DestroyWindow(button_win);
+ return;
+ }
+
+ /* simple button click test */
+ simulate_click(TRUE, 150, 150);
+ got_button_down = got_button_up = FALSE;
+ while (wait_for_message(&msg))
+ {
+ DispatchMessageA(&msg);
+
+ if (msg.message == WM_LBUTTONDOWN)
+ {
+ got_button_down = TRUE;
+ }
+ else if (msg.message == WM_LBUTTONUP)
+ {
+ got_button_up = TRUE;
+ break;
+ }
+ }
+ ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
+ ok(got_button_up, "expected WM_LBUTTONUP message\n");
+
+ /* click through HTTRANSPARENT child window */
+ static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_CHILD,
+ 0, 0, 100, 100, button_win, NULL, NULL, NULL);
+ ok(static_win != 0, "CreateWindow failed\n");
+ def_static_proc = (void*)SetWindowLongPtrA(static_win,
+ GWLP_WNDPROC, (LONG_PTR)static_hook_proc);
+ simulate_click(FALSE, 150, 150);
+ hittest_no = 0;
+ got_button_down = got_button_up = FALSE;
+ while (wait_for_message(&msg))
+ {
+ DispatchMessageA(&msg);
+
+ if (msg.message == WM_RBUTTONDOWN)
+ {
+ ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
+ got_button_down = TRUE;
+ }
+ else if (msg.message == WM_RBUTTONUP)
+ {
+ ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
+ got_button_up = TRUE;
+ break;
+ }
+ }
+ ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
+ todo_wine ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
+ todo_wine ok(got_button_up, "expected WM_RBUTTONUP message\n");
+ DestroyWindow(static_win);
+
+ /* click through HTTRANSPARENT top-level window */
+ static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
+ 100, 100, 100, 100, 0, NULL, NULL, NULL);
+ ok(static_win != 0, "CreateWindow failed\n");
+ def_static_proc = (void*)SetWindowLongPtrA(static_win,
+ GWLP_WNDPROC, (LONG_PTR)static_hook_proc);
+ simulate_click(TRUE, 150, 150);
+ hittest_no = 0;
+ got_button_down = got_button_up = FALSE;
+ while (wait_for_message(&msg))
+ {
+ DispatchMessageA(&msg);
+
+ if (msg.message == WM_LBUTTONDOWN)
+ {
+ ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
+ got_button_down = TRUE;
+ }
+ else if (msg.message == WM_LBUTTONUP)
+ {
+ ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
+ got_button_up = TRUE;
+ break;
+ }
+ }
+ ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
+ todo_wine ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
+ todo_wine ok(got_button_up, "expected WM_LBUTTONUP message\n");
+ DestroyWindow(static_win);
+
+ /* click on HTTRANSPARENT top-level window that belongs to other thread */
+ thread_data.start_event = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ok(thread_data.start_event != NULL, "CreateEvent failed\n");
+ thread_data.end_event = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ok(thread_data.end_event != NULL, "CreateEvent failed\n");
+ thread = CreateThread(NULL, 0, create_static_win, &thread_data, 0, NULL);
+ ok(thread != NULL, "CreateThread failed\n");
+ hittest_no = 0;
+ got_button_down = got_button_up = FALSE;
+ WaitForSingleObject(thread_data.start_event, INFINITE);
+ simulate_click(FALSE, 150, 150);
+ while (wait_for_message(&msg))
+ {
+ DispatchMessageA(&msg);
+
+ if (msg.message == WM_RBUTTONDOWN)
+ got_button_down = TRUE;
+ else if (msg.message == WM_RBUTTONUP)
+ got_button_up = TRUE;
+ }
+ SetEvent(thread_data.end_event);
+ WaitForSingleObject(thread, INFINITE);
+ ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
+ ok(!got_button_down, "unexpected WM_RBUTTONDOWN message\n");
+ ok(!got_button_up, "unexpected WM_RBUTTONUP message\n");
+
+ /* click on HTTRANSPARENT top-level window that belongs to ther thread,
+ * threads input queues are attached */
+ thread = CreateThread(NULL, 0, create_static_win, &thread_data, 0, &thread_id);
+ ok(thread != NULL, "CreateThread failed\n");
+ hittest_no = 0;
+ got_button_down = got_button_up = FALSE;
+ WaitForSingleObject(thread_data.start_event, INFINITE);
+ ok(AttachThreadInput(thread_id, GetCurrentThreadId(), TRUE),
+ "AttachThreadInput failed\n");
+ while (wait_for_message(&msg)) DispatchMessageA(&msg);
+ SetWindowPos(thread_data.win, button_win, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+ simulate_click(TRUE, 150, 150);
+ while (wait_for_message(&msg))
+ {
+ DispatchMessageA(&msg);
+
+ if (msg.message == WM_LBUTTONDOWN)
+ got_button_down = TRUE;
+ else if (msg.message == WM_LBUTTONUP)
+ got_button_up = TRUE;
+ }
+ SetEvent(thread_data.end_event);
+ WaitForSingleObject(thread, INFINITE);
+ todo_wine ok(hittest_no > 50, "expected loop with WM_NCHITTEST messages\n");
+ ok(!got_button_down, "unexpected WM_LBUTTONDOWN message\n");
+ ok(!got_button_up, "unexpected WM_LBUTTONUP message\n");
+
+ CloseHandle(thread_data.start_event);
+ CloseHandle(thread_data.end_event);
+ DestroyWindow(button_win);
+}
+
START_TEST(input)
{
init_function_pointers();
@@ -1652,6 +1904,7 @@ START_TEST(input)
test_Input_blackbox();
test_Input_whitebox();
test_Input_unicode();
+ test_Input_mouse();
}
else win_skip("SendInput is not available\n");
More information about the wine-cvs
mailing list