Я пытаюсь захватить глобальный ввод мыши и клавиатуры.Понимание низкоуровневой мыши и клавиатуры (win32)
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
, а остальная часть моего приложения будет работать независимо.
У вас есть 'MouseHookProc' внутри цикла DLL и' SetWindowsHookEx' и 'PeekMessage' внутри EXE? – Oleg
Мне не хотелось вводить DLL. Кажется более подходящим для моих потребностей в том, чтобы система переключилась на мою программу, чтобы вызвать ее «MouseHookProc», поэтому я хочу использовать крючок с низким уровнем мыши. Насколько я понимаю, обычный крючок мыши, если я хочу, чтобы он был глобальным, должен использовать метод DLL. –