Partager via


Vue d’ensemble des hooks

Un hook est un mécanisme par lequel une application peut intercepter des événements, tels que des messages, des actions de souris et des séquences de touches. Une fonction qui intercepte un type particulier d’événement est appelée procédure de hook. Une procédure de hook peut agir sur chaque événement qu’elle reçoit, puis modifier ou ignorer l’événement.

Voici quelques exemples d’utilisations pour les hooks :

  • Surveiller les messages à des fins de débogage
  • Prendre en charge l’enregistrement et la lecture des macros
  • Fournir un support pour la touche d'aide (F1)
  • Simuler l’entrée de la souris et du clavier
  • Implémenter une application de formation basée sur ordinateur (CBT)

Remarque

Les crochets ont tendance à ralentir le système, car ils augmentent la quantité de traitement que le système doit effectuer pour chaque message. Vous devez installer un hook uniquement si nécessaire et le supprimer dès que possible.

 

Cette section décrit les éléments suivants :

Chaînes à crochets

Le système prend en charge de nombreux types de hooks ; chaque type donne accès à différents aspects de leur mécanisme de gestion des messages. Par exemple, une application peut utiliser le hook WH_MOUSE pour surveiller le trafic de messages pour les messages de souris.

Le système gère une chaîne de crochets distincte pour chaque type de crochet. Une chaîne de crochets est une liste de pointeurs vers des fonctions de rappel spéciales définies par l'application, appelées procédures de crochets. Lorsqu’un message se produit associé à un type particulier de crochet, le système transmet le message à chaque procédure de raccordement référencée dans la chaîne de crochets, l’une après l’autre. L’action qu’une procédure de raccordement peut prendre dépend du type de crochet impliqué. Les procédures de raccordement pour certains types de hooks ne peuvent surveiller que les messages ; d’autres peuvent modifier des messages ou arrêter leur progression par le biais de la chaîne, ce qui les empêche d’atteindre la procédure de raccordement suivante ou la fenêtre de destination.

Procédures Hook

Pour tirer parti d’un type particulier de hook, le développeur fournit une procédure de hook et utilise la fonction SetWindowsHookEx pour l’installer dans la chaîne associée au crochet. Une procédure de hook doit avoir la syntaxe suivante :

LRESULT CALLBACK HookProc(
  int nCode, 
  WPARAM wParam, 
  LPARAM lParam
)
{
   // process event
   ...

   return CallNextHookEx(NULL, nCode, wParam, lParam);
}

HookProc est un espace réservé pour un nom défini par l’application.

Le paramètre nCode est un code de hook que la procédure de hook utilise pour déterminer l’action à effectuer. La valeur du code de hook dépend du type du hook ; chaque type a son propre ensemble caractéristique de codes de crochet. Les valeurs des paramètres wParam et lParam dépendent du code de hook, mais elles contiennent généralement des informations sur un message envoyé ou publié.

La fonction SetWindowsHookEx installe toujours une procédure hook au début d’une chaîne hook. Lorsqu’un événement se produit qui est surveillé par un type particulier de crochet, le système appelle la procédure au début de la chaîne de crochet associée au crochet. Chaque procédure hook dans la chaîne détermine s’il faut passer l’événement à la procédure suivante. Une procédure de hook transmet un événement à la procédure suivante en appelant la fonction CallNextHookEx .

Notez que les procédures hook pour certains types de hook peuvent uniquement surveiller les messages. Le système transmet les messages à chaque procédure hook, qu'une procédure particulière appelle ou non CallNextHookEx.

Un hook global surveille les messages pour tous les threads du même bureau que le thread appelant. Un hook spécifique au thread surveille les messages d’un thread individuel uniquement. Une procédure de hook globale peut être appelée dans le contexte de n’importe quelle application du même bureau que le thread appelant, de sorte que la procédure doit se trouver dans un module DLL distinct. Une procédure de hook spécifique au thread est appelée uniquement dans le contexte du thread associé. Si une application installe une procédure de hook pour l’un de ses propres threads, la procédure de hook peut se trouver dans le même module que le reste du code de l’application ou dans une DLL. Si l’application installe une procédure de hook pour un thread d’une autre application, la procédure doit se trouver dans une DLL. Pour plus d’informations, consultez Dynamic-Link bibliothèques.

Remarque

Veuillez utiliser les hooks globaux uniquement à des fins de débogage ; dans tous les autres cas, il est recommandé de les éviter. Les hooks globaux nuisent aux performances du système et provoquent des conflits avec d’autres applications qui implémentent le même type de hook global.

 

Types Hook

Chaque type de hook permet à une application de surveiller un aspect différent du mécanisme de gestion des messages du système. Les sections suivantes décrivent les hooks disponibles.

WH_CALLWNDPROC et WH_CALLWNDPROCRET

Les WH_CALLWNDPROCet WH_CALLWNDPROCRET hooks vous permettent de surveiller les messages envoyés aux procédures de fenêtre. Le système appelle une procédure de raccordement WH_CALLWNDPROC avant de transmettre le message à la procédure de fenêtre de réception et appelle la procédure de raccordement WH_CALLWNDPROCRET une fois la procédure de fenêtre traitée.

Le hook WH_CALLWNDPROCRET passe un pointeur vers une structure CWPRETSTRUCT à la procédure hook. La structure contient la valeur de retour de la procédure de fenêtre qui a traité le message, ainsi que les paramètres de message associés au message. La sous-classe de la fenêtre ne fonctionne pas pour les messages définis entre les processus.

Pour plus d’informations, consultez les fonctions de rappel CallWndProc et CallWndRetProc .

WH_CBT

Le système appelle une procédure de raccordement WH_CBT avant d’activer, de créer, de détruire, de minimiser, d’optimiser, de déplacer ou de dimensionner une fenêtre ; avant de terminer une commande système ; avant de supprimer un événement de souris ou de clavier de la file d’attente des messages système ; avant de définir le focus d’entrée ; ou avant la synchronisation avec la file d’attente de messages système. La valeur renvoyée par la procédure de raccordement détermine si le système autorise ou empêche l’une de ces opérations. Le WH_CBT hook est destiné principalement aux applications de formation basée sur ordinateur (CBT).

Pour plus d’informations, consultez la fonction de rappel CBTProc .

Pour plus d’informations, consultez WinEvents.

WH_DEBUG

Le système appelle une procédure hook WH_DEBUG avant d'appeler des procédures hook associées à n'importe quel autre hook dans le système. Vous pouvez utiliser ce point d'interception pour déterminer s’il faut autoriser le système à appeler des procédures d'interception associées à d'autres types de points d'interception.

Pour plus d’informations, consultez la fonction de rappel DebugProc .

WH_FOREGROUNDIDLE

Le hook WH_FOREGROUNDIDLE vous permet d’effectuer des tâches de faible priorité pendant les moments où son thread de premier plan est inactif. Le système appelle une procédure de raccordement WH_FOREGROUNDIDLE lorsque le thread de premier plan de l’application est sur le point de devenir inactif.

Pour plus d’informations, consultez la fonction de rappel ForegroundIdleProc .

WH_GETMESSAGE

Le hook WH_GETMESSAGE permet à une application de surveiller les messages sur le point d’être retournés par la fonction GetMessage ou PeekMessage . Vous pouvez utiliser la fonction hook WH_GETMESSAGE pour surveiller l’entrée de la souris et du clavier ainsi que d'autres messages envoyés à la file d'attente des messages.

Pour plus d’informations, consultez la fonction de rappel GetMsgProc .

WH_JOURNALPLAYBACK

Avertissement

Les API Hooks de journalisation ne sont plus prises en charge à partir de Windows 11 et seront supprimées dans une version ultérieure. Pour cette raison, nous vous recommandons vivement d'utiliser plutôt l'API SendInput TextInput.

Le hook WH_JOURNALPLAYBACK permet à une application d’insérer des messages dans la file d’attente des messages système. Vous pouvez utiliser ce hook pour lire une série d’événements de souris et de clavier enregistrés précédemment en utilisant WH_JOURNALRECORD. Les entrées standard de la souris et du clavier sont désactivées pendant qu'une accroche WH_JOURNALPLAYBACK est installée. Un WH_JOURNALPLAYBACK hook est un hook global. Il ne peut pas être utilisé comme hook spécifique au thread.

Le hook WH_JOURNALPLAYBACK retourne une valeur de délai d’attente. Cette valeur indique au système le nombre de millisecondes à attendre avant de traiter le message actuel à partir du hook de lecture. Cela permet au hook de gérer la synchronisation des événements qu’il lit.

Pour plus d’informations, consultez la fonction de rappel JournalPlaybackProc .

WH_JOURNALRECORD

Avertissement

Les API Hooks de journalisation ne sont plus prises en charge à partir de Windows 11 et seront supprimées dans une version ultérieure. Pour cette raison, nous vous recommandons vivement d'utiliser plutôt l'API SendInput TextInput.

Le hook WH_JOURNALRECORD vous permet de surveiller et d’enregistrer les événements d’entrée. En règle générale, vous utilisez ce hook pour enregistrer une séquence d’événements de souris et de clavier pour une lecture ultérieure à l’aide de WH_JOURNALPLAYBACK. Le WH_JOURNALRECORD hook est un hook global. Il ne peut pas être utilisé comme hook spécifique au thread.

Pour plus d’informations, consultez la fonction de rappel JournalRecordProc .

WH_KEYBOARD_LL

Le hook WH_KEYBOARD_LL vous permet de contrôler les événements d’entrée clavier sur le point d’être publiés dans une file d’attente d’entrée de thread.

Pour plus d’informations, consultez la fonction de rappel LowLevelKeyboardProc .

WH_KEYBOARD

Le hook WH_KEYBOARD permet à une application de surveiller le trafic des messages pour WM_KEYDOWN et de WM_KEYUP les messages sur le point d’être retournés par la fonction GetMessage ou PeekMessage . Vous pouvez utiliser le hook WH_KEYBOARD pour surveiller l'entrée du clavier envoyée à une file de messages.

Pour plus d’informations, consultez la fonction de rappel KeyboardProc .

WH_MOUSE_LL

Le hook WH_MOUSE_LL vous permet de contrôler les événements d’entrée souris sur le point d’être publiés dans une file d’attente d’entrée de thread.

Pour plus d’informations, consultez la fonction de rappel LowLevelMouseProc .

WH_MOUSE

Le hook WH_MOUSE vous permet de surveiller les messages de souris sur le point d’être retournés par la fonction GetMessage ou PeekMessage . Vous pouvez utiliser le hook WH_MOUSE pour contrôler l’entrée de la souris transmise à une file d'attente de messages.

Pour plus d’informations, consultez la fonction de rappel MouseProc .

WH_MSGFILTER et WH_SYSMSGFILTER

Les hooks WH_MSGFILTER et WH_SYSMSGFILTER vous permettent de surveiller les messages sur le point d'être traités par un menu, une barre de défilement, une boîte de message ou une boîte de dialogue, et de détecter lorsqu'une autre fenêtre est sur le point d'être activée à la suite de l'appui de l'utilisateur sur la combinaison de touches ALT+TAB ou ALT+ESC. Le WH_MSGFILTER hook ne peut surveiller que les messages transmis à un menu, une barre de défilement, une boîte de message ou une boîte de dialogue créée par l’application qui a installé la procédure de hook. Le WH_SYSMSGFILTER hook surveille ces messages pour toutes les applications.

Les WH_MSGFILTERet WH_SYSMSGFILTER hooks vous permettent d’effectuer le filtrage des messages pendant les boucles modales équivalentes au filtrage effectué dans la boucle de message principale. Par exemple, une application examine souvent un nouveau message dans la boucle principale entre le moment où il récupère le message de la file d’attente et le moment où il distribue le message, effectuant un traitement spécial selon les besoins. Toutefois, pendant une boucle modale, le système récupère et distribue des messages sans permettre à une application de filtrer les messages dans sa boucle de message principale. Si une application installe une procédure de raccordement WH_MSGFILTER ou WH_SYSMSGFILTER , le système appelle la procédure pendant la boucle modale.

Une application peut appeler directement le hook WH_MSGFILTER en appelant la fonction CallMsgFilter . À l’aide de cette fonction, l’application peut utiliser le même code pour filtrer les messages pendant les boucles modales qu’elle utilise dans la boucle de message principale. Pour ce faire, encapsulez les opérations de filtrage dans une procédure de hook WH_MSGFILTER et appelez CallMsgFilter entre les appels aux fonctions GetMessage et DispatchMessage .

while (GetMessage(&msg, (HWND) NULL, 0, 0)) 
{ 
    if (!CallMsgFilter(&qmsg, 0)) 
        DispatchMessage(&qmsg); 
} 

Le dernier argument de CallMsgFilter est simplement passé à la procédure de hook ; vous pouvez entrer n’importe quelle valeur. La procédure de raccordement, en définissant une constante telle que MSGF_MAINLOOP, peut utiliser cette valeur pour déterminer où la procédure a été appelée.

Pour plus d’informations, consultez les fonctions de rappel MessageProc et SysMsgProc .

WH_SHELL

Une application shell peut utiliser le hook WH_SHELL pour recevoir des notifications importantes. Le système appelle une procédure de raccordement WH_SHELL lorsque l’application shell est sur le point d’être activée et lorsqu’une fenêtre de niveau supérieur est créée ou détruite.

Notez que les applications shell personnalisées ne reçoivent pas de messages WH_SHELL . Par conséquent, toute application qui s’inscrit en tant qu’interpréteur de commandes par défaut doit appeler la fonction SystemParametersInfo avant qu’elle (ou toute autre application) puisse recevoir des messages WH_SHELL . Cette fonction doit être appelée avec SPI_SETMINIMIZEDMETRICS et une structure MINIMIZEDMETRICS . Définissez le membre iArrange de cette structure à ARW_HIDE.

Pour plus d’informations, consultez la fonction de rappel ShellProc .