Я пытаюсь захватить глобальный ввод мыши и клавиатуры.
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
).
Теперь, насколько я понимаю, низкоуровневые перехватчики работают путем переключения контекста на процесс, который его установил, а затем отправляют процессу какое-то сообщение, позволяющее ему выполнять обратный вызов hook. Меня немного смущает, поэтому моя программа никогда не будет печатать "msg recvd", но при каждом нажатии правой кнопки мыши она выводит "правую мышь вниз/вверх". Это приводит меня к выводу, что мой MouseHookProc
вызывается во время вызова PeekMessage
. Просто случается, что это какое-то специальное сообщение, а PeekMessage
возвращает 0. Но мне все равно нужно называть PeekMessage
или какой-то эквивалент.
Поскольку моя программа должна выполнять кучу вещей, я, очевидно, не могу взвесить цикл пересылки сообщений (тот, который вызывает PeekMessage
), вызывая другую функцию, которая принимает, скажем, 50 мс для возврата. Как я могу многократно использовать мою программу для поддержания реакции на мышь, одновременно делая небольшой тяжелый подъем? В многопоточной программе win32 существует еще одна очередь сообщений, правильно?
Обновление: прочитав документацию по MS, я думаю, что знаю, что мне нужно делать правильно. Я должен просто создать поток в моем приложении, который вызывает SetWindowsHookEx
, чтобы зарегистрировать крючок мыши, а затем посидеть в своем собственном контуре сообщений, и система позаботится о том, чтобы поместить обновления мыши в этот поток. Он будет свободен делать все, что захочет, в MouseHookProc
, а остальная часть моего приложения будет работать независимо.