我是VSTO VB.Net编程的新手.我正在开发一个单词应用程序级别Addin并想要捕获按键事件.我尝试了各种挂钩代码,但没有一个正常工作.我想使用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,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,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,Keys) Or modifiers)) ElseIf Not CapsLock AndAlso shifting Then RaiseEvent KeyUp(Me,Keys) Or modifiers)) ElseIf Not shifting Then If CapsLock Then RaiseEvent KeyUp(Me,Keys) Or modifiers)) Else RaiseEvent KeyUp(Me,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
您的问题可能与以下内容重复:
> 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#
…但是,答案仍然是一样的:你根本不能:)
在@L_403_3@到上面列出的最后一个问题中,我将更详细地解释其背后的原因,并且还涵盖了涉及WindowSelectionChange
事件的可能替代解决方案.