Auteur de questions
Mise en place de raccourcis clavier (HotKey) dans une application VB.NET

Discussion générale
-
Mise en place de raccourcis clavier (HotKey) dans une application VB.NET
Bonjour à tous,
Souvent il est très utile voire indispensable d'utiliser des raccourcis clavier dans une application.Ces raccourcis nous simplifient la vie, que ce soit pour sauvegarder, ouvrir ou encore fermer un document par exemple. On pourra également définir un raccourci global afin de masquer/afficher notre programme tout en ayant le focus sur une autre application, par exemple.
Mise en place d'un raccourci spécifique à l'application :
Ces raccourcis sont faciles à mettre en place et relativement connus. On utilise pour cela les évènements KeyDown, KeyUp ou encore KeyPress de notre formulaire (ou d'une manière générale d'un contrôle possédant ces évènements).
En plaçant sur notre formulaire un contrôle TextBox. On peut implémenter l'exemple suivant, qui simulera une sauvegarde du contenu de la TextBox grâce à CTRL + S
'A chaque fois qu'une touche est appuyée à partir de la TextBox Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown If e.Control AndAlso e.KeyCode = Keys.S Then 'si la touche controle est appuyée ainsi que la touche S MsgBox("contenu de la textbox sauvegardé") 'on simule une sauvegarde End If End Sub
À présent un problème peut se poser. En effet si l'on souhaite sauvegarder le contenu plus global du formulaire entier, on constate que le contrôle ayant un focus empêche l'interception par le formulaire.
Le problème se résout en mettant la propriété KeyPreview du formulaire à True :
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.KeyPreview = True 'le formulaire traitera les évènements en premier End Sub
Maintenant quel que soit le contrôle sélectionné, c'est le formulaire qui gèrera les évènements.
Mise en place d'un raccourci global :
La méthode précédente est locale à l'application. On ne peut donc pas communiquer à distance avec l'application.
On va à présent définir un raccourci global que notre application saura traiter, quel que soit son état et quel que soit le focus.
Pour cela on aura besoin de déclarer des fonctions de la dll user32 :
Declare Auto Function RegisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Integer, ByVal fsModifier As FsModifiers, ByVal vk As Keys) As Boolean Declare Auto Function UnregisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer) As Integer
RegisterHotKey prend comme paramètre le handle de la fenêtre qui recevra le message WM_HOTKEY, un id unique et différent pour chaque raccourci, un entier correspondant à l'état des touches CTRL,ALT, WINDOWS ou encore SHIF et enfin le code clé virtuel.
L'état des touches CTRL, ALT, SHIFT et WIN et donné par l'énumération FsModifiers suivante :
Enum FsModifiers None = 0 Alt = 1 Control = 2 Shift = 4 Windows = 8 Alt_Ctrl = 3 Alt_Shift = 5 Alt_Windows = 9 Ctrl_Shift = 6 Ctrl_Windows = 10 Shift_Windows = 12 No_Repeat = 16384 End Enum
A noter que None est l'équivalent d'aucune des 4 touches appuyée et No_Repeat (non supporté par Vista/XP/2000) permet d'empêcher la répétition du raccourci si l'utilisateur reste appuyé continuellement.
On va se définir un numéro unique pour notre hotkey :
Private Const HOTKEY_ID1 As Integer = 571742 'numéro aléatoire que l'on choisit
Il nous reste ainsi à utiliser ce que l'on a :
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.Load 'dès le lancement de l'application on définit notre hotkey comment étant ALT + CTRL + B RegisterHotKey(Me.Handle, HOTKEY_ID1, FsModifiers.Alt_Ctrl, Keys.B) End Sub
Lors de la fermeture de notre application on libère la hotkey assignée :
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing UnregisterHotKey(Me.Handle, HOTKEY_ID1) End Sub
Vient maintenant la partie gestion. On va pour cela utiliser la procédure WndProc et intercepter le message WM_HOTKEY dont je parlais avant :
On va d'abord le définir, il vaut 786 :
Private Const WM_HOTKEY As Integer = 786
Ensuite :
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) Select Case m.Msg 'on va tester le message reçu à chaque appel de cette fonction Case WM_HOTKEY 'si il s'agit du message WM_HOTKEY (si l'utilisateur a appuyé sur CTRL + ALT + B) 'le code ici s'exécutera lorsque le raccourci sera détécté MsgBox("Ceci est un raccourci global") End Select MyBase.WndProc(m) End Sub
Voila le code complet de cette deuxième partie, avec un ajout d'une deuxième hotkey (wParam contient l'id de la hotkey qui a déclenché l'évènement) :
Public Class Form1 Enum FsModifiers None = 0 Alt = 1 Control = 2 Shift = 4 Windows = 8 Alt_Ctrl = 3 Alt_Shift = 5 Alt_Windows = 9 Ctrl_Shift = 6 Ctrl_Windows = 10 Shift_Windows = 12 No_Repeat = 16384 End Enum Declare Auto Function RegisterHotKey Lib "user32.dll" (ByVal handle As IntPtr, ByVal id As Integer, ByVal fsModifier As FsModifiers, ByVal vk As Keys) As Boolean Declare Auto Function UnregisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer) As Integer Private Const HOTKEY_ID1 As Integer = 571584 Private Const HOTKEY_ID2 As Integer = 752452 Private Const WM_HOTKEY As Integer = 786 Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) Select Case m.Msg 'on va tester le message reçu à chaque appel de cette fonction Case WM_HOTKEY 'si il s'agit du message WM_HOTKEY (si l'utilisateur a appuyé sur CTRL + ALT + B) If m.WParam = HOTKEY_ID1 Then 'on cherche quelle hotkey a déclenché l'évènement MsgBox("Ctrl + alt + b") ElseIf m.WParam = HOTKEY_ID2 Then MsgBox("Ctrl + alt + shift + win + d") End If End Select MyBase.WndProc(m) End Sub Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing UnregisterHotKey(Me.Handle, HOTKEY_ID1) UnregisterHotKey(Me.Handle, HOTKEY_ID2) End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load RegisterHotKey(Me.Handle, HOTKEY_ID1, FsModifiers.Alt_Ctrl, Keys.B) RegisterHotKey(Me.Handle, HOTKEY_ID2, FsModifiers.Ctrl_Windows + FsModifiers.Alt_Shift, Keys.D) End Sub End Class
Voir :
http://msdn.microsoft.com/fr-fr/library/ms646279%28v=vs.85%29.aspx
http://msdn.microsoft.com/fr-fr/library/ms646309%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/ms646327%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.keys.aspx
N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement - Best Regards.
- Fractionné Ciprian Duduiala vendredi 3 juin 2011 13:09 meilleur article 01.05.2011-01.06.2011
- Modifié Michel K jeudi 7 novembre 2013 20:37