Entran los expertos en programación de VB
Introducción detallada al gancho HOOK SetWindowsHookEx
Concepto básico
Hook es una plataforma para el mecanismo de procesamiento de mensajes de Windows, en la que las aplicaciones pueden configurar subrutinas para monitorear ciertos mensajes. en la ventana especificada, y la ventana monitoreada puede ser creada por otros procesos. Cuando llega un mensaje, se procesa antes de la función del controlador de ventana de destino. El mecanismo de enlace permite que las aplicaciones intercepten y procesen mensajes de ventana o eventos específicos.
Un gancho es en realidad un segmento de programa que procesa mensajes y se conecta al sistema a través de llamadas al sistema. Siempre que se envía un mensaje específico, el programa de enlace capturará el mensaje antes de llegar a la ventana de destino, es decir, la función de enlace primero obtendrá el control
. En este momento, la función de enlace puede procesar (cambiar) el mensaje, continuar entregándolo sin procesarlo o forzar la finalización de la entrega del mensaje.
------------------------------------------------- ---- -------------------------------------
Mecanismo de funcionamiento
1. Lista enlazada de ganchos y subproceso de ganchos:
Cada gancho tiene una lista de punteros asociada, que se denomina lista enlazada de ganchos y es mantenida por el sistema. El puntero de esta lista apunta a la función de devolución de llamada especificada y definida por la aplicación llamada por la subrutina Hook, es decir, cada subrutina de procesamiento del gancho. Cuando aparece un mensaje asociado con el tipo de Hook especificado, el sistema pasa el mensaje a la subrutina Hook. Algunos subprocesos de Hook solo pueden monitorear mensajes, modificar mensajes o detener el progreso de los mensajes para evitar que estos mensajes pasen al siguiente subproceso de Hook o ventana de destino. El gancho instalado más recientemente se coloca al principio de la cadena y el gancho instalado más recientemente se coloca al final, es decir, el que se agrega más tarde obtiene el control primero.
Windows no requiere que el orden de desinstalación de los subprocesos de enlace se invierta respecto del orden de instalación. Cada vez que se desinstala un gancho, Windows libera la memoria que ocupa y actualiza toda la lista de ganchos. Si el programa instala un gancho pero finaliza antes de desinstalarlo, el sistema lo desinstalará automáticamente.
La subrutina de enlace es una función de devolución de llamada definida por la aplicación (función CALLBACK). No se puede definir como una función miembro de una determinada clase, solo se puede definir como una función C ordinaria. Se utiliza para monitorear el sistema o un tipo específico de evento. Estos eventos pueden asociarse con un subproceso específico o pueden ser eventos para todos los subprocesos del sistema.
La subrutina de gancho debe seguir la siguiente sintaxis:
LRESULT CALLBACK HookProc
(
int nCode,
WPARAM wParam,
LPARAM lParam
HookProc es el nombre definido por la aplicación.
El parámetro nCode es el código Hook y la subrutina Hook utiliza este parámetro para determinar la tarea. El valor de este parámetro depende del tipo de gancho. Cada tipo de gancho tiene su propio conjunto de caracteres característicos de código de gancho.
Los valores de los parámetros wParam y lParam dependen del código Hook, pero sus valores típicos contienen información sobre el envío o la recepción de mensajes.
2. Instalación y liberación de enlaces:
Utilice la función API SetWindowsHookEx() para instalar una subrutina de enlaces definida por la aplicación en la lista de enlaces. La función SetWindowsHookEx siempre instala la subrutina Hook al comienzo de la cadena Hook.
Cuando ocurre un evento monitoreado por un tipo específico de Hook, el sistema llama a la subrutina Hook al comienzo de la cadena Hook asociada con este Hook. Cada subproceso Hook en la cadena Hook decide si pasa este evento al siguiente subproceso Hook. La subrutina Hook necesita llamar a la función CallNextHookEx para transferir eventos a la siguiente subrutina Hook.
HHOOK SetWindowsHookEx(
int idHook, //El tipo de gancho, es decir, el tipo de mensaje que maneja
HOOKPROC lpfn, //La dirección puntero de la subrutina de enlace. Si el parámetro dwThreadId es 0
// o el identificador de un hilo creado por otro proceso,
// lpfn debe apuntar a la subrutina de enlace en el. DLL.
// Además, lpfn puede apuntar a un código de subrutina de enlace del proceso actual
// La dirección de entrada de la función de enlace. gancho engancha cualquier mensaje. /p>
HINSTANCE hMod, // El identificador de la instancia de la aplicación Identifica la
DLL que contiene el subproceso señalado por lpfn. Si dwThreadId identifica la creación del proceso actual. Un hilo,
// Y el código de subrutina se encuentra en el proceso actual, hMod debe ser NULL
// Se puede configurar fácilmente. como identificador de instancia de esta aplicación
DWORD dwThreadId // El identificador del subproceso asociado con el subproceso de enlace instalado
// Si es 0, el subproceso de enlace. El proceso está asociado con todos los subprocesos, que es global. Hook.
Si la función tiene éxito, devolverá el identificador del subproceso del gancho. falla, devolverá NULL.
La asociación entre el subproceso de enlace y el hilo mencionado anteriormente significa que los mensajes enviados al hilo en una lista de enlaces se envían al subproceso de enlace al mismo tiempo y son procesados por el enlace. subproceso primero.
Llame a la función de enlace que ha obtenido el control en la subrutina de enlace. Después de completar el procesamiento del mensaje, si desea que el mensaje continúe entregándose, debe llamar a la función API CallNextHookEx en otro SDK. para entregarlo, para ejecutar la siguiente subrutina de enlace señalada por la lista de enlaces. En caso de éxito, esta función devuelve el valor de retorno del siguiente procedimiento de enlace en la cadena de enlace. El tipo de valor de retorno depende del tipo de enlace. El prototipo de esta función es el siguiente:
LRESULT CallNextHookEx
(
HHOOK hhk;
int nCode;
WPARAM wParam;
LPARAM lParam;
);
hhk es el identificador del gancho actual, devuelto por la función SetWindowsHookEx().
NCode es el código de evento pasado al proceso de enlace.
wParam y lParam son los valores de wParam pasados al subproceso de enlace respectivamente, y sus significados específicos están relacionados con el tipo de enlace.
La función de enlace también puede descartar el mensaje e impedir la entrega del mensaje devolviendo VERDADERO directamente. De lo contrario, otras aplicaciones enlazadas no recibirán notificaciones de enlace y pueden producir resultados incorrectos.
Después de usar el gancho, debe usar UnHookWindowsHookEx() para desinstalarlo; de lo contrario, causará problemas. Liberar el gancho es relativamente simple, UnHookWindowsHookEx() tiene solo un parámetro.
El prototipo de la función es el siguiente:
UnHookWindowsHookEx
(
HHOOK hhk;
The); La función devuelve VERDADERO con éxito; de lo contrario, devuelve FALSO.
3. Algunos mecanismos operativos:
En el entorno Win16, los datos globales de la DLL son los mismos para cada proceso que la carga en el entorno Win32, la situación ha cambiado; Cualquier objeto (incluidas las variables) creado por el código en la función DLL es propiedad del hilo o proceso que lo llama. Cuando un proceso carga una DLL, el sistema operativo asigna automáticamente la dirección de la DLL al espacio privado del proceso, que es el espacio de direcciones virtuales del proceso, y también copia una copia de los datos globales de la DLL al espacio del proceso. Es decir, los datos globales de la misma DLL propiedad de cada proceso tienen el mismo nombre, pero su valor no es necesariamente el mismo y no interfieren entre sí.
Por lo tanto, si desea compartir datos entre múltiples procesos en un entorno Win32, debe realizar las configuraciones necesarias. Compartir memoria entre procesos que acceden al mismo DLL se logra mediante la tecnología de archivos mapeados en memoria. También puede separar los datos que deben compartirse, colocarlos en un segmento de datos independiente y establecer el atributo del segmento en compartido. A estas variables se les deben asignar valores iniciales; de lo contrario, el compilador colocará las variables sin valores iniciales en un segmento de datos llamado no inicializado.
La directiva de preprocesamiento #pragma data_seg se utiliza para configurar el segmento de datos compartidos. Por ejemplo:
#pragma data_seg("SharedDataName")
HHOOK hHook=NULL
#pragma data_seg()
en; # Todas las variables entre pragma data_seg("SharedDataName") y #pragma data_seg() serán vistas y compartidas por todos los procesos que accedan a la Dll. Junto con una instrucción #pragma comment(linker, "/section:.SharedDataName, rws"), los datos de esta sección de datos se pueden compartir entre todas las instancias de la DLL. Todas las operaciones con estos datos se realizan en la misma instancia, en lugar de tener una copia en el espacio de direcciones de cada proceso.
Cuando un proceso llama implícita o explícitamente a una función en una biblioteca dinámica, el sistema debe asignar la biblioteca dinámica al espacio de direcciones virtuales del proceso (en lo sucesivo, "espacio de direcciones"). Esto hace que la DLL forme parte del proceso, ejecutándose como ese proceso, utilizando la pila del proceso.
4. Ganchos del sistema y ganchos de hilo:
El último parámetro de la función SetWindowsHookEx() determina si el gancho es un gancho del sistema o un gancho de hilo.
Los ganchos de subprocesos se utilizan para monitorear mensajes de eventos de subprocesos específicos. Los ganchos de hilo generalmente están dentro del hilo actual o en un hilo derivado del hilo actual.
Los enlaces del sistema monitorean los mensajes de eventos de todos los hilos del sistema. Debido a que los enlaces del sistema afectan a todas las aplicaciones del sistema, la función de enlace debe colocarse en una biblioteca de vínculos dinámicos (DLL) separada. El sistema asigna automáticamente la DLL que contiene la "función de devolución de llamada de enlace" al espacio de direcciones de todos los procesos afectados por la función de enlace, es decir, inyecta esta DLL en esos procesos.
Algunas notas:
(1) Si tanto los ganchos de hilo como los ganchos del sistema están instalados para el mismo evento (como un mensaje del mouse), el sistema llamará automáticamente al primer gancho de hilo. y luego llame al enlace del sistema.
(2) Se pueden instalar múltiples procesos de procesamiento de enlaces para el mismo mensaje de evento, y estos procesos de procesamiento de enlaces forman una cadena de enlaces.
Una vez completado el procesamiento del enlace actual, la información del enlace debe pasarse a la siguiente función del enlace.
(3) Los ganchos, especialmente los ganchos del sistema, consumirán tiempo de procesamiento de mensajes y reducirán el rendimiento del sistema. Instale ganchos sólo cuando sea necesario y desinstálelos inmediatamente después de su uso.
------------------------------------------------- ---- -------------------------------------
Tipo de gancho
Cada tipo de Hook permite a las aplicaciones monitorear diferentes tipos de mecanismos de procesamiento de mensajes del sistema. Todos los tipos de ganchos disponibles se describen a continuación.
1. Hooks WH_CALLWNDPROC y WH_CALLWNDPROCRET
Los Hooks WH_CALLWNDPROC y WH_CALLWNDPROCRET le permiten monitorear los mensajes enviados al proceso de ventana. El sistema llama a la subrutina Hook WH_CALLWNDPROC antes de que el mensaje se envíe al procedimiento de ventana de recepción y llama a la subrutina Hook WH_CALLWNDPROCRET después de que el procedimiento de ventana haya procesado el mensaje.
WH_CALLWNDPROCRET Hook pasa el puntero a la estructura CWPRETSTRUCT y luego lo pasa a la subrutina Hook.
La estructura CWPRETSTRUCT contiene el valor de retorno del procedimiento de ventana que procesó el mensaje, así como los parámetros del mensaje asociados con el mensaje.
2. WH_CBT Hook
El sistema llamará a la subrutina WH_CBT Hook antes de los siguientes eventos. Estos eventos incluyen:
1. Activación, creación, destrucción. Minimizar, maximizar, mover, cambiar tamaño y otros eventos de ventana;
2. Completar instrucciones del sistema;
3. Mover eventos de mouse y teclado de la cola de mensajes del sistema;
p>
4. Establezca el evento de enfoque de entrada;
5. Sincronice el evento de la cola de mensajes del sistema.
El valor de retorno de la subrutina Hook determina si el sistema permite o impide una de estas operaciones.
3. Hook WH_DEBUG
Antes de que el sistema llame a la subrutina Hook asociada con otros Hooks en el sistema, el sistema llamará a la subrutina Hook WH_DEBUG. Puede utilizar este Hook para decidir si permite que el sistema llame a subrutinas de Hook asociadas con otros Hooks.
4. Gancho WH_FOREGROUNDIDLE
Cuando el hilo de primer plano de la aplicación está inactivo, puede utilizar el gancho WH_FOREGROUNDIDLE para realizar tareas de baja prioridad. Cuando el subproceso de primer plano de la aplicación esté a punto de quedar inactivo, el sistema llamará a la subrutina Hook WH_FOREGROUNDIDLE.
5. Hook WH_GETMESSAGE
La aplicación utiliza el Hook WH_GETMESSAGE para monitorear los mensajes devueltos por la función GetMessage o PeekMessage. Puede utilizar el gancho WH_GETMESSAGE para monitorear la entrada del mouse y el teclado, así como otros mensajes enviados a la cola de mensajes.
6. Gancho WH_JOURNALPLAYBACK
El gancho WH_JOURNALPLAYBACK permite a las aplicaciones insertar mensajes en la cola de mensajes del sistema. Puede utilizar este gancho para reproducir eventos consecutivos de mouse y teclado grabados usando el gancho WH_JOURNALRECORD.
Mientras el gancho WH_JOURNALPLAYBACK esté instalado, los eventos normales de mouse y teclado no son válidos.
WH_JOURNALPLAYBACK El gancho es un gancho global y no se puede utilizar como un gancho específico de un subproceso.
WH_JOURNALPLAYBACK Hook devuelve un valor de tiempo de espera, que le indica al sistema cuánto tiempo (milisegundos) necesita esperar antes de procesar el mensaje actual desde el Hook de reproducción. Esto permite a Hooks controlar la reproducción de eventos en tiempo real.
WH_JOURNALPLAYBACK son enlaces locales para todo el sistema, no se inyectarán en ningún espacio de direcciones de viaje.
7. Gancho WH_JOURNALRECORD
El gancho WH_JOURNALRECORD se utiliza para monitorear y registrar eventos de entrada. Normalmente, puede utilizar este gancho para grabar eventos continuos del mouse y el teclado y luego reproducirlos usando el gancho WH_JOURNALPLAYBACK.
WH_JOURNALRECORD Hook es un Hook global y no se puede utilizar como un Hook específico de un hilo.
WH_JOURNALRECORD son enlaces locales para todo el sistema, no se inyectarán en ningún espacio de direcciones de viaje.
8. Hook WH_KEYBOARD
En la aplicación, el Hook WH_KEYBOARD se utiliza para monitorear los mensajes WM_KEYDOWN y WM_KEYUP, que se devuelven a través de la función GetMessage o PeekMessage. Puede utilizar este gancho para monitorear los mensajes del teclado ingresados en la cola de mensajes.
9. WH_KEYBOARD_LL Hook
WH_KEYBOARD_LL Hook monitorea la entrada de mensajes del teclado en la cola de mensajes del hilo.
10. WH_MOUSE Hook
WH_MOUSE Hook monitorea los mensajes del mouse devueltos por la función GetMessage o PeekMessage. Utilice este gancho para monitorear la entrada de mensajes del mouse a la cola de mensajes.
11. Hook WH_MOUSE_LL
Hook WH_MOUSE_LL monitorea la entrada de mensajes del mouse a la cola de mensajes del hilo.
12. Hooks WH_MSGFILTER y WH_SYSMSGFILTER
Los Hooks WH_MSGFILTER y WH_SYSMSGFILTER nos permiten monitorear menús, barras de desplazamiento, cuadros de mensajes, mensajes de diálogo y descubrir que los usuarios usan la tecla ALT TAB o ALT ESC combinaciones Cambiar ventanas. WH_MSGFILTER Hook solo puede monitorear mensajes pasados a menús, barras de desplazamiento, cuadros de mensajes y mensajes pasados a cuadros de diálogo creados por aplicaciones que tienen instalada la subrutina Hook. WH_SYSMSGFILTER Hook monitorea todos los mensajes de la aplicación.
Los Hooks WH_MSGFILTER y WH_SYSMSGFILTER nos permiten filtrar mensajes durante el bucle de patrón, lo que equivale a filtrar mensajes en el bucle de mensajes principal.
El gancho WH_MSGFILTER se puede llamar directamente llamando a la función CallMsgFilter. Al usar esta función, la aplicación puede usar el mismo código para filtrar mensajes durante el bucle de patrón que en el bucle de mensajes principal.
13. WH_SHELL Hook
Las aplicaciones Shell pueden usar WH_SHELL Hook para recibir notificaciones importantes. Cuando la aplicación de shell está activa y cuando se crea o destruye la ventana de nivel superior, el sistema llama a la subrutina Hook WH_SHELL.
WH_SHELL ***Hay 5 situaciones:
1. Siempre que se cree, active o destruya una ventana de nivel superior sin propietario
; 2. Cuando la barra de tareas necesita volver a dibujar un botón;
3. Cuando el sistema necesita mostrar una forma minimizada de un programa en la barra de tareas
4. Cuando cambia el estado de la distribución del teclado; ;
5. Cuando el usuario presiona Ctrl Esc para ejecutar el Administrador de tareas (o un programa del mismo nivel).
Por convención, las aplicaciones shell no reciben mensajes WH_SHELL. Por lo tanto, antes de que la aplicación pueda recibir el mensaje WH_SHELL, la aplicación debe llamar a la función SystemParametersInfo para registrarse.
Usar prototipo:
SetWindowsHookEx(WH_KEYBOARD, KeyBoardProc, HInstance, 0);