键盘挂钩,防止键盘输入到应用程序

时间:2014-04-01 19:53:48

标签: vb.net keyboard keyboard-hook

我正在努力学习键盘挂钩是如何工作的并且失败了。我收集了以下代码,其中包含了我想要的一些内容 我要做的是拦截某些键盘输入并执行我的代码,而不是将这些特定的键盘输入传递回应用程序。我的代码能够拦截键盘输入并执行我的代码,但键盘输入总是在我的代码执行后传递给应用程序。有什么建议吗?

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

1 个答案:

答案 0 :(得分:2)

在回调函数中返回非零值。

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

更多细节 http://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx