如何使用VSTO在MSword中捕获按键事件

如何使用VSTO在MSword中捕获按键事件

本文介绍了如何使用VSTO在MSword中捕获按键事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是VSTO VB.Net编程的新手.我正在开发Word应用程序级Addin,并希望捕获按键事件.我已经尝试了各种挂钩代码,但是都没有用.我想使用使用WH_KEYBOARD而不是WH_KEYBOARD_LL的应用程序级挂钩.我尝试过的以下代码会在停止后仅捕获一个按键.而且,我不知道在哪里放置按键.我将如何使用以下内容来处理关键事件.

I am new to VSTO VB.Net programming. and I am developing a word application level Addin and want to trap keypress event. I have tried various codes of hooking but none is working. I want to use application level hook using WH_KEYBOARD instead of WH_KEYBOARD_LL. The following code which I have tried traps just one key stroke after that it stops. Moreover I could not understand where to put trap the keystrokes. How would I use the following for handling key events.

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

推荐答案

您的问题可能与以下内容重复:

Your question is a possible duplicate of:

  • How to get the "KeyPress" event from a Word 2010 Addin (developed in C#)?
  • How to raise an event on MS word Keypress
  • Capturing keydown event of MS Word using C#

...但是,答案仍然相同:您根本无法:)

... however, the answer remains the same: you simply can't :)

我对以上列出的最后一个问题的回答中,我会详细解释其原因,并且还介绍了可能的替代解决方案,其中涉及 WindowSelectionChange 事件.

In my answer to the last of the questions listed above I explain the reason behind this in a bit more detail, and also covers a possible alternative solution involving the WindowSelectionChange event.

这篇关于如何使用VSTO在MSword中捕获按键事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 13:52