En una aplicación Delphi XE, estoy tratando de configurar un gancho global para monitorear los cambios de enfoque. El gancho se crea en un archivo DLL:SetWindowsHookEx crea un gancho local. ¿Cómo hacerlo global?
focusHook := SetWindowsHookEx(WH_CBT, @FocusHookProc, HInstance, 0);
// dwThreadId (the last argument) set to 0 should create a global hook
En la misma DLL tengo el procedimiento de enlace que publica un mensaje a la ventana de la aplicación host:
function FocusHookProc(code : integer; wParam: WPARAM; lParam: LPARAM) : LResult; stdcall;
begin
if (code < 0) then
begin
result := CallNextHookEx(focusHook, code, wParam, lParam);
exit;
end;
result := 0;
if (code = HCBT_SETFOCUS) then
begin
if (hostHWND <> INVALID_HANDLE_VALUE) then
PostMessage(hostHWND, cFOCUSMSGID, wParam, lParam);
end;
end;
Esto funciona, pero el anfitrión sólo recibe notificaciones en cambios de foco dentro de la aplicación misma. Hay una nota y algunos TButtons en el formulario principal, y cambiar el foco entre ellos produce el mensaje esperado. Sin embargo, ningún cambio de foco fuera de la aplicación en sí nunca se informa.
Supongo que tiene algo que ver con varias instancias de DLL que se inyecta en otros procesos. Hay una pregunta similar con una respuesta aceptada here, pero es para C, y no puedo ver cómo puedo hacer lo mismo en un dll Delphi (por ejemplo, las declaraciones pragma para configurar la memoria compartida).
(Esto es sobre todo una prueba de concepto, pero aún me gustaría ponerlo a funcionar. Necesito saber qué ventana estaba activa justo antes de que mi aplicación se activara al hacer clic, alt + tab, activación hotkey etc. El problema es que si se usa el mouse o alt + tab, GetForegroundWindow siempre devuelve el manejador de la ventana de mi propia aplicación, sin importar qué tan temprano lo puse, como enganchar la cola de mensajes principal de la aplicación. única solución viable, aunque no me gusta mucho la idea.)
+1 en cada DLL que tiene sus propios datos siendo el problema probable aquí. Sin embargo, en este caso específico, el OP puede no necesitar el uso de la memoria compartida: una solución simple para el código anterior sería dar a la ventana de destino una nombre de clase específico, y hacer que el código de enlace use FindWindow para encontrar ese objetivo. Además, otra limitación de los ganchos: los ganchos de 32 bits solo se pueden enganchar en el código de 32 bits; del mismo modo con 64 bits; de modo que conectar ambos procesos de 32 y 64 bits puede ser problemático. – BrendanMcK