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 }
|
{ 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,
|
static void CALLBACK win_event_global_hook_proc(HWINEVENTHOOK hevent,
|
||||||
DWORD event,
|
DWORD event,
|
||||||
HWND hwnd,
|
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);
|
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 */
|
/* Log also SetFocus(0) calls */
|
||||||
hwnd = wParam ? (HWND)wParam : (HWND)lParam;
|
hwnd = wParam ? (HWND)wParam : (HWND)lParam;
|
||||||
|
@ -5798,6 +5820,33 @@ static DWORD WINAPI cbt_global_hook_thread_proc(void *param)
|
||||||
return 0;
|
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)
|
static void test_winevents(void)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -5960,6 +6009,39 @@ static void test_winevents(void)
|
||||||
ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n");
|
ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n");
|
||||||
/****** end of out of context event test *************/
|
/****** 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");
|
ok(DestroyWindow(hwnd), "failed to destroy window\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue