none
VSTO 键盘钩子无法处理消息 RRS feed

  • 问题

  • 我在VSTO开发中,使用了键盘钩子来响应键盘事件。

     Dim id As UInteger = Win32API.GetCurrentThreadId()
     KeyboardHookProcedure = New Win32API.HookProc(AddressOf KeyboardHookProc)
    hKeyboardHook = Win32API.SetWindowsHookEx(CType(HookHelper.WH_Codes.WH_KEYBOARD_LL, IntPtr), KeyboardHookProcedure, IntPtr.Zero, id)

    在事件处理函数中,试图将第二个参数转换为结构体

     Private Function KeyboardHookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
            If nCode <= 0 Then
                Return 0
            End If
            Dim MyKeyboardHookStruct As HookHelper.KeyboardHookStruct = Marshal.PtrToStructure(lParam, GetType(HookHelper.KeyboardHookStruct))

    但是却导致Word程序无响应。

    我将上述代码移植到Winform项目中,程序进入中断,并提示:尝试读取或写入受保护的内存。这通常指示其他内存已损坏

    开发环境:Windows 10(1809),Microsoft Office 2019,Visual Studio 2019,.Net Framework4.7.2

    2019年5月9日 8:57

全部回复

  • 你好

    vsto的问题这个论坛不support,你只给出了部分代码,这是我以前用的代码,你可以看一下:

    Private Function KeyboardHookProc(ByVal nCode As Integer, ByVal wParam As Int32, ByVal lParam As IntPtr) As Integer
        If (nCode >= 0) AndAlso (OnKeyDownEvent IsNot Nothing OrElse OnKeyUpEvent IsNot Nothing OrElse OnKeyPressEvent IsNot Nothing) Then
            Dim KeyDataFromHook As Win32Api.KeyboardHookStruct = CType(Marshal.PtrToStructure(lParam, GetType(Win32Api.KeyboardHookStruct)), Win32Api.KeyboardHookStruct)
            Dim keyData As Keys = CType(KeyDataFromHook.vkCode, Keys)
    
            If (OnKeyDownEvent IsNot Nothing OrElse OnKeyPressEvent IsNot Nothing) AndAlso (wParam = Win32Api.WM_KEYDOWN OrElse wParam = Win32Api.WM_SYSKEYDOWN) Then
    
                If IsCtrlAltShiftKeys(keyData) AndAlso preKeysList.IndexOf(keyData) = -1 Then
                    preKeysList.Add(keyData)
                End If
            End If
    
            If OnKeyDownEvent IsNot Nothing AndAlso (wParam = Win32Api.WM_KEYDOWN OrElse wParam = Win32Api.WM_SYSKEYDOWN) Then
                Dim e As System.Windows.Forms.KeyEventArgs = New System.Windows.Forms.KeyEventArgs(GetDownKeys(keyData))
                OnKeyDownEvent(Me, e)
            End If
    
            If OnKeyPressEvent IsNot Nothing AndAlso wParam = Win32Api.WM_KEYDOWN Then
                Dim keyState As Byte() = New Byte(255) {}
                Win32Api.GetKeyboardState(keyState)
                Dim inBuffer As Byte() = New Byte(1) {}
    
                If Win32Api.ToAscii(KeyDataFromHook.vkCode, KeyDataFromHook.scanCode, keyState, inBuffer, KeyDataFromHook.flags) = 1 Then
                    Dim e As KeyPressEventArgs = New KeyPressEventArgs(ChrW(inBuffer(0)))
                    OnKeyPressEvent(Me, e)
                End If
            End If
    
            If (OnKeyDownEvent IsNot Nothing OrElse OnKeyPressEvent IsNot Nothing) AndAlso (wParam = Win32Api.WM_KEYUP OrElse wParam = Win32Api.WM_SYSKEYUP) Then
    
                If IsCtrlAltShiftKeys(keyData) Then
    
                    For i As Integer = preKeysList.Count - 1 To 0
    
                        If preKeysList(i) = keyData Then
                            preKeysList.RemoveAt(i)
                        End If
                    Next
                End If
            End If
    
            If OnKeyUpEvent IsNot Nothing AndAlso (wParam = Win32Api.WM_KEYUP OrElse wParam = Win32Api.WM_SYSKEYUP) Then
                Dim e As System.Windows.Forms.KeyEventArgs = New System.Windows.Forms.KeyEventArgs(GetDownKeys(keyData))
                OnKeyUpEvent(Me, e)
            End If
        End If
    
        Return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam)
    End Function

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年5月9日 10:01