vb.net 如何在后台听键盘并按需触发按键?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15038413/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to listen keyboard in background and fire keystrokes on demand?
提问by user2101855
I want to make a program in vb.NET 2008 which will listen keyboard in background, i.e. even though the application is minimized (globally). If a specific key is been pressed by user, it should keep firing 2 other keys at regular given time intervals until the user presses that specific key again.
我想在 vb.NET 2008 中制作一个程序,它将在后台监听键盘,即即使应用程序被最小化(全局)。如果用户按下了一个特定的键,它应该在给定的时间间隔内继续触发其他 2 个键,直到用户再次按下该特定键。
How can this be done in vb.NET 2008?
这如何在 vb.NET 2008 中完成?
回答by Parimal Raj
Source : Here
来源:这里
Usage: To create the hook
用法:创建钩子
Private WithEvents kbHook As New KeyboardHook
Then each event can be handled:
然后可以处理每个事件:
Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown
Debug.WriteLine(Key.ToString)
End Sub
Private Sub kbHook_KeyUp(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyUp
Debug.WriteLine(Key)
End Sub
Keyboard Hook Class :
键盘挂钩类:
Imports System.Runtime.InteropServices
Public Class KeyboardHook
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Private Structure KBDLLHOOKSTRUCT
Public vkCode As UInt32
Public scanCode As UInt32
Public flags As KBDLLHOOKSTRUCTFlags
Public time As UInt32
Public dwExtraInfo As UIntPtr
End Structure
<Flags()> _
Private Enum KBDLLHOOKSTRUCTFlags As UInt32
LLKHF_EXTENDED = &H1
LLKHF_INJECTED = &H10
LLKHF_ALTDOWN = &H20
LLKHF_UP = &H80
End Enum
Public Shared Event KeyDown(ByVal Key As Keys)
Public Shared Event KeyUp(ByVal Key As Keys)
Private Const WH_KEYBOARD_LL As Integer = 13
Private Const HC_ACTION As Integer = 0
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const WM_SYSKEYDOWN = &H104
Private Const WM_SYSKEYUP = &H105
Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
Private HHookID As IntPtr = IntPtr.Zero
Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
If (nCode = HC_ACTION) Then
Dim struct As KBDLLHOOKSTRUCT
Select Case wParam
Case WM_KEYDOWN, WM_SYSKEYDOWN
RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
Case WM_KEYUP, WM_SYSKEYUP
RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
End Select
End If
Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
End Function
Public Sub New()
HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
If HHookID = IntPtr.Zero Then
Throw New Exception("Could not set keyboard hook")
End If
End Sub
Protected Overrides Sub Finalize()
If Not HHookID = IntPtr.Zero Then
UnhookWindowsHookEx(HHookID)
End If
MyBase.Finalize()
End Sub
End Class
回答by Arvin Salvador
If you use KeyboardHook class, make sure you have to build your program before using. With regards to the question for a specific key, you can trigger it in KeyDown or KeyUp event. But before that, you have to use sendkeys to send keys to active window.
如果您使用 KeyboardHook 类,请确保您必须在使用前构建您的程序。对于特定键的问题,您可以在 KeyDown 或 KeyUp 事件中触发它。但在此之前,您必须使用 sendkeys 将密钥发送到活动窗口。
SendKeys.Send("L") 'Sends letter L to active window.
SendKeys.Send("L") '将字母 L 发送到活动窗口。
Then you can do the following code; below checks if letter "a" is being pressed.
然后你可以执行以下代码;下面检查是否正在按下字母“a”。
Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown
Debug.WriteLine(Key.ToString)
if Key.ToString() = "a" then
'trigger your sendkeys
end if
End Sub
To trigger a specific key like a switch button, just declare a boolean variable to check if the button is switched or not. You can declare it globally:
要触发一个特定的键,比如开关按钮,只需声明一个布尔变量来检查按钮是否被切换。您可以全局声明它:
Dim switch as boolean = false
Dim 开关为 boolean = false
Just update the area where you set a condition to check the letter pressed. It will look like below:
只需更新您设置条件以检查按下的字母的区域。它将如下所示:
if Key.ToString() = "a" then
if switch = false then
switch = true
'trigger send keys
else
switch = false
'deactivate send keys
end if
end if
To have a specific time in sending keys, use timer. I hope it helps.
要指定发送密钥的时间,请使用计时器。我希望它有帮助。

