Cómo usar correctamente SetWindowsHookEx y CallNextHookEx
winapi (1)
Puedo configurar correctamente un gancho de Windows, pero me confunde la línea en MSDN que dice "Llamar a la función CallNextHookEx para encadenar al siguiente procedimiento de enlace es opcional, pero es muy recomendable; de lo contrario, otras aplicaciones que tengan los ganchos instalados no recibir notificaciones de gancho y puede tener un comportamiento incorrecto como resultado. Debería llamar a CallNextHookEx a menos que sea absolutamente necesario evitar que otras aplicaciones vean la notificación ".
Quiero ser un buen ciudadano de programación y llamar al próximo gancho. Pero, mi procedimiento de gancho se ve así:
LRESULT CALLBACK CBTProc(int code, WPARAM wp, LPARAM lp)
{
if (code != HCBT_CREATEWND)
{
// What do I do here? It''s not the event I requested so how do I pass it on?
return 0;
}
// It''s the code we want (create window)
CallNextHookEx(...);
...
}
Entonces, ¿qué sucede en el procedimiento de enlace si el código no es el que me interesa? ¿Cómo llamo al siguiente gancho?
Editar: El principal problema es que un HHOOK se devuelve desde SetWindowsHookEx, y que debe pasar a la función CallNextHookEx.
Actualización: parece que el parámetro hook se ignora en las plataformas NT:
http://msdn.microsoft.com/en-us/library/ms644974.aspx
http://www.klenotic.com/pl/null_hhook/
De acuerdo con los documentos, lo correcto es pasar los argumentos que recibió directamente a CallNextHookEx, exactamente como los recibió. También debe llamar a CallNextHookEx independientemente de si decidió manejar el mensaje de enlace.
Según MSDN , el primer parámetro para CallNextHookEx
se ignora en NT / XP / 2003, y para sistemas operativos antiguos basados en Win95 debe ser el HHOOK
que recibió cuando registró su hook con SetWindowsHookEx
. Los documentos no especifican un valor para Windows 2000, pero como es parte de la familia NT, una suposición razonable es que también se ignora allí.
Teniendo en cuenta todo eso, una buena manera de codificar el método para los sistemas operativos de la familia NT podría ser este:
LRESULT CALLBACK CBTProc( int code, WPARAM wp, LPARAM lp )
{
if( code == HCBT_CREATEWND )
ProcessCreateWnd( wp, lp );
return CallNextHookEx( 0, code, wp, lp );
}
void ProcessCreateWnd( WPARAM wp, LPARAM lp )
{
// my code here
}
Esto asegura que siempre llame al enganche al final de su procesamiento, y hace que sea difícil agregar accidentalmente una return
que evitará CallNextHookEx
.