Reputation: 21
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
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