我是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, 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
答案 0 :(得分:2)
您的问题可能与以下内容重复:
...但是,答案仍然是相同的:你根本不能:)
在上面列出的最后一个问题的my answer中,我将更详细地解释其背后的原因,并且还介绍了涉及WindowSelectionChange
事件的可能替代解决方案。