1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

win32u: Avoid calling WH_KEYBOARD and WH_CBT HCBT_KEYSKIPPED hooks recursively.

Previously, accept_hardware_message() is called after WH_KEYBOARD and WH_CBT HCBT_KEYSKIPPED hooks.
So when PeekMessage() gets called in WH_KEYBOARD and WH_CBT HCBT_KEYSKIPPED hooks, the hooks will be
called recursively because the message is still in the server message queue.

Fix Toad for Oracle F3 find next function not working properly because its WH_KEYBOARD hook gets
called too many times.
This commit is contained in:
Zhiyi Zhang 2023-12-14 15:02:37 +08:00 committed by Alexandre Julliard
parent 3c9e57d57f
commit a676f094f6
2 changed files with 4 additions and 4 deletions

View file

@ -12584,7 +12584,6 @@ static void test_recursive_hook(void)
flush_events();
/* Expect the WH_KEYBOARD hook not gets called recursively */
todo_wine
ok(max_hook_depth == 1, "Got expected %d.\n", max_hook_depth);
/* Test a possible recursive WH_CBT HCBT_KEYSKIPPED hook condition */
@ -12600,7 +12599,6 @@ static void test_recursive_hook(void)
while (PeekMessageA(&msg, hook_hwnd, WM_KEYFIRST, WM_KEYLAST, 0)) DispatchMessageA(&msg);
/* Expect the WH_CBT HCBT_KEYSKIPPED hook not gets called recursively */
todo_wine
ok(max_hook_depth == 1, "Got expected %d.\n", max_hook_depth);
UnhookWindowsHookEx(cbt_hook);

View file

@ -2384,15 +2384,17 @@ static BOOL process_keyboard_message( MSG *msg, UINT hw_id, HWND hwnd_filter,
}
}
/* if remove is TRUE, remove message first before calling hooks to avoid recursive hook calls */
if (remove) accept_hardware_message( hw_id );
if (call_hooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
LOWORD(msg->wParam), msg->lParam, 0 ))
{
/* if the message has not been removed, remove it */
if (!remove) accept_hardware_message( hw_id );
/* skip this message */
call_hooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, 0 );
accept_hardware_message( hw_id );
return FALSE;
}
if (remove) accept_hardware_message( hw_id );
msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt );
if (remove && msg->message == WM_KEYDOWN)