Introducción a los enlaces
Un enlace es un mecanismo por el que una aplicación puede interceptar eventos, como mensajes, acciones del mouse y pulsaciones de tecla. Una función que intercepta un tipo determinado de evento se conoce como procedimiento de enlace. Un procedimiento de enlace puede actuar en cada evento que recibe y, a continuación, modificar o descartar el evento.
En el ejemplo siguiente se usa para enlaces:
- Supervisión de mensajes con fines de depuración
- Proporcionar compatibilidad con la grabación y reproducción de macros
- Proporcionar compatibilidad con una clave de ayuda (F1)
- Simular la entrada del mouse y el teclado
- Implementación de una aplicación de entrenamiento basado en equipos (CBT)
Nota
Los enlaces tienden a ralentizar el sistema porque aumentan la cantidad de procesamiento que el sistema debe realizar para cada mensaje. Debe instalar un enlace solo cuando sea necesario y quitarlo lo antes posible.
En esta sección se describe lo siguiente:
Cadenas de gancho
El sistema admite muchos tipos diferentes de ganchos; cada tipo proporciona acceso a un aspecto diferente de su mecanismo de control de mensajes. Por ejemplo, una aplicación puede usar el enlace de WH_MOUSE para supervisar el tráfico del mensaje de los mensajes del mouse.
El sistema mantiene una cadena de enlace independiente para cada tipo de gancho. Una cadena de enlace es una lista de punteros a funciones de devolución de llamada especiales definidas por la aplicación denominadas procedimientos de enlace. Cuando se produce un mensaje asociado a un tipo determinado de enlace, el sistema pasa el mensaje a cada procedimiento de enlace al que se hace referencia en la cadena de enlace, uno después del otro. La acción que puede realizar un procedimiento de enlace depende del tipo de enlace implicado. Los procedimientos de enlace para algunos tipos de enlaces solo pueden supervisar los mensajes; otros pueden modificar los mensajes o detener su progreso a través de la cadena, lo que impide que lleguen al siguiente procedimiento de enlace o a la ventana de destino.
Procedimientos de enlace
Para aprovechar un tipo determinado de enlace, el desarrollador proporciona un procedimiento de enlace y usa la función SetWindowsHookEx para instalarlo en la cadena asociada al enlace. Un procedimiento de enlace debe tener la sintaxis siguiente:
LRESULT CALLBACK HookProc(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
// process event
...
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
HookProc es un marcador de posición para un nombre definido por la aplicación.
El parámetro nCode es un código de enlace que el procedimiento de enlace usa para determinar la acción que se va a realizar. El valor del código de enlace depende del tipo del enlace; cada tipo tiene su propio conjunto de características de códigos de enlace. Los valores de los parámetros wParam y lParam dependen del código de enlace, pero normalmente contienen información sobre un mensaje enviado o publicado.
La función SetWindowsHookEx siempre instala un procedimiento de enlace al principio de una cadena de enlace. Cuando se produce un evento supervisado por un tipo determinado de enlace, el sistema llama al procedimiento al principio de la cadena de enlace asociada al enlace. Cada procedimiento de enlace de la cadena determina si se debe pasar el evento al siguiente procedimiento. Un procedimiento de enlace pasa un evento al siguiente procedimiento llamando a la función CallNextHookEx .
Tenga en cuenta que los procedimientos de enlace para algunos tipos de enlaces solo pueden supervisar los mensajes. el sistema pasa mensajes a cada procedimiento de enlace, independientemente de si un procedimiento determinado llama a CallNextHookEx.
Un enlace global supervisa los mensajes de todos los subprocesos del mismo escritorio que el subproceso que realiza la llamada. Un enlace específico del subproceso supervisa los mensajes solo para un subproceso individual. Se puede llamar a un procedimiento de enlace global en el contexto de cualquier aplicación del mismo escritorio que el subproceso que llama, por lo que el procedimiento debe estar en un módulo DLL independiente. Solo se llama a un procedimiento de enlace específico del subproceso en el contexto del subproceso asociado. Si una aplicación instala un procedimiento de enlace para uno de sus propios subprocesos, el procedimiento de enlace puede estar en el mismo módulo que el resto del código de la aplicación o en un archivo DLL. Si la aplicación instala un procedimiento de enlace para un subproceso de otra aplicación, el procedimiento debe estar en un archivo DLL. Para obtener información, consulte Bibliotecas de vínculos dinámicos.
Nota
Debe usar enlaces globales solo con fines de depuración; de lo contrario, debe evitarlos. Los enlaces globales dañan el rendimiento del sistema y provocan conflictos con otras aplicaciones que implementan el mismo tipo de enlace global.
Tipos de enlace
Cada tipo de enlace permite a una aplicación supervisar un aspecto diferente del mecanismo de control de mensajes del sistema. En las secciones siguientes se describen los enlaces disponibles.
- WH_CALLWNDPROC y WH_CALLWNDPROCRET
- WH_CBT
- WH_DEBUG
- WH_FOREGROUNDIDLE
- WH_GETMESSAGE
- WH_JOURNALPLAYBACK
- WH_JOURNALRECORD
- WH_KEYBOARD_LL
- WH_KEYBOARD
- WH_MOUSE_LL
- WH_MOUSE
- WH_MSGFILTER y WH_SYSMSGFILTER
- WH_SHELL
WH_CALLWNDPROC y WH_CALLWNDPROCRET
Los enlaces WH_CALLWNDPROC y WH_CALLWNDPROCRET permiten supervisar los mensajes enviados a procedimientos de ventana. El sistema llama a un procedimiento de enlace WH_CALLWNDPROC antes de pasar el mensaje al procedimiento de ventana receptora y llama al procedimiento de enlace WH_CALLWNDPROCRET después de que el procedimiento de ventana haya procesado el mensaje.
El enlace WH_CALLWNDPROCRET pasa un puntero a una estructura CWPRETSTRUCT al procedimiento de enlace. La estructura contiene el valor devuelto del procedimiento de ventana que procesó el mensaje, así como los parámetros del mensaje asociados al mensaje. La subclase de la ventana no funciona para los mensajes establecidos entre procesos.
Para obtener más información, consulte las funciones callWndProc y CallWndRetProc .
WH_CBT
El sistema llama a un procedimiento de enlace WH_CBT antes de activar, crear, destruir, minimizar, maximizar, mover o ajustar el tamaño de una ventana; antes de completar un comando del sistema; antes de quitar un evento de mouse o teclado de la cola de mensajes del sistema; antes de establecer el foco de entrada; o antes de sincronizar con la cola de mensajes del sistema. El valor que devuelve el procedimiento de enlace determina si el sistema permite o impide una de estas operaciones. El enlace de WH_CBT está pensado principalmente para aplicaciones de entrenamiento basadas en equipos (CBT).
Para obtener más información, consulte la función de devolución de llamada CBTProc .
Para obtener información, consulte WinEvents.
WH_DEBUG
El sistema llama a un procedimiento de enlace WH_DEBUG antes de llamar a procedimientos de enlace asociados a cualquier otro enlace del sistema. Puede usar este enlace para determinar si el sistema debe llamar a procedimientos de enlace asociados a otros tipos de enlaces.
Para obtener más información, consulte la función de devolución de llamada DepurarProc .
WH_FOREGROUNDIDLE
El enlace de WH_FOREGROUNDIDLE permite realizar tareas de prioridad baja durante los tiempos en que su subproceso en primer plano está inactivo. El sistema llama a un procedimiento de enlace de WH_FOREGROUNDIDLE cuando el subproceso en primer plano de la aplicación está a punto de estar inactivo.
Para obtener más información, consulte la función de devolución de llamada ForegroundIdleProc .
WH_GETMESSAGE
El enlace de WH_GETMESSAGE permite a una aplicación supervisar los mensajes que va a devolver la función GetMessage o PeekMessage . Puede usar el enlace de WH_GETMESSAGE para supervisar la entrada del mouse y el teclado y otros mensajes publicados en la cola de mensajes.
Para obtener más información, consulte la función de devolución de llamada GetMsgProc .
WH_JOURNALPLAYBACK
Advertencia
Las API de enlaces de registro en diario no se admiten a partir de Windows 11 y se quitarán en una versión futura. Por este motivo, se recomienda encarecidamente llamar a la API SendInput TextInput en su lugar.
El enlace WH_JOURNALPLAYBACK permite que una aplicación inserte mensajes en la cola de mensajes del sistema. Puede usar este enlace para reproducir una serie de eventos de mouse y teclado grabados anteriormente mediante WH_JOURNALRECORD. La entrada normal del mouse y del teclado está deshabilitada siempre que se instale un enlace de WH_JOURNALPLAYBACK . Un enlace de WH_JOURNALPLAYBACK es un enlace global; no se puede usar como un enlace específico del subproceso.
El enlace WH_JOURNALPLAYBACK devuelve un valor de tiempo de espera. Este valor indica al sistema cuántos milisegundos esperar antes de procesar el mensaje actual desde el enlace de reproducción. Esto permite que el enlace controle el tiempo de los eventos que reproduce.
Para obtener más información, consulte la función de devolución de llamada JournalPlaybackProc .
WH_JOURNALRECORD
Advertencia
Las API de enlaces de registro en diario no se admiten a partir de Windows 11 y se quitarán en una versión futura. Por este motivo, se recomienda encarecidamente llamar a la API SendInput TextInput en su lugar.
El enlace WH_JOURNALRECORD permite supervisar y registrar eventos de entrada. Normalmente, se usa este enlace para grabar una secuencia de eventos de mouse y teclado para reproducirlos más adelante mediante WH_JOURNALPLAYBACK. El WH_JOURNALRECORD enlace es un enlace global; no se puede usar como un enlace específico del subproceso.
Para obtener más información, consulte la función de devolución de llamada JournalRecordProc .
WH_KEYBOARD_LL
El enlace de WH_KEYBOARD_LL permite supervisar los eventos de entrada del teclado sobre cómo publicarse en una cola de entrada de subprocesos.
Para obtener más información, consulte la función de devolución de llamada LowLevelKeyboardProc .
WH_KEYBOARD
El enlace de WH_KEYBOARD permite a una aplicación supervisar el tráfico de mensajes para WM_KEYDOWN y WM_KEYUP mensajes a punto de devolverlos la función GetMessage o PeekMessage . Puede usar el enlace de WH_KEYBOARD para supervisar la entrada del teclado publicada en una cola de mensajes.
Para obtener más información, consulte la función de devolución de llamada KeyboardProc .
WH_MOUSE_LL
El enlace de WH_MOUSE_LL permite supervisar los eventos de entrada del mouse sobre cómo publicarse en una cola de entrada de subprocesos.
Para obtener más información, consulte la función de devolución de llamada LowLevelMouseProc .
WH_MOUSE
El enlace WH_MOUSE permite supervisar los mensajes del mouse a punto de devolverlos la función GetMessage o PeekMessage . Puede usar el enlace de WH_MOUSE para supervisar la entrada del mouse publicada en una cola de mensajes.
Para obtener más información, consulte la función de devolución de llamada MouseProc .
WH_MSGFILTER y WH_SYSMSGFILTER
Los enlaces de WH_MSGFILTER y WH_SYSMSGFILTER permiten supervisar los mensajes a punto de ser procesados por un menú, barra de desplazamiento, cuadro de mensaje o cuadro de diálogo, y para detectar cuándo una ventana diferente está a punto de activarse como resultado de presionar la combinación de teclas ALT+TAB o ALT+ESC. El enlace de WH_MSGFILTER solo puede supervisar los mensajes pasados a un menú, barra de desplazamiento, cuadro de mensaje o cuadro de diálogo creados por la aplicación que instaló el procedimiento de enlace. El enlace WH_SYSMSGFILTER supervisa estos mensajes para todas las aplicaciones.
Los enlaces WH_MSGFILTER y WH_SYSMSGFILTER permiten realizar el filtrado de mensajes durante bucles modales equivalentes al filtrado realizado en el bucle de mensajes principal. Por ejemplo, una aplicación suele examinar un nuevo mensaje en el bucle principal entre el momento en que recupera el mensaje de la cola y la hora en que envía el mensaje, realizando un procesamiento especial según corresponda. Sin embargo, durante un bucle modal, el sistema recupera y envía mensajes sin permitir que una aplicación pueda filtrar los mensajes en su bucle de mensajes principal. Si una aplicación instala un procedimiento de enlace de WH_MSGFILTER o WH_SYSMSGFILTER , el sistema llama al procedimiento durante el bucle modal.
Una aplicación puede llamar directamente al enlace WH_MSGFILTER llamando a la función CallMsgFilter . Mediante este uso de esta función, la aplicación puede usar el mismo código para filtrar los mensajes durante los bucles modales que usa en el bucle de mensajes principal. Para ello, encapsula las operaciones de filtrado en un procedimiento de enlace de WH_MSGFILTER y llama a CallMsgFilter entre las llamadas a las funciones GetMessage y DispatchMessage .
while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
if (!CallMsgFilter(&qmsg, 0))
DispatchMessage(&qmsg);
}
El último argumento de CallMsgFilter se pasa simplemente al procedimiento de enlace; puede escribir cualquier valor. El procedimiento de enlace, mediante la definición de una constante como MSGF_MAINLOOP, puede usar este valor para determinar desde dónde se llamó al procedimiento.
Para obtener más información, consulte las funciones de devolución de llamada MessageProc y SysMsgProc .
WH_SHELL
Una aplicación de shell puede usar el enlace de WH_SHELL para recibir notificaciones importantes. El sistema llama a un procedimiento de enlace de WH_SHELL cuando la aplicación de shell está a punto de activarse y cuando se crea o destruye una ventana de nivel superior.
Tenga en cuenta que las aplicaciones de shell personalizadas no reciben mensajes WH_SHELL . Por lo tanto, cualquier aplicación que se registre como shell predeterminado debe llamar a la función SystemParametersInfo antes de que (o cualquier otra aplicación) pueda recibir mensajes WH_SHELL . Se debe llamar a esta función con SPI_SETMINIMIZEDMETRICS y una estructura MINIMIZEDMETRICS . Establezca el miembro iArrange de esta estructura en ARW_HIDE.
Para obtener más información, consulte la función de devolución de llamada ShellProc .