none
Mise en place de raccourcis clavier (HotKey) dans une application VB.NET RRS feed

  • 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
    samedi 14 mai 2011 17:23