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