Hi guys, I'm trying to hook the keyboard in vb.net. Who can show me an example where you press button "F2" and a message box appear (MsgBox("You've pressed F2")). I need to hook the keyboard to make some action when DirectX application is running (I've Already tryed with "registerhotkey" but do not works in dx app). Thanks in advance.

P.S. Sorry for bad english...

To create simple shortcut keys, import a Timer and set it to enabled. Then enter this code above your class:

<System.Runtime.InteropServices.DllImport("user32.dll")> _
Private Shared Function GetAsyncKeyState(ByVal vkey As System.Windows.Forms.Keys) As Short
    'Nothing
End Function

Then add this code on the Timer_Tick event:

Dim key As Boolean
key = GetAsyncKeyState(Keys.F2)
If key = True Then
    MsgBox("You've pressed F2")
End If

Hope this fixes your issue or at least push you in the right direction.

Edited 5 Years Ago by NetJunkie: n/a

Also, I have run into some issues when using the F keys because most of them are used for other things when the user is using a Laptop so I would try to add it to keys that are not used often by your users. Some examples of these would be the Home, Page Up, Page Down, End, keys.

Thanks for your code, I've trayed it and works when the form is unfocused (like registerhotkey) but still not work with Dx application. btw thanks for your reply.

I'm trying to make something like this:

Imports System.Runtime.InteropServices

Public Class KeyboardHook

    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
    End Function

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure KBDLLHOOKSTRUCT
        Public vkCode As UInt32
        Public scanCode As UInt32
        Public flags As KBDLLHOOKSTRUCTFlags
        Public time As UInt32
        Public dwExtraInfo As UIntPtr
    End Structure

    <Flags()> _
    Private Enum KBDLLHOOKSTRUCTFlags As UInt32
        LLKHF_EXTENDED = &H1
        LLKHF_INJECTED = &H10
        LLKHF_ALTDOWN = &H20
        LLKHF_UP = &H80
    End Enum

    Public Shared Event KeyDown(ByVal Key As Keys)
    Public Shared Event KeyUp(ByVal Key As Keys)

    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const HC_ACTION As Integer = 0
    Private Const WM_KEYDOWN = &H100
    Private Const WM_KEYUP = &H101
    Private Const WM_SYSKEYDOWN = &H104
    Private Const WM_SYSKEYUP = &H105

    Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer

    Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
    Private HHookID As IntPtr = IntPtr.Zero

    Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        If (nCode = HC_ACTION) Then
            Dim struct As KBDLLHOOKSTRUCT
            Select Case wParam
                Case WM_KEYDOWN, WM_SYSKEYDOWN
                    MsgBox("You've pressed anythink")
            End Select
        End If
        Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
    End Function

    Public Sub New()
        HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
        If HHookID = IntPtr.Zero Then
            Throw New Exception("Could not set keyboard hook")
        End If
    End Sub

    Protected Overrides Sub Finalize()
        If Not HHookID = IntPtr.Zero Then
            UnhookWindowsHookEx(HHookID)
        End If
        MyBase.Finalize()
    End Sub

End Class

With this code works with any key, but I need to make it work only with one key (F2 or pageup, etc...)

Your keyboard Proc should look like this

Private Const vk_F2 As Integer = 113

    Private Shared Function KeyBoardHookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer

        'Don't process just pass along
        If nCode < 0 Then
            Return CallNextHookEx(HookId, nCode, wParam, lParam)
        End If

        'Extract the keyboard structure from the lparam
        'This will contain the virtual key and any flags.
        Dim KeyboardSruct As KBDLLHOOKSTRUCT = Marshal.PtrToStructure(lParam, GetType(KBDLLHOOKSTRUCT))

        'If the 7th bit in the flags is 1 then key up.
        '7th bit = 128
        If KeyboardSruct.vkCode = vk_F2 Then
            If CBool(KeyboardSruct.flags And 128) Then
                MsgBox("F2 Up")
            Else
                MsgBox("F2 Down")
            End If

        End If
      
        'Send the message along 
        Return CallNextHookEx(HookId, nCode, wParam, lParam)

    End Function

Heres a list of all key codes
http://msdn.microsoft.com/en-us/library/ms645540(v=VS.85).aspx

This article has been dead for over six months. Start a new discussion instead.