user/tests: Add test for low level mouse hooks.
This commit is contained in:
parent
b670ec83fd
commit
6c64b74a7c
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue