VB按住键 [英] VB Press and hold keystroke
问题描述
我正在创建一个宏程序来记录和播放鼠标和键盘输入.录制效果很好,鼠标回放也一样,但是回放键盘输入时遇到了麻烦-特别是在释放前按住键数秒.这不等于重复按下该键.这是我尝试过的:
技术1:Me.KeyDown
Private Sub keyboard_pressed() Handles Me.KeyDown
Dim keypress = e.KeyData
MsgBox(keypress)
End Sub
仅在焦点对准窗口时有效.
技术2:SendKeys
Private Sub timer_keyboardplayback_Tick() Handles timer_playback.Tick
SendKeys.Send("{LEFT}")
timer_playback.Interval = 30
End Sub
工作不清晰,但反复按向左箭头而不是按住箭头
技术3:keybd_event
Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Private Sub timer_keyboardplayback_Tick() Handles timer_playback.Tick
Const keydown = &H1
Const keyup = &H2
Dim VK_LEFT = 37
keybd_event(VK_LEFT, 0, keydown, 0)
End Sub
工作不清晰,但仍然无法按保持箭头
有人可以告诉我如何实现媒体宣传吗?按住左箭头键几秒钟,然后松开.
几年前,不推荐使用keybd_event
和mouse_event
函数.相反,您应该使用 SendInput()
功能 .
通过.NET使用它来模拟输入有时可能会有些棘手,幸运的是,尽管我已经编写了一个名为 InputHelper 的库( 窗口消息 ).
不幸的是,我还没有时间编写与此有关的文档/维基(除了库的每个成员上的XML文档,这是Visual Studio的IntelliSense所显示的),但是到目前为止,您可以找到一个关于在 项目的Wiki 上创建钩子的小信息. /p>
此库的简短描述:
-
InputHelper.Hooks
用于创建全局的低级鼠标/键盘挂钩(利用 Wiki .
-
InputHelper.Keyboard
用于处理/模拟物理键盘输入(利用
SendInput()
和SendMessage()
和-
InputHelper.Keyboard.PressKey(Key As Keys, Optional HardwareKey As Boolean)
发送两次指定按键的击键(向下和向上).
如果设置了
HardwareKey
,该函数将发送密钥的 虚拟密钥代码 (默认为False
) -
InputHelper.Keyboard.SetKeyState(Key As Keys, KeyDown As Boolean, Optional HardwareKey As Boolean)
发送一次指定键的击键.
如果
KeyDown
是True
,则密钥将作为KEYDOWN事件发送,否则将作为KEYUP发送.HardwareKey
与上面的相同.
您将使用后者,因为您想控制将按键按住多长时间.
按住键指定的时间
为此,您需要像已经使用的那样使用某种计时器.但是,为了使事情更具动态性,我编写了一个函数,该函数可让您指定按住哪个键以及持续多长时间.
'Lookup table for the currently held keys. Private HeldKeys As New Dictionary(Of Keys, Tuple(Of Timer, Timer)) ''' <summary> ''' Holds down (and repeats, if specified) the specified key for a certain amount of time. ''' Returns False if the specified key is already being held down. ''' </summary> ''' <param name="Key">The key to hold down.</param> ''' <param name="Time">The amount of time (in milliseconds) to hold the key down for.</param> ''' <param name="RepeatInterval">How often to repeat the key press (in milliseconds, -1 = do not repeat).</param> ''' <remarks></remarks> Public Function HoldKeyFor(ByVal Key As Keys, ByVal Time As Integer, Optional ByVal RepeatInterval As Integer = -1) As Boolean If HeldKeys.ContainsKey(Key) = True Then Return False Dim WaitTimer As New Timer With {.Interval = Time} Dim RepeatTimer As Timer = Nothing If RepeatInterval > 0 Then RepeatTimer = New Timer With {.Interval = RepeatInterval} 'Handler for the repeat timer's tick event. AddHandler RepeatTimer.Tick, _ Sub(tsender As Object, te As EventArgs) InputHelper.Keyboard.SetKeyState(Key, True) 'True = Key down. End Sub End If 'Handler for the wait timer's tick event. AddHandler WaitTimer.Tick, _ Sub(tsender As Object, te As EventArgs) InputHelper.Keyboard.SetKeyState(Key, False) 'False = Key up. WaitTimer.Stop() WaitTimer.Dispose() If RepeatTimer IsNot Nothing Then RepeatTimer.Stop() RepeatTimer.Dispose() End If HeldKeys.Remove(Key) End Sub 'Add the current key to our lookup table. HeldKeys.Add(Key, New Tuple(Of Timer, Timer)(WaitTimer, RepeatTimer)) WaitTimer.Start() If RepeatTimer IsNot Nothing Then RepeatTimer.Start() 'Initial key press. InputHelper.Keyboard.SetKeyState(Key, True) Return True End Function
用法示例:
'Holds down 'A' for 5 seconds, repeating it every 50 milliseconds. HoldKeyFor(Keys.A, 5000, 50)
I am creating a macro program to record and play back mouse and keyboard input. Recording works fine, as does mouse playback, but I am having trouble in playing back the keyboard input - specifically pressing and holding a key for several seconds before releasing. This is not equivalent to repetitively pressing the key. This is what I have tried:
Technique 1: Me.KeyDown
Private Sub keyboard_pressed() Handles Me.KeyDown Dim keypress = e.KeyData MsgBox(keypress) End Sub
Only works when window is in focus.
Technique 2: SendKeys
Private Sub timer_keyboardplayback_Tick() Handles timer_playback.Tick SendKeys.Send("{LEFT}") timer_playback.Interval = 30 End Sub
Works out of focus, but repetitively presses left arrow rather than press and hold arrow
Technique 3: keybd_event
Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long) Private Sub timer_keyboardplayback_Tick() Handles timer_playback.Tick Const keydown = &H1 Const keyup = &H2 Dim VK_LEFT = 37 keybd_event(VK_LEFT, 0, keydown, 0) End Sub
Works out of focus, but still fails to press hold arrow
Can someone please show me how I can achieve a press & hold of the Left Arrow Key for several seconds, and then release.
解决方案The
keybd_event
andmouse_event
functions are deprecated as of a few years ago. Instead you should use theSendInput()
function.Simulating input with it from .NET can sometimes be a bit tricky, fortunately though I've written a library called InputHelper (Download from GitHub) which is a wrapper around
SendInput()
. I've customized it so that it covers some of the many different ways of input handling and input simulation, mainly:- Simulate keystrokes (internally utilizing
SendInput()
). - Simulate mouse movement and mouse button clicks (also utilizing
SendInput()
internally). - Send virtual keystrokes and mouse clicks to the current/a specific window (internally utilizing Window Messages).
- Create global, low-level mouse and keyboard hooks.
Unfortunately I've not yet had the time to write a proper documentation/wiki about this (apart from the XML documentation on each member of the library, which is shown by Visual Studio's IntelliSense), but so far you can find a little info about creating hooks on the project's wiki.
A short description of what this library consist of:
InputHelper.Hooks
For creating global, low-level mouse/keyboard hooks (utilizes
SetWindowsHookEx()
and other related methods). This is partially covered in the wiki.InputHelper.Keyboard
For handling/simulating physical keyboard input (utilizes
SendInput()
andGetAsyncKeyState()
).InputHelper.Mouse
For handling/simulating physical mouse input (utilizes
SendInput()
).InputHelper.WindowMessages
For handling/simulating virtual mouse/keyboard input, for instance to a specific window (utilizes
SendMessage()
andPostMessage()
).
Sending a keystroke
Sending a "physical" keystroke can be done via two functions:
InputHelper.Keyboard.PressKey(Key As Keys, Optional HardwareKey As Boolean)
Sends two keystrokes (down and up) of the specified key.
If
HardwareKey
is set, the function will send the key's Scan Code instead of its Virtual Key Code (default isFalse
).InputHelper.Keyboard.SetKeyState(Key As Keys, KeyDown As Boolean, Optional HardwareKey As Boolean)
Sends a single keystroke of the specified key.
If
KeyDown
isTrue
the key will be sent as a KEYDOWN event, otherwise KEYUP.HardwareKey
is the same as above.
You'd use the latter, since you want to control for how long you want the key to be held down.
Holding a key down for the specified amount of time
In order to do this you need to use some sort of timer, like you already do. However to make things a bit more dynamic I've written a function that'll let you specify which key to hold down, and also for how long.
'Lookup table for the currently held keys. Private HeldKeys As New Dictionary(Of Keys, Tuple(Of Timer, Timer)) ''' <summary> ''' Holds down (and repeats, if specified) the specified key for a certain amount of time. ''' Returns False if the specified key is already being held down. ''' </summary> ''' <param name="Key">The key to hold down.</param> ''' <param name="Time">The amount of time (in milliseconds) to hold the key down for.</param> ''' <param name="RepeatInterval">How often to repeat the key press (in milliseconds, -1 = do not repeat).</param> ''' <remarks></remarks> Public Function HoldKeyFor(ByVal Key As Keys, ByVal Time As Integer, Optional ByVal RepeatInterval As Integer = -1) As Boolean If HeldKeys.ContainsKey(Key) = True Then Return False Dim WaitTimer As New Timer With {.Interval = Time} Dim RepeatTimer As Timer = Nothing If RepeatInterval > 0 Then RepeatTimer = New Timer With {.Interval = RepeatInterval} 'Handler for the repeat timer's tick event. AddHandler RepeatTimer.Tick, _ Sub(tsender As Object, te As EventArgs) InputHelper.Keyboard.SetKeyState(Key, True) 'True = Key down. End Sub End If 'Handler for the wait timer's tick event. AddHandler WaitTimer.Tick, _ Sub(tsender As Object, te As EventArgs) InputHelper.Keyboard.SetKeyState(Key, False) 'False = Key up. WaitTimer.Stop() WaitTimer.Dispose() If RepeatTimer IsNot Nothing Then RepeatTimer.Stop() RepeatTimer.Dispose() End If HeldKeys.Remove(Key) End Sub 'Add the current key to our lookup table. HeldKeys.Add(Key, New Tuple(Of Timer, Timer)(WaitTimer, RepeatTimer)) WaitTimer.Start() If RepeatTimer IsNot Nothing Then RepeatTimer.Start() 'Initial key press. InputHelper.Keyboard.SetKeyState(Key, True) Return True End Function
Example usage:
'Holds down 'A' for 5 seconds, repeating it every 50 milliseconds. HoldKeyFor(Keys.A, 5000, 50)
这篇关于VB按住键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-