Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ocdtrekkie/936e37c2a67a59a5db1518efd0ff127b to your computer and use it in GitHub Desktop.
Save ocdtrekkie/936e37c2a67a59a5db1518efd0ff127b to your computer and use it in GitHub Desktop.
VB.NET - How to add global hotkeys to applications in VB.NET

Authored in 2010

When you want to make your application do things by the user pressing a hotkey / key combination, even when your application does not have focus, you will need a so called global hotkey. A global hotkey is a form of "keyboard hook" which is a low level way of monitoring the computer for a certain key combination, aka hotkey. Below is a simple class, which let's you register a hotkey and define what code should execute, once the hotkey is pressed.

    Public Class Hotkey

#Region "Declarations - WinAPI, Hotkey constant and Modifier Enum"
        ''' <summary>
        ''' Declaration of winAPI function wrappers. The winAPI functions are used to register / unregister a hotkey
        ''' </summary>
        Private Declare Function RegisterHotKey Lib "user32" _
        (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer

        Private Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer

        Public Const WM_HOTKEY As Integer = &H312

        Enum KeyModifier
            None = 0
            Alt = &H1
            Control = &H2
            Shift = &H4
            Winkey = &H8
        End Enum 'This enum is just to make it easier to call the registerHotKey function: The modifier integer codes are replaced by a friendly "Alt","Shift" etc.
#End Region


#Region "Hotkey registration, unregistration and handling"
        Public Shared Sub registerHotkey(ByRef sourceForm As Form, ByVal triggerKey As String, ByVal modifier As KeyModifier)
            RegisterHotKey(sourceForm.Handle, 1, modifier, Asc(triggerKey.ToUpper))
        End Sub
        Public Shared Sub unregisterHotkeys(ByRef sourceForm As Form)
            UnregisterHotKey(sourceForm.Handle, 1)  'Remember to call unregisterHotkeys() when closing your application.
        End Sub
        Public Shared Sub handleHotKeyEvent(ByVal hotkeyID As IntPtr)
            MsgBox("The hotkey was pressed")
        End Sub
#End Region

    End Class

To register a hotkey, you need to call the registerHotkey function of the class Hotkey. If you for example want to register ALT+Q, you can do the following:

Hotkey.RegisterHotKey(Me, "W", Hotkey.KeyModifier.Alt)

The first parameter is the sourceform, essentially your main form. The second parameter is a number ID for the hotkey registration, this can be any integer though with some limitations. Next parameter is the key that needs to be pressed, and the fourth and final is the modifier (alt, shift, control, winkey) if any. For this to work, you will need to add one piece of code to your source form:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = Hotkey.WM_HOTKEY Then
Hotkey.handleHotKeyEvent(m.WParam)
End If
MyBase.WndProc(m)
End Sub 'System wide hotkey event handling

The above sub captures and sends keyboard messages from the WinAPI to the handleHotKey method in the Hotkey class.

Once you have called Hotkey.RegisterHotkey from your code, the hotkey is registered, and will trigger the code in the Hotkey.handleHotKeyEvent, every time the user presses that specific hotkey.

Note Hotkeys with special keys such as F1-F12, space and similar requires a slightly different approach. The methods are essentially the same, but you will need to retrieve the "virtual key code" of the special key, and use it as a parameter in the Hotkey.registerHotkey method instead of the Asc(triggerKey.toUpper) parameter. Googling "virtual key codes" will get you a list of the codes.

Multiple hotkeys

In the above, we assume only one hotkey is needed. Sometimes you need more than one hotkey. In this case we need a few, small changes to the above code. If you examine our "registerHotkey" method in the Hotkey class, you will notice that the second parameter is a number, in our case "1":

Public Shared Sub registerHotkey(ByRef sourceForm As Form, ByVal triggerKey As String, ByVal modifier As KeyModifier)
            RegisterHotKey(sourceForm.Handle, 1, modifier, Asc(triggerKey.ToUpper))
End Sub

This is an ID for the hotkey we are registering. To add multiple hotkeys we simply need to specify another ID. Let's change our method, so it is possible to manually supply an ID:

Public Shared Sub registerHotkey(ByRef sourceForm As Form, ByVal hotkeyID As Integer, ByVal triggerKey As String, ByVal modifier As KeyModifier)
            RegisterHotKey(sourceForm.Handle, hotkeyID, modifier, Asc(triggerKey.ToUpper))
End Sub

Now, when you call the registerHotkey method in the Hotkey class, you will have to supply a hotkeyID of type integer. This allows you to register multiple hotkeys, using a different ID for each. To register three different hotkeys, you might now use the following method call outside the Hotkey class (for example inside a button.click event:

Private Sub btnRegHotkey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRegHotkey.Click
        Hotkey.RegisterHotKey(Me, "W", 1, Hotkey.KeyModifier.Alt)
        Hotkey.RegisterHotKey(Me, "E", 2, Hotkey.KeyModifier.Alt)
        Hotkey.RegisterHotKey(Me, "R", 3, Hotkey.KeyModifier.Alt)
End Sub

The above will register both ALT+W, ALT+E and ALT+R as hotkeys. Next, we need to add a little more code to the Hotkey class, in order to handle these different hotkeys. We will handle this using a simple Select Case statement on the hotkey ID. Open the Hotkey class and change the "handleHotKeyEvent" method to reflect the following:

    Public Shared Sub handleHotKeyEvent(ByVal hotkeyID As IntPtr)
Select Case hotkeyID
            Case 1
                MsgBox("The hotkey ALT+W (ID: 1) was pressed")
            Case 2
                MsgBox("The hotkey ALT+E (ID: 2) was pressed")
            Case 3
                MsgBox("The hotkey ALT+R (ID: 3) was pressed")
        End Select
    End Sub

To unregister the hotkeys, when closing your application you'd just change the "unregisterHotkeys" method with all the registered hotkey ID's:

        Public Shared Sub unregisterHotkeys(ByRef sourceForm As Form)
            UnregisterHotKey(sourceForm.Handle, 1)  'Remember to call unregisterHotkeys() when closing your application.
            UnregisterHotKey(sourceForm.Handle, 2) 
            UnregisterHotKey(sourceForm.Handle, 3)
        End Sub

Those relative minor changes is all there is to handling multiple hotkeys in your .NET application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment