VB按住键 [英] VB Press and hold keystroke

查看:94
本文介绍了VB按住键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个宏程序来记录和播放鼠标和键盘输入.录制效果很好,鼠标回放也一样,但是回放键盘输入时遇到了麻烦-特别是在释放前按住键数秒.这不等于重复按下该键.这是我尝试过的:

技术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_eventmouse_event函数.相反,您应该使用 SendInput()功能 .

通过.NET使用它来模拟输入有时可能会有些棘手,幸运的是,尽管我已经编写了一个名为 InputHelper 的库( 项目的Wiki 上创建钩子的小信息. /p>

此库的简短描述:

  • InputHelper.Hooks

    用于创建全局的低级鼠标/键盘挂钩(利用 Wiki .

  • InputHelper.Keyboard

    用于处理/模拟物理键盘输入(利用SendInput() SendMessage()

    您将使用后者,因为您想控制将按键按住多长时间.


    按住键指定的时间

    为此,您需要像已经使用的那样使用某种计时器.但是,为了使事情更具动态性,我编写了一个函数,该函数可让您指定按住哪个键以及持续多长时间.

    '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 and mouse_event functions are deprecated as of a few years ago. Instead you should use the SendInput() 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() and GetAsyncKeyState()).

    • 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() and PostMessage()).


    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 is False).

    • InputHelper.Keyboard.SetKeyState(Key As Keys, KeyDown As Boolean, Optional HardwareKey As Boolean)

      Sends a single keystroke of the specified key.

      If KeyDown is True 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆