2011-09-18 15 views
11

He estado tratando algunas cosas con ganchos, y yo no entiendo por qué ganchos deben ser usados ​​con una cola de mensajesSetWindowsHookEx ser utilizado con una cola de mensajes ventanas

hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0); 
MSG msg; 
while(GetMessage(&msg, NULL, 0, 0) > 0) 
{ 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
} 
UnhookWindowsHookEx(hook); 

¿Por qué no hace algo como este trabajo?

hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0); 
cin >> aKey; 
UnhookWindowsHookEx(hook); 

Uso de los hilos de refuerzo, y una barrera tampoco funciona. ¿Por qué la espera entre el gancho y el desenganche no se puede hacer de otra manera?

EDIT:

hice un error cuando creé esta muestra, se crea un gancho WH_KEYBOARD_LL, no WH_KEYBOARD, (no creo que hace una gran diferencia)

también el bucle no se ejecuta nunca solo espera en la función GetMessage.

El ciclo se ejecuta solo cuando publico el mensaje de abandono PostThreadMessage(id, WM_QUIT, 2323, NULL);, así que no entiendo qué hace al lado de esperar, ¿hay algún procesamiento interno?

RELACIONADA:

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

How can I set up a CBT hook on a Win32 console window?

Respuesta

26

Los ganchos de bajo nivel, y WH_KEYBOARD_LL WH_MOUSE_LL son diferentes de todos los otros ganchos. No requieren una DLL para ser inyectada en el proceso objetivo. En cambio, Windows llama a su devolución de llamada de enlace directamente, dentro de su propio proceso. Para que funcione, se requiere un ciclo de mensajes. No hay otro mecanismo para que Windows realice devoluciones de llamada en su hilo principal, la devolución de llamada solo puede ocurrir cuando ha llamado a Get/PeekMessage() para que Windows tenga el control.

Un gancho global como WH_KEYBOARD es muy diferente. Requiere una DLL y la devolución de llamada ocurre dentro del proceso que procesa el mensaje del teclado. Necesita algún tipo de comunicación entre procesos para que su propio programa tenga conocimiento de esto. Las tuberías con nombre son la elección habitual. Lo cual, por supuesto, requiere que este proceso inyectado bombee un ciclo de mensajes. De lo contrario, no recibiría mensajes de teclado.

Favorecer un gancho de bajo nivel, son mucho más fácil de poner en marcha.Pero hazlo o no funcionará. Y ten cuidado con los tiempos de espera, si no respondes lo suficiente, Windows matará tu anzuelo sin previo aviso.

Understanding the low-level mouse and keyboard hook (win32)

+0

Entonces, si entiendo esto correctamente, Windows solo puede llamar a mi devolución de llamada mientras está en una llamada Get/PeekMessage()? – Ha11owed

+2

Lo entiende correctamente. No hay otra forma de insertar llamadas de forma segura en un hilo, tiene que estar inactivo. Esta es la razón por la cual existen bucles de mensajes. –

+0

@HansPassant para aclarar, ¿sugiere que para los enlaces globales como WH_KEYBOARD los conductos con nombre se puedan usar para "pasar" información a mi propio programa y ese programa no necesita una bomba de mensajes? – dave

4

de Windows Hooks enganchar el mensaje bucle de Windows: http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook

El gancho WH_KEYBOARD permite que una aplicación para supervisar el tráfico de mensajes para WM_KEYDOWN y WM_KEYUP mensajes a punto de ser devueltos por el Función GetMessage o PeekMessage. Puede utilizar el gancho WH_KEYBOARD para controlar la entrada de teclado publicada en una cola de mensajes.

Las aplicaciones de consola no bombean los mensajes ellos mismos: el proceso de la consola sí lo hace. Por lo tanto, no funcionará a menos que el proceso tenga un ciclo de mensajes.

Ver:

How can I set up a CBT hook on a Win32 console window?

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

+0

gracias por los enlaces, fui a través de todos ellos, pero todavía no entienden lo GetMessage qué lado de la espera. En mi caso (aplicación de consola) la única vez que se ejecuta cuando publico el mensaje de abandono en el hilo. – Ha11owed

+0

Además, dado que GetMessage espera, ¿no significa esto que la consola no está enviando ningún mensaje hasta mi mensaje de abandono? – Ha11owed

+0

Consulte la respuesta de Han: Windows solo devolverá su cadena cuando sepa que está inactiva. Y si el hilo está bloqueado en GetMesasge() Windows sabe que no está haciendo nada – shf301

Cuestiones relacionadas