RegisterHotKey


Description:
This is a small example of how to use the RegisterHotKey API to create and respond to a system wide hotkey. This example registers the hotkeys Ctrl-N and Ctrl-M, which also demonstrates how this technique can be used to prevent some keystrokes, since this stops the user from opening a new window in IE by pressing Ctrl-N.

9/4/2003: Added support for more than one hotkey at at time.
 
Code:
' ---------------------------------------------------------------------
' Begin: Module modHook
'
' This is the main code of the hotkey functions.  This module is
'  responsible for calling the API's, and it also needs to sub-class
'  the main application's window so you can see when the hot key is
'  pressed.

Option Explicit

Private Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As _
    Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As _
    Long) As Long
Private Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd _
    As Long, ByVal id As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias _
    "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, _
    ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias _
    "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As _
    Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As _
    Long) As Long
Private Declare Function PostMessage Lib "user32" Alias _
    "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _
    wParam As Long, ByVal lParam As Long) As Long

Private Const WM_HOTKEY = &H312
Private Const WM_NCDESTROY = &H82
Private Const WM_MOUSEMOVE = &H200
Private Const GWL_WNDPROC = (-4)

Private m_lpPrevWndProc As Long
Private m_hWndMain As Long
Private m_hWndPicture As Long

'Begin the windows hook, and register the hotkey.  hWndPicture
' is a handle to a hidden picture box that get's a mouse move
' message when the hotkey is pressed
Public Sub StartHook(hwnd As Long, hWndPicture As Long)

    'Store our variables
    m_hWndMain = hwnd
    m_hWndPicture = hWndPicture
    
    'Register two hotkeys
    RegisterHotKey hwnd, 0, vbCtrlMask, vbKeyN
    RegisterHotKey hwnd, 1, vbCtrlMask, vbKeyM

    'Sub-class the main window
    m_lpPrevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, _
        AddressOf WndProc)

End Sub

Public Sub StopHook()

    'Un register the hotkeys
    UnregisterHotKey m_hWndMain, 0
    UnregisterHotKey m_hWndMain, 1
    
    'Stop the sub-classing so the application doesn't die
    SetWindowLong m_hWndMain, GWL_WNDPROC, m_lpPrevWndProc

End Sub

Public Function WndProc(ByVal hwnd As Long, ByVal uMsg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long

    Select Case uMsg
        Case WM_NCDESTROY
            'Make sure we stop subclassing if the app closses
            StopHook
        Case WM_HOTKEY
            'Pass along a message about the hotkey, passing
            ' the wParam, which is the ID, into the lParam
            ' so it's easy to find out from the handler
            PostMessage m_hWndPicture, WM_MOUSEMOVE, 0, wParam
    End Select
    
    'Let VB handle the rest of the messages
    WndProc = CallWindowProc(m_lpPrevWndProc, hwnd, uMsg, _
        wParam, lParam)

End Function

' End: Module modHook
' ---------------------------------------------------------------------


' ---------------------------------------------------------------------
' Begin: Form frmMain
'
'  This is a very simple main form.  You need to add a PictureBox
'   to the form and make it hidden (Visible=False)

Option Explicit

Private Sub Form_Load()

    'Start the hook, and register the hotkey
    StartHook Me.hwnd, pctHotKey.hwnd

End Sub

Private Sub Form_Unload(Cancel As Integer)

    'Stop the subclassing
    StopHook

End Sub

Private Sub pctHotkey_MouseMove(Button As Integer, Shift As Integer, _
    X As Single, Y As Single)

    'Since the picturebox is hidden, the only way to get here
    ' is via the hotkey, so it's been pressed.  Just print a simple
    ' message.
    
    ' Dig out the ID of the hotkey
    Dim nID As Long
    nID = pctHotKey.ScaleX(X, pctHotKey.ScaleMode, vbPixels)
    
    Debug.Print "Hotkey pressed - ID: " & Format(nID)

End Sub

' End: Module modHook
' ---------------------------------------------------------------------
 
Sample Usage:
 
n/a