VB按住按键

Leg*_*bre 5 vb.net keyboard-events

我正在创建一个宏程序来记录和播放鼠标和键盘输入.录制工作正常,鼠标播放也是如此,但我在播放键盘输入时遇到了麻烦 - 特别是在释放前按住键几秒钟.这不等于重复按键.这是我尝试过的:

技巧1:Me.KeyDown

 Private Sub keyboard_pressed() Handles Me.KeyDown
        Dim keypress = e.KeyData
        MsgBox(keypress)
    End Sub
Run Code Online (Sandbox Code Playgroud)

仅在窗口处于焦点时才起作用.

技术2:SendKeys

 Private Sub timer_keyboardplayback_Tick() Handles timer_playback.Tick
            SendKeys.Send("{LEFT}")
            timer_playback.Interval = 30
    End Sub
Run Code Online (Sandbox Code Playgroud)

工作失焦,但重复按左箭头而不是按住箭头

技巧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
Run Code Online (Sandbox Code Playgroud)

工作失焦,但仍然无法按住箭头

有人可以告诉我如何按住左箭头键几秒钟,然后释放.

Vis*_*ent 1

和函数在几年前就已被弃用keybd_eventmouse_event相反,您应该使用该SendInput()函数

使用它来模拟来自 .NET 的输入有时会有点棘手,幸运的是,尽管我编写了一个名为InputHelper的库(从 GitHub 下载),它是 .NET 的包装器SendInput()。我对其进行了定制,使其涵盖了输入处理和输入模拟的许多不同方式中的一些,主要是:

  • 模拟击键(内部利用SendInput())。
  • 模拟鼠标移动和鼠标按钮单击(也在SendInput()内部使用)。
  • 将虚拟击键和鼠标点击发送到当前/特定窗口(内部利用Window Messages)。
  • 创建全局、低级鼠标和键盘挂钩。

不幸的是,我还没有时间写一个关于这个的适当的文档/wiki(除了库每个成员的 XML 文档,这是由 Visual Studio 的 IntelliSense 显示的),但到目前为止你可以找到一些关于在项目的 wiki上创建挂钩。

该库包含的内容的简短描述:

  • InputHelper.Hooks

    用于创建全局、低级鼠标/键盘挂钩(利用SetWindowsHookEx()和其他相关方法)。维基百科对此进行了部分介绍。

  • InputHelper.Keyboard

    用于处理/模拟物理键盘输入(使用SendInput()GetAsyncKeyState())。

  • InputHelper.Mouse

    用于处理/模拟物理鼠标输入(使用SendInput())。

  • InputHelper.WindowMessages

    用于处理/模拟虚拟鼠标/键盘输入,例如特定窗口(利用SendMessage()PostMessage())。


发送击键

发送“物理”击键可以通过两个函数完成:

  • 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)

    发送指定键的单个击键。

    如果KeyDownTrue按键,将作为 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
Run Code Online (Sandbox Code Playgroud)

用法示例:

'Holds down 'A' for 5 seconds, repeating it every 50 milliseconds.
HoldKeyFor(Keys.A, 5000, 50)
Run Code Online (Sandbox Code Playgroud)