System-wide hook | System-wide hook |
1. What is a hook? | Qu'est-ce qu'un hook? |
A
hook is a mechanism we can use to
monitor windows messages before they reach the target window. This
allows us to intercept messages and perform a certain task before they
are treated by the window. For a global hook the code must be placed in a DLL. For an application hook, it is not required. To install a hook, we use SetWindowsHookEx(), specifying the type of the hook and a callback procedure. To release the hook, we call UnhookWindowsHookEx(), specifying the hook handle of the early created hook. SetWindowsHookEx() add the hook to a chain. The hook procedure can call the next hook in the chain or not. It depends on our needs. |
Un hook est un
système qui
permet d'intercepter les messages que Windows envoie aux fenêtres
avant qu'ils ne soient traiter par la fenêtre. Le code du hook doit être placé dans une DLL si le hook est global. Ceci n'est pas nécessaire si le hook ne concerne qu'une application. Pour installer un hook, on appelle la fonction de l'API SetWindowsHookEx() en spécifiant un type de hook et une procédure de callback. Pour supprimer un hook, on appelle la fonction UnhookWindowsHookEx() en lui donnant en paramètre le handle du hook créé précédemment. SetWindowsHookEx() ajoute le hook à une chaîne. La procédure peut permettre ou non l'appel du hook suivant dans la chaîne. |
2. Types of hook | Types de hook |
WH_CALLWNDPROC | Allows
you to monitor messages sent
by Windows with SendMessage(). The WH_CALLWNDPROC hook
procedure is called before the message is sent to the target window.
Permet de monitorer les messages envoyés par Windows au moyen de SendMessage(). La procédure de hook est appelée avant que le message ne soit envoyé à la fenêtre. |
WH_CALLWNDPROCRET | Allows
you to monitor messages send
by windows with SendMessage(). The WH_CALLWNDPROCRET hook procedure is
called after the message is sent to the target window.
Permet de monitorer les messages envoyés par windows au moyen de SendMessage(). La procédure de hook est appelée après que le message ne soit envoyé à la fenêtre. |
WH_CBT | The
hook is called before a system
command is completed like creating, destroying, sizing, moving ... a
window.
Le hook est appelé avant qu'une commande système ne soit effectuée, comme par exemple créer, détruire, redimensionner ou bouger une fenêtre. |
WH_DEBUG | The
hook procedure is called before
any other type of hook.
La procédure de hook est lancée avant tout autre type de hook. |
WH_FOREGROUNDIDLE | The
hook procedure is called when
the foreground thread is idle.
La procédure de hook est appelée lorsque le thread est en mode idle. |
WM_GETMESSAGE | This
type of hook allows you to
monitor messages about to be returned by PeekMessage()
or GetMessage() and posted to the message queue.
Ce type permet de monitorer les messages sur le point d'être renvoyer par PeekMessage() et GetMessage() et envoyés dans la 'message queue'. |
WH_JOURNALPLAYBACK | With
this hook, you can insert
messages in the message queue.
Ce type de hook permet d'insérer des messages dans la 'message queue'. |
WH_JOURNALRECORD | It
allows you to record a sequence
of messages, like mouse or keyboard messages, and send them later using
WH_JOURNALPLAYBACK.
Permet d'enregistrer une séquence de messages comme par exemple ceux envoyés par la souris ou le clavier et de les envoyer plus tard en utilisant WH_JOURNALPLAYBACK. |
WH_KEYBOARD | Enables
you to intercept keyboard
messages.
Permet d'intercepter les messages du clavier. |
WH_MOUSE | Enables
you to intercept mouse
messages.
Permet d'intercepter les messages de la souris. |
WH_MSGFILTER | This
type of hook is used to monitor
messages sent to a menu, scrollbar, dialogbox. It can only be used by
the application who installed the hook.
Ce type de hook est utilisé pour monitorer les messages envoyés par les menus, les scrollbars ou les boîtes de dialogue. Il ne peut être utilisé que par l'application qui a installé le hook. |
WH_SYSMSGFILTER | Same
as above but for all
applications.
Même chose que le type ci-dessus mais pour l'ensemble des applications. |
WM_SHELL | Called
when the shell is about to be
activated and when a top-level window is created or destroyed.
Ce hook est apelé lorsque le shell est sur le point d'être activé et lorsqu'une fenêtre 'top-level' est créée ou détruite. |
3. Example : Installing a mouse hook | Exemple : Installation d'un hook sur la souris |
As an example, we will try to install a mouse hook wich will launch the screensaver everytime the mouse is in the upper right edge of the screen. Whenever the mouse is moved, the hook procedure is called. This one does the following : it gets the mouse position with GetCursorPos(), check if the mouse is in a predetermined rectangle, corresponding to the upper right edge and if it is the case, launch the screen saver. Then it calls the next hook in the chain using CallNextHookEx(). | Comme exemple de hook, nous allons installer un hook sur la souris qui lancera l'économiseur d'écran lorsque la souris sera dans le coin droit supérieur de l'écran. Chaque fois que la souris bouge la procédure de hook est appelée. Celle-ci effectue les tâches suivantes : obtenir la position de la souris avec la fonction GetCursorPos(), tester si la souris se trouve dans un rectangle prédéterminé, correspondant au coin supérieur droit de l'écran, lancer le screensaver et ensuite appeler le hook suivant dans la chaîne de hook CallNextHookEx(). |
First,
create a new application with
two buttons on the form and a label. The first button is used to
install the hook, the second to release the hook. The real functions which install and remove the hook are in the DLL, so the only thing the button function do is calling a function in the DLL. Place the code below in the OnClick event of each button : |
D'abord,
créons une nouvelle application et plaçons deux boutons
sur la forme et un label. Le premier bouton sert à installer le
hook, le second à le supprimer. Comme les véritables fonctions qui installent et suppriment le hook se trouve dans la DLL, l'appui sur un bouton ne fait qu'appeler une fonction contenue dans la DLL. Placez le code suivant dans l'événement OnClick de chaque bouton : |
In Unit1.h : |
Now,
we have to create the DLL
containing the hook procedure and the functions to install and remove
the hook. Click on the File menu, choose New... and DLL. Then click OK.
The canvas of our DLL is automatically created by Builder. We want to export two functions : InstallMouseHook() which will be called by the install hook button and a RemoveMouseHook() which will be called by the remove hook button. After the two exported functions, we have the declaration of the hook procedure and some global variables. The DllEntrypoint() allows us to know when the DLL is mapped in or out the application address space. InstallMouseHook() install the hook, calling SetWindowsHookEx(). RemoveMouseHook() remove the hook using UnhookWindowsHookEx(). MouseProc() is the callback hook procedure. It's the procedure called by Windows whenever the mouse moves. First we create a rectangle and get the position of the mouse. We check if the mouse is in the rectangle and if true, we launch the screensaver using SendMessage(). And finally, we call the next hook in the chain using CallNextHookEx(). |
Nous
devons maintenant créer la DLL qui va contenir le code du hook
et les fonctions appelées par les deux boutons de notre forme
pour installer et désinstaller le hook. Cliquez sur le menu
Fichier. Choisissez Nouveau... puis DLL. Builder crée alors le
canevas de notre DLL. Nous voulons exporter deux fonctions : InstallMouseHook() et RemoveMouseHook() qui sont les deux fonctions appelées par les boutons du formulaire. Après la déclarations des deux fonctions exportées, nous trouvons la déclaration de la fonction de callback utilisée par le hook et appelée chaque fois que la souris bouge. DllEntryPoint() est appelée chaque fois que la DLL est mappée dans la zône d'adresse de notre application. InstallMouseHook() installe le hook en utilisant la fonction SetWindowsHookEx(). RemoveMouseHook() supprime le hook en utilisant UnhookWindowsHookEx(). MouseProc() est la fonction de callback proprement dite et est appelée par Windows lorsque la souris bouge. Dans cette fonction, on crée d'abord un rectangle correspondant au coin supérieur droit de l'écran, ensuite on obtient la position de la souris et on teste pour savoir si la souris se trouve dans le rectangle. Si c'est le cas, on lance le screensaver au moyen de SendMessage(). pour terminer, on appelle le hook suivant dans la chaîne avec CallNextHookEx(). |
#include <vcl.h> |
All
you have to do now is to build
the application and the DLL. Run the application and click on the button1, this will install the hook. Put the mouse in the upper right edge of the screen . This will launch the screensaver. A click on the second button will uninstall the hook. |
Il ne vous reste plus qu'à compiler l'application et la DLL. Ensuite, lancez l'application et cliquez sur le bouton 1 pour installer le hook . Placez la souris dans le coin supérieur droit, cela devrait lancer le screensaver. Si vous voulez désinstaller le hook, cliquez sur le deuxième bouton. |
Download : BCB4 source code (5.97 kb)