mrWeenus
mrWeenus

Reputation: 21

Keyboard Hooking, prevent keyboard input to application

I am trying to learn how keyboard hooking works and am failing. I have gathered the following code which does some of what I want it to.
What I'm trying to do is Intercept certain keyboard inputs and execute my code, and not pass those specific keyboard inputs back to the application. My code is capable of intercepting keyboard inputs and executing my code, but the keyboard inputs are always passed onto the application after my code has executed. Any suggestions?

Imports System
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports System.Windows.Forms


Friend Class KeyboardHooking
' Methods
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function

<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
End Function

Private Shared Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    If ((nCode >= 0) AndAlso (nCode = 0)) Then
        Dim keyData As Keys = DirectCast(CInt(wParam), Keys)

        If ((BindingFunctions.IsKeyDown(Keys.ControlKey) AndAlso BindingFunctions.IsKeyDown(Keys.ShiftKey)) AndAlso BindingFunctions.IsKeyDown(My.Settings.keyLinkQuickToDB)) Then
            linkQuickToDB()

        'Qty Changer
        ElseIf ((BindingFunctions.IsKeyDown(Keys.ControlKey) AndAlso BindingFunctions.IsKeyDown(Keys.ShiftKey)) AndAlso BindingFunctions.IsKeyDown(My.Settings.keyQtyChange)) Then
            qtyChanger()
        End If
    End If

    Return CInt(KeyboardHooking.CallNextHookEx(KeyboardHooking._hookID, nCode, wParam, lParam))

End Function

Public Shared Sub ReleaseHook()
    KeyboardHooking.UnhookWindowsHookEx(KeyboardHooking._hookID)
End Sub

Public Shared Sub SetHook()
    KeyboardHooking._hookID = KeyboardHooking.SetWindowsHookEx(2, KeyboardHooking._proc, IntPtr.Zero, Convert.ToUInt32(AppDomain.GetCurrentThreadId))
End Sub

<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As LowLevelKeyboardProc, ByVal hMod As IntPtr, ByVal dwThreadId As UInt32) As IntPtr
End Function

<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function


' Fields
Private Shared _hookID As IntPtr = IntPtr.Zero
Private Shared _proc As LowLevelKeyboardProc = New LowLevelKeyboardProc(AddressOf KeyboardHooking.HookCallback)
Private Const WH_KEYBOARD As Integer = 2
Private Const WH_KEYBOARD_LL As Integer = 13
Private Const WM_KEYDOWN As Integer = &H100

' Nested Types
Public Delegate Function LowLevelKeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer

End Class

Public Class BindingFunctions
' Methods
<DllImport("user32.dll")> _
Private Shared Function GetKeyState(ByVal nVirtKey As Integer) As Short
End Function

Public Shared Function IsKeyDown(ByVal keys As Keys) As Boolean
    Return ((BindingFunctions.GetKeyState(CInt(keys)) And &H8000) = &H8000)
End Function

End Class

Upvotes: 2

Views: 1424

Answers (1)

Jumpei
Jumpei

Reputation: 621

Return nonzero value in callback function.

Private Shared Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    If ((nCode >= 0) AndAlso (nCode = 0)) Then
        Dim keyData As Keys = DirectCast(CInt(wParam), Keys)

        If ((BindingFunctions.IsKeyDown(Keys.ControlKey) AndAlso BindingFunctions.IsKeyDown(Keys.ShiftKey)) AndAlso BindingFunctions.IsKeyDown(My.Settings.keyLinkQuickToDB)) Then
            linkQuickToDB()
            Return -1 'prevent passing

        'Qty Changer
        ElseIf ((BindingFunctions.IsKeyDown(Keys.ControlKey) AndAlso BindingFunctions.IsKeyDown(Keys.ShiftKey)) AndAlso BindingFunctions.IsKeyDown(My.Settings.keyQtyChange)) Then
            qtyChanger()
            Return -1 'prevent passing
        End If
    End If

    Return CInt(KeyboardHooking.CallNextHookEx(KeyboardHooking._hookID, nCode, wParam, lParam))    
End Function

More details http://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx

Upvotes: 2

Related Questions