Estoy intentando capturar la entrada global de mouse y teclado.Comprensión del gancho de mouse y teclado de bajo nivel (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
}
Así que todo funciona aquí, excepto si #define TEST
a poner en el Sleep
, el ratón se vuelve increíblemente lento, como era de esperar si de repente solo permiten el ratón para actualizar 20 veces por segundo. Y sin el sueño, estoy vinculando la CPU al 100%. Pero está bien por ahora (eso desaparece si uso GetMessage
).
Ahora, tal como lo entiendo, los ganchos de bajo nivel funcionan cambiando el contexto al proceso que lo instaló, y luego enviando al proceso algún tipo de mensaje para que ejecute la devolución de llamada del enlace. Lo que me confunde un poco, sin embargo, es por qué mi programa nunca imprimirá "msg recvd", pero imprime "el botón derecho del mouse hacia arriba/arriba" cada vez que hago clic con el botón derecho del mouse. Esto me lleva a concluir que mi MouseHookProc
se invoca durante la llamada PeekMessage
. Simplemente sucede que es un tipo de mensaje especial y PeekMessage
devuelve 0. Pero aún necesito llamar al PeekMessage
o un equivalente.
Dado que mi programa necesita hacer un montón de cosas, claramente no puedo pesar mi ciclo de bombeo de mensajes (el que llama al PeekMessage
) llamando a otra función que tarda, digamos 50ms en regresar. ¿Cómo puedo leer varias veces mi programa para mantener la capacidad de respuesta del mouse y al mismo tiempo hacer un poco de trabajo pesado? En un programa de Win32 multiproceso, todavía hay una sola cola de mensajes, ¿verdad?
Actualización: Después de leer la documentación de MS, creo que sé lo que es correcto para mí. Debería generar un hilo en mi aplicación que llame al SetWindowsHookEx
para registrar el gancho del mouse, y luego sentarme en su propio bucle de mensajes, y el sistema se encargará de enviar las actualizaciones del mouse a este hilo. Será libre de hacer lo que quiera dentro del MouseHookProc
, y el resto de mi aplicación se ejecutará de forma independiente.
¿Tiene 'MouseHookProc' dentro de un archivo DLL y' SetWindowsHookEx' y 'PeekMessage' dentro de un archivo EXE? – Oleg
Quería evitar tener que inyectar una DLL. Parece más adecuado para mis necesidades para que el sistema cambie a mi programa para llamarlo 'MouseHookProc', de ahí que quiera usar el gancho de bajo nivel del mouse. Según lo entiendo, un gancho de mouse normal, si quiero que sea global, debe usar el método DLL. –