The keybd_event
and mouse_event
几年前,函数已被弃用。相反,你应该使用SendInput()功能 https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx.
使用它来模拟来自 .NET 的输入有时会有点棘手,幸运的是,尽管我已经编写了一个名为输入助手 (从 GitHub 下载 https://github.com/Visual-Vincent/InputHelper/releases) 这是一个包装器SendInput()
。我对其进行了定制,使其涵盖了输入处理和输入模拟的许多不同方式中的一些,主要是:
- 模拟击键(内部利用
SendInput()
).
- 模拟鼠标移动和鼠标按钮点击(也利用
SendInput()
内部)。
- 将虚拟击键和鼠标点击发送到当前/特定窗口(内部利用窗口消息 https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927(v=vs.85).aspx).
- 创建全局的、低级的鼠标和键盘挂钩。
不幸的是,我还没有时间写一个关于这个的适当的文档/wiki(除了库每个成员的 XML 文档,这是由 Visual Studio 的 IntelliSense 显示的),但到目前为止你可以找到一些关于创建钩子项目的维基 https://github.com/Visual-Vincent/InputHelper/wiki.
该库包含的内容的简短描述:
-
InputHelper.Hooks
用于创建全局的、低级的鼠标/键盘挂钩(利用SetWindowsHookEx() https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx以及其他相关方法)。这部分包含在wiki https://github.com/Visual-Vincent/InputHelper/wiki/Low-level-keyboard-hook.
-
InputHelper.Keyboard
用于处理/模拟物理键盘输入(利用SendInput()
and GetAsyncKeyState() https://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx).
-
InputHelper.Mouse
用于处理/模拟物理鼠标输入(利用SendInput()
).
-
InputHelper.WindowMessages
用于处理/模拟虚拟鼠标/键盘输入,例如特定窗口(利用SendMessage() https://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx and PostMessage() https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944(v=vs.85).aspx).
发送击键
发送“物理”击键可以通过两个函数完成:
-
InputHelper.Keyboard.PressKey(Key As Keys, Optional HardwareKey As Boolean)
发送指定键的两次击键(向下和向上)。
If HardwareKey
设置后,该功能将发送密钥的扫码 https://msdn.microsoft.com/en-us/library/windows/desktop/ms646267(v=vs.85).aspx#scan_code而不是它的虚拟键码 https://msdn.microsoft.com/en-us/library/windows/desktop/ms646267(v=vs.85).aspx#_win32_Virtual_Key_Codes_Described (默认为False
).
-
InputHelper.Keyboard.SetKeyState(Key As Keys, KeyDown As Boolean, Optional HardwareKey As Boolean)
发送指定键的单个击键。
If KeyDown
is 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)