2011-12-07 166 views
0

我在獲取某些代碼時遇到了一些麻煩。那就是:鍵盤掛鉤錯誤

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 WithEvents kbHook As New KeyboardHook 


    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 
        RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys)) 
       Case WM_KEYUP, WM_SYSKEYUP 
        RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys)) 
      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 

    Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown 
     Debug.WriteLine(Key.ToString) 
    End Sub 
    Private Sub kbHook_KeyUp(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyUp 
     Debug.WriteLine(Key) 
    End Sub 

End Class 

我已設置:項目 - > [項目名稱]屬性 - >調試 - >取消選中「啓用在Visual Studio宿主進程」

我收到以下錯誤:

System.StackOverflowException was unhandled 
An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll 

請問在這種情況下可以得到一些幫助嗎?

感謝

西蒙

回答

3
Private WithEvents kbHook As New KeyboardHook 

你的KeyboardHook構造函數初始化類的成員,包括kbHook。其中,由於As New關鍵字構造了一個KeyboardHook的新實例。初始化類的成員,包括kbHook。其中,... Kaboom!

刪除kbHook並將其放在其他地方,如在窗體中。

請注意,您的代碼無法在AnyCPU生效的64位操作系統上運行,Marshal.GetHINSTANCE()強制關閉。如果您需要幫助,請提出另一個問題。

+0

對不起,您能否再次解釋... –

+0

從該類中刪除kbHook。 –