user32/tests: Add mouse SendInput tests.

This commit is contained in:
Piotr Caban 2014-10-14 13:28:12 +02:00 committed by Alexandre Julliard
parent 80cbd276e0
commit 65b09537b3
1 changed files with 253 additions and 0 deletions

View File

@ -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");