From 6c64b74a7cdddf0456f592f8db8f97882f34590c Mon Sep 17 00:00:00 2001 From: Vitaliy Margolen Date: Mon, 30 Jan 2006 14:56:17 +0100 Subject: [PATCH] user/tests: Add test for low level mouse hooks. --- dlls/user/tests/msg.c | 82 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/dlls/user/tests/msg.c b/dlls/user/tests/msg.c index 2495df751c7..dd671d7641b 100644 --- a/dlls/user/tests/msg.c +++ b/dlls/user/tests/msg.c @@ -5659,6 +5659,13 @@ static const struct message WmGlobalHookSeq_2[] = { { 0 } }; +static const struct message WmMouseLLHookSeq[] = { + { WM_MOUSEMOVE, hook }, + { WM_LBUTTONDOWN, hook }, + { WM_LBUTTONUP, hook }, + { 0 } +}; + static void CALLBACK win_event_global_hook_proc(HWINEVENTHOOK hevent, DWORD event, HWND hwnd, @@ -5710,6 +5717,21 @@ static LRESULT CALLBACK cbt_global_hook_proc(int nCode, WPARAM wParam, LPARAM lP return CallNextHookEx(hCBT_global_hook, nCode, wParam, lParam); } + /* WH_MOUSE_LL hook */ + if (nCode == HC_ACTION) + { + struct message msg; + MSLLHOOKSTRUCT *mhll = (MSLLHOOKSTRUCT *)lParam; + + /* we can't test for real mouse events */ + if (mhll->flags & LLMHF_INJECTED) + { + msg.message = wParam; + msg.flags = hook; + add_message(&msg); + } + return CallNextHookEx(hCBT_global_hook, nCode, wParam, lParam); + } /* Log also SetFocus(0) calls */ hwnd = wParam ? (HWND)wParam : (HWND)lParam; @@ -5798,6 +5820,33 @@ static DWORD WINAPI cbt_global_hook_thread_proc(void *param) return 0; } +static DWORD WINAPI mouse_ll_global_thread_proc(void *param) +{ + HWND hwnd; + MSG msg; + HANDLE hevent = *(HANDLE *)param; + + hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL); + assert(hwnd); + trace("created thread window %p\n", hwnd); + + *(HWND *)param = hwnd; + + flush_sequence(); + + mouse_event(MOUSEEVENTF_MOVE, 100, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); + + SetEvent(hevent); + while (GetMessage(&msg, 0, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return 0; +} + static void test_winevents(void) { BOOL ret; @@ -5960,6 +6009,39 @@ static void test_winevents(void) ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n"); /****** end of out of context event test *************/ + /****** start of MOUSE_LL hook test *************/ + hCBT_global_hook = SetWindowsHookExA(WH_MOUSE_LL, cbt_global_hook_proc, GetModuleHandleA(0), 0); + assert(hCBT_global_hook); + + hevent = CreateEventA(NULL, 0, 0, NULL); + assert(hevent); + hwnd2 = (HWND)hevent; + + hthread = CreateThread(NULL, 0, mouse_ll_global_thread_proc, &hwnd2, 0, &tid); + ok(hthread != NULL, "CreateThread failed, error %ld\n", GetLastError()); + + while (WaitForSingleObject(hevent, 100) == WAIT_TIMEOUT) + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + + ok_sequence(WmMouseLLHookSeq, "MOUSE_LL hook other thread", FALSE); + flush_sequence(); + + mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); + + ok_sequence(WmMouseLLHookSeq, "MOUSE_LL hook same thread", FALSE); + + ret = UnhookWindowsHookEx(hCBT_global_hook); + ok( ret, "UnhookWindowsHookEx error %ld\n", GetLastError()); + + PostThreadMessageA(tid, WM_QUIT, 0, 0); + ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n"); + CloseHandle(hthread); + CloseHandle(hevent); + ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n"); + /****** end of MOUSE_LL hook test *************/ + ok(DestroyWindow(hwnd), "failed to destroy window\n"); }