28
Mar
09

[VB.net] Keyboard Hook Class

The keyboard hook from my old blog; “Low Level Keyboard Hook (Global) – Installing a Low Level Keyboard Hook”
This version is slightly updated, to cast the vkCode to the .net Keys enum to make key handling easier.

    Public Class KeyboardHook
        ''Constants
        Private Const HC_ACTION As Integer = 0
        Private Const WH_KEYBOARD_LL As Integer = 13
        Private Const WM_KEYDOWN = &H100
        Private Const WM_KEYUP = &H101
        Private Const WM_SYSKEYDOWN = &H104
        Private Const WM_SYSKEYUP = &H105

        ''Keypress Structure
        Private Structure KBDLLHOOKSTRUCT
            Public vkCode As Integer
            Public scancode As Integer
            Public flags As Integer
            Public time As Integer
            Public dwExtraInfo As Integer
        End Structure
        ''API Functions
        Private Declare Function SetWindowsHookEx Lib "user32" _
        Alias "SetWindowsHookExA" _
        (ByVal idHook As Integer, _
        ByVal lpfn As KeyboardProcDelegate, _
        ByVal hmod As Integer, _
        ByVal dwThreadId As Integer) As Integer

        Private Declare Function CallNextHookEx Lib "user32" _
        (ByVal hHook As Integer, _
        ByVal nCode As Integer, _
        ByVal wParam As Integer, _
        ByVal lParam As KBDLLHOOKSTRUCT) As Integer

        Private Declare Function UnhookWindowsHookEx Lib "user32" _
        (ByVal hHook As Integer) As Integer

        ''Our Keyboard Delegate
        Private Delegate Function KeyboardProcDelegate _
        (ByVal nCode As Integer, _
        ByVal wParam As Integer, _
        ByRef lParam As KBDLLHOOKSTRUCT) As Integer

        ''The KeyPress events
        Public Shared Event KeyDown(ByVal Key As Keys)
        Public Shared Event KeyUp(ByVal Key As Keys)
        ''The identifyer for our KeyHook
        Private Shared KeyHook As Integer
        ''KeyHookDelegate
        Private Shared KeyHookDelegate As KeyboardProcDelegate

        Public Sub New()
            ''Installs a Low Level Keyboard Hook
            KeyHookDelegate = New KeyboardProcDelegate(AddressOf KeyboardProc)
            KeyHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyHookDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
        End Sub

        Private Shared Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
            ''If it is a keypress
            If (nCode = HC_ACTION) Then
                Select Case wParam
                    ''If it is a Keydown Event
                    Case WM_KEYDOWN, WM_SYSKEYDOWN
                        ''Activates the KeyDown event in Form 1
                        RaiseEvent KeyDown(CType(lParam.vkCode, Keys))
                    Case WM_KEYUP, WM_SYSKEYUP
                        ''Activates the KeyUp event in Form 1
                        RaiseEvent KeyUp(CType(lParam.vkCode, Keys))
                End Select
            End If
            ''Next
            Return CallNextHookEx(KeyHook, nCode, wParam, lParam)
        End Function

        Protected Overrides Sub Finalize()
            ''On close it UnHooks the Hook
            UnhookWindowsHookEx(KeyHook)
            MyBase.Finalize()
        End Sub
    End Class

Usage:
To create the hook

Private WithEvents kbHook As New KeyboardHook

Then each event can be handled:

    Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown
        Debug.WriteLine(Key.ToString)
    End Sub

    Private Sub kbHook_KeyUp(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyUp
        Debug.WriteLine(Key)
    End Sub

Note: To run this inside Visual Studio, you will need to go to:
Project -> [Project Name] Properties -> Debug -> Uncheck “Enable the Visual Studio hosting process”
As that intercepts the hooked messages before your program.


5 Responses to “[VB.net] Keyboard Hook Class”


  1. April 1, 2009 at 6:58 pm

    Hi! As always, a great guide.

    But now i have some problems, i can´t see the text it records. How do i do that?

  2. 2 ih4x
    April 1, 2009 at 7:03 pm

    When you handle to events, instead of doing Debug.WriteLine you could, say do Textbox1.text = Key.Tostring or similar

  3. 3 Someone
    September 7, 2009 at 2:01 am

    Hi, This is really amazing, thanks a million!


Leave a Reply