如何使用VSTO在MSWORD陷阱按键事件?(How to trap keypress event

2019-07-03 13:58发布

我是新来VSTO VB.Net编程。 我正在开发一个Word应用程序级加载项并想捕获按键事件。 我曾尝试挂钩的各种代码,但没有工作。 我想用使用的应用程序级挂钩WH_KEYBOARD ,而不是WH_KEYBOARD_LL 。 下面的代码,我已经到停止后试图陷阱只是一个击键。 而且我不明白哪里放陷阱击键。 我将如何使用,用于处理关键事件以下。

Public Event KeyDown As KeyEventHandler

Public Event KeyPress As KeyPressEventHandler

Public Event KeyUp As KeyEventHandler

我使用的代码是

Imports System.ComponentModel

Imports System.Windows.Forms

Imports System.Runtime.InteropServices

Public Class KeyBoardHook
    Inherits Component
    Dim PredictString As String

#Region "     keyboardHook"
    Private Declare Auto Function LoadLibrary Lib "kernel32" (ByVal lpFileName As String) As IntPtr
    Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hhk As IntPtr) As Boolean
    Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, _
    ByVal lpfn As KeyboardProc, ByVal hmod As IntPtr, ByVal dwThreadId As Integer) As IntPtr
    Private Delegate Function KeyboardProc(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As IntPtr
    Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As IntPtr, ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As IntPtr

    Private Structure KBDLLHOOKSTRUCT
        Public vkCode As Integer
        Public scanCode As Integer
        Public flags As Integer
        Public time As Integer
        Public dwExtraInfo As Integer
    End Structure

    'Keyboard Constants
    Private Const HC_ACTION As Integer = 0
    Private Const WM_KEYDOWN As Integer = &H100
    Private Const WM_KEYUP As Integer = &H101
    Private Const WM_SYSKEYDOWN As Integer = &H104
    Private Const WM_SYSKEYUP As Integer = &H105

    Private Const WH_KEYBOARD As Integer = 2
    Public hKeyboardHook As IntPtr

    Public Event KeyDown As KeyEventHandler
    Public Event KeyPress As KeyPressEventHandler
    Public Event KeyUp As KeyEventHandler

    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
    Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Integer) As Integer

    Private Const VK_ALT As Integer = &H12
    Private Const VK_CONTROL As Integer = &H11
    Private Const VK_SHIFT As Integer = 16

    <MarshalAs(UnmanagedType.FunctionPtr)> Private callback As KeyboardProc

    Public Sub HookKeyboard()
        callback = New KeyboardProc(AddressOf KeyboardCallback)
        Dim hInstance As IntPtr = LoadLibrary("User32")
        hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, callback, hInstance, 0)
        CheckHooked()
    End Sub

    Private Function KeyboardCallback(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As IntPtr
        Dim xy As System.Drawing.Point = Cursor.Position()
        Try
            If (Code = HC_ACTION Or Code = 3) Then
                Dim CapsLock As Boolean = GetKeyState(Keys.CapsLock) = 1
                Dim shifting As Boolean = False
                Dim modifiers As Keys
                If GetAsyncKeyState(VK_CONTROL) <> 0 Then
                    modifiers = modifiers Or Keys.Control
                End If
                If GetAsyncKeyState(VK_SHIFT) <> 0 Then
                    modifiers = modifiers Or Keys.Shift
                    shifting = True
                End If
                If GetAsyncKeyState(VK_ALT) <> 0 Then
                    modifiers = modifiers Or Keys.Alt
                End If
                Static lastKeys As Keys
                Select Case wParam
                    Case WM_KEYDOWN, WM_SYSKEYDOWN
                        RaiseEvent KeyDown(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
                        If lastKeys <> (DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers) Then
                            lastKeys = (DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers)
                            If CapsLock AndAlso shifting Then
                                RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToLower(Chr(lParam.vkCode))))
                            ElseIf Not CapsLock AndAlso shifting Then
                                RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToUpper(Chr(lParam.vkCode))))
                            ElseIf Not shifting Then
                                If CapsLock Then
                                    RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToUpper(Chr(lParam.vkCode))))
                                Else
                                    RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToLower(Chr(lParam.vkCode))))
                                End If
                            End If
                        End If
                    Case WM_KEYUP, WM_SYSKEYUP
                        If CapsLock AndAlso shifting Then
                            RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
                        ElseIf Not CapsLock AndAlso shifting Then
                            RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
                        ElseIf Not shifting Then
                            If CapsLock Then
                                RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
                            Else
                                RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
                            End If
                        End If
                        lastKeys = Nothing
                End Select
            End If

            MsgBox("Keypressed is -> " & lParam.vkCode)
            Return CallNextHookEx(hKeyboardHook, Code, wParam, lParam)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Function

    Private Function keyboardHooked() As Boolean
        Return hKeyboardHook <> IntPtr.Zero
    End Function

    Public Sub UnhookKeyboard()
        If keyboardHooked() Then
            UnhookWindowsHookEx(hKeyboardHook)
        End If
    End Sub
#End Region
    Private Sub CheckHooked()
        If keyboardHooked() Then
            MsgBox("Keyboard hooked")
        Else
            MsgBox("Keyboard hook failed: " & Err.LastDllError)
        End If
    End Sub
End Class

Answer 1:

你的问题是可能重复:

  • 如何获得从Word 2010加载项(在C#开发)的“按键响应”事件?
  • 如何提高对MS字按键时的事件
  • 使用C#捕获的MS Word的keydown事件

......然而,答案是一样的: 你根本无法:)

在我的答案在最后我上面列出的问题,解释这背后的原因,多一点细节,也包括涉及一个可能的技术方案WindowSelectionChange事件。



文章来源: How to trap keypress event in MSword using VSTO?