Подтвердить что ты не робот

Почему SetWindowsHookEx должен использоваться с очередью сообщений Windows

Я пробовал некоторые вещи с помощью перехватчиков, и я не понимаю, почему крючки должны использоваться с очередью сообщений

hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
        TranslateMessage(&msg);
        DispatchMessage(&msg);
}
UnhookWindowsHookEx(hook);

Почему это не работает?

hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0);
cin >> aKey;
UnhookWindowsHookEx(hook);

Использование повышающих потоков, и барьер тоже не работает. Почему нельзя ожидать ожидания между крюком и отцеплением другим способом?

EDIT:

Я сделал ошибку, когда создал этот образец, я создаю крюк WH_KEYBOARD_LL, а не WH_KEYBOARD (я не думаю, что это имеет большое значение)

Также цикл никогда не выполняет только ожидания функции GetMessage.

Цикл выполняется только тогда, когда я отправляю сообщение quit PostThreadMessage(id, WM_QUIT, 2323, NULL);, поэтому я не понимаю, что он делает, помимо ожидания, есть ли какая-то внутренняя обработка?

СВЯЗАННЫЕ:

С++ SetWindowsHookEx WH_KEYBOARD_LL Исправить настройку

Как настроить крючок CBT в окне консоли Win32?

4b9b3361

Ответ 1

Низкоуровневые крючки WH_KEYBOARD_LL и WH_MOUSE_LL отличаются от всех других крючков. Им не требуется встраивать DLL в целевой процесс. Вместо этого Windows вызывает ваш обратный вызов с крюком напрямую, внутри вашего собственного процесса. Для выполнения этой работы требуется цикл сообщений. Нет другого механизма, позволяющего Windows делать обратные вызовы в вашем основном потоке, обратный вызов может возникать только тогда, когда вы вызывали Get/PeekMessage(), так что Windows находится под контролем.

Глобальный крючок, подобный WH_KEYBOARD, очень отличается. Для этого требуется DLL, и обратный вызов происходит в процессе, обрабатывающем сообщение клавиатуры. Вам нужно какое-то межпроцессное общение, чтобы ваша собственная программа знала об этом. Именованные трубы являются обычным выбором. В противном случае, конечно, требуется, чтобы этот инжектируемый процесс перекачал контур сообщения. В противном случае он не получал бы клавиатурные сообщения.

Благодарите за низкоуровневый крюк, им гораздо легче двигаться. Но делать насос, или он не будет работать. И будьте осторожны с таймаутами, если вы недостаточно отзывчивы, тогда Windows будет убивать ваш крючок без уведомления.

Понимание низкоуровневого мыши и клавиатуры (win32)

Ответ 2

Крюки Windows подключают цикл сообщений Windows: http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook

Крючок WH_KEYBOARD позволяет приложению отслеживать трафик сообщений для сообщений WM_KEYDOWN и WM_KEYUP, которые должны быть возвращены GetMessage или PeekMessage. Вы можете использовать крюк WH_KEYBOARD для контроля ввода клавиатуры, отправленного в очередь сообщений.

Консольные приложения сами не перекачивают сообщения - процесс консоли. Поэтому он не будет работать, если процесс не имеет цикла сообщений.

См:

Как настроить крючок CBT в окне консоли Win32?

С++ SetWindowsHookEx WH_KEYBOARD_LL Исправить настройку