2014-04-01 182 views
1

我想了解鍵盤掛鉤如何工作和失敗。我收集了一些我想要的代碼。
我想要做的是攔截某些鍵盤輸入並執行我的代碼,而不是將這些特定的鍵盤輸入傳遞迴應用程序。我的代碼能夠攔截鍵盤輸入並執行我的代碼,但鍵盤輸入總是在代碼執行後傳遞到應用程序。有什麼建議麼?鍵盤掛鉤,防止鍵盤輸入到應用程序

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

在回調函數中返回非零值。

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