Home > front end >  Trying to programmatically hold a key down
Trying to programmatically hold a key down

Time:04-12

I'm trying to write an app to perform some basic process automation by sending keyboard events (i.e. simulating single key presses as well as holding keys down) to a window in focus (any window, such as Notepad). I can get single key presses to work just fine, but I can't get it to hold a key down. Even if I do a key down event, followed by a lengthy delay, followed by a key up... all I get is a single keypress.

I've read so many tutorials, and many of them multiple times over to ensure I haven't missed something. Every single time however, all I get is a single key press, it fails to hold the key down.

The following is a code sample I found from: https://social.msdn.microsoft.com/Forums/vstudio/en-US/bad5b1f3-cf59-4a2b-889b-257ee590bf99/vb-advanced-key-bot?forum=vbgeneral

What I'm expecting to have happen is that it would send a keyboard event that tells the system to hold down a key (e.g. aaaaaaaaaaaaaaaaaaaa), but all I get is a single character. I've tried spamming the system with repeat keypresses, but the receiving app sees the different keyboard code for keydowns and keyups, as opposed to a key in a held status, and thus is not responding as though the key were actually held key down.

What am I doing wrong? Did they maybe change this dll?

A huge thanks to anyone who can help me get this working.

Public Class Form1
    Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
    Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Integer, ByVal wMapType As Integer) As Integer

    ' flag to indicate completion
    Dim finished As Boolean = True

    ' how long to 'press' the Space key
    Dim delay As Integer = 3

    ' how many times to repeat Q and Space
    Dim Repeats As Integer

    ' User closes application during processing
    Dim UserInterupt As Boolean = False

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        KeyPreview = True
    End Sub
    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        If Not finished Then
            TextBox1.AppendText("USER closing" & vbCrLf)
            UserInterupt = True
            e.Cancel = True
        End If
    End Sub
    Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
        Select Case e.KeyChar
            Case "z", "Z"
                e.Handled = True
                Repeats = 12
                finished = False
                Do While Not finished
                    TextBox1.AppendText("Pressing SPACE" & vbCrLf)
                    HoldKeyDown(Keys.Space, delay)
                Loop
            Case "x", "X"
                e.Handled = True
                TextBox1.AppendText("USER stopping" & vbCrLf)
                finished = True
        End Select
    End Sub
    Private Sub HoldKeyDown(ByVal k As Keys, ByVal Hold As Integer)
        Dim HoldFor As DateTime = DateTime.Now().AddSeconds(Hold)
        keybd_event(k, MapVirtualKey(k, 0), 0, 0)
        While HoldFor.Subtract(DateTime.Now()).TotalSeconds > 0
            Application.DoEvents()
        End While
        keybd_event(k, MapVirtualKey(k, 0), 2, 0)
        TextBox1.AppendText("SPACE released" & vbCrLf)
        Repeats -= 1
        If Repeats = 0 Then
            finished = True
            TextBox1.AppendText("REPEATS completed" & vbCrLf)
        End If
        If UserInterupt Then End
    End Sub
End Class

CodePudding user response:

Answering my own question after going right down the rabbit hole on this one.

Basically put, the only way to do this is with SendKeys. The other methods are all deprecated and so will not work in this way anymore.

However this isn't a dead-end for you. If you want to use SendKeys to "hold down" a key, then spam the key at 10ms intervals and this should trigger the receiving app to think the key is held down.

  • Related