Я пытаюсь захватить глобальный ввод мыши и клавиатуры.
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, а остальная часть моего приложения будет работать независимо.