Я пытаюсь захватить глобальный ввод с помощью мыши и клавиатуры.
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
if (wParam == WM_RBUTTONDOWN) printf("right mouse down\n");
if (wParam == WM_RBUTTONUP) printf("right mouse up\n");
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
while(true) {
MSG msg;
if (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
printf("msg recvd\n");
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#ifdef TEST
Sleep(50);
#endif
}
Так что все работает здесь, кроме того, что если я #define TEST
вставлю Sleep
, мышь станет невероятно вялой, как и следовало ожидать, если я вдруг позволю мыши обновляться только 20 раз в секунду. А без сна привязываю процессор на 100%. Но пока все в порядке (это исчезнет, если я использую GetMessage
).
Теперь, насколько я понимаю, низкоуровневые перехватчики работают путем переключения контекста на процесс, который его установил, и затем посылают процессу какое-то сообщение, чтобы позволить ему выполнить обратный вызов перехвата. Что меня немного смущает, так это то, что моя программа никогда не будет печатать «msg recvd», а печатает «правой / левой кнопкой мыши вниз / вверх» всякий раз, когда я нажимаю правую кнопку мыши. Это приводит меня к выводу, что мой MouseHookProc
вызывается во время вызова PeekMessage
. Просто случается, что это какое-то специальное сообщение, и PeekMessage
возвращает 0. Но мне все еще нужно позвонить PeekMessage
или какому-то эквивалентному.
Так как моей программе нужно делать кучу вещей, я явно не могу взвесить мой цикл прокачки сообщений (тот, который вызывает PeekMessage
), вызывая другую функцию, которая требует, скажем, 50 мс для возврата. Как я могу использовать многопоточность своей программы, чтобы поддерживать отзывчивость мыши при одновременной небольшой нагрузке? В многопоточной программе win32 есть только одна очередь сообщений, верно?
Обновление: после прочтения документации MS я думаю, что знаю, что мне нужно сделать. Я должен просто создать поток в моем приложении, который вызывает SetWindowsHookEx
, чтобы зарегистрировать ловушку мыши, а затем сидеть в своем собственном цикле сообщений, и система позаботится об отправке обновлений мыши в этот поток. В MouseHookProc
он будет свободен делать все, что захочет, а остальная часть моего приложения будет работать независимо.