Simulating input: key pressed, hold and release
Asked Answered
G

2

6

I am trying to simulate a user pressing a key, holding it for some specific time interval, and then releasing it. I have tried to implement this using SendKeys.Send(), but I cannot figure out how to control the duration of how long the key is pressed.

I don't want to just keep sending the same key over and over; I want a single key-down and a single key-up event.

For example, I have code like this:

//when i press this button, will sent keyboard key "A", i want to hold it until i release

private void start_btn_Click(object sender, EventArgs e)
{
    testSent();
}

//how should i hold it for a timer???
private void testSent()
{
    SendKeys.Send("A");
}
Gravelly answered 19/11, 2015 at 0:55 Comment(1)
Sorry but i am not clear what you are trying to do. Can you show some sample timer code of what you are trying to do? In one of code comment you told "i want to hold it until i release" and one more comment says "how should i hold it for a timer???", aren't they conflicting?Octuple
M
2

If you want the receiving program to see just the key-down event followed by a key-up event some period of time later, you will need a different API than SendKeys. That one only sends entire key-strokes, i.e. with key-down and key-up. You may be able to do what you want by p/invoking the native Windows SendInput() function.

I haven't used it, but you may find that the Windows Input Simulator is a useful managed code wrapper for the API you need.

Assuming you figure out how to end the appropriate key events, doing it on a timed basis is trivial:

private static readonly TimeSpan _keyDownInterval = ...; // initialize as desired

private async void start_btn_Click(object sender, EventArgs e)
{
    SendKeyDown();
    await Task.Delay(_keyDownInterval);
    SendKeyUp();
}

// These two are implemented using whatever mechanism you prefer,
// e.g. p/invoke `SendInput()`, using the Windows Input Simulator library, or whatever.
private void SendKeyDown() { ... }
private void SendKeyUp() { ... }


Here are some related questions on Stack Overflow:
Send keys to WPF Browser control
C# p/Invoke How to simulate a keyPRESS event using SendInput for DirectX games

Neither specifically address your question, but they both include some discussion on the usage of SendInput().

Martyr answered 19/11, 2015 at 8:3 Comment(2)
When you hold a key down and keep holding it down in an actual physical keyboard, it keeps repeating automatically until you let go of the key. But when you simulate KyDown with an input simulator, the key doesn't keep repeating automatically. Why? How do you get it to behave like the physical key ?Tempura
@RoySeberg: Windows explicitly repeats the WM_KEYDOWN message when the key is held down. You would need to simulate this yourself by sending that input yourself, e.g. using a timer, for the duration desired.Martyr
O
2

Don't expect SendKeys.Send("A") wil hold up the A key instead it will send the A key multiple times and you can also write SendKeys.Send("{A 6}") to send the A key 6 times but moreover it will be all same since the SendKeys is just designed to send keypress keystrokes to an application and a keypress event is a combination of keyDown & keyUp event.

But you can use kebd_event for API for that as:

int VK_A = 0x41,

[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);


public static void KeyPress(int keycode, int delay = 0)
{
   keybd_event((byte)keycode, 0x0, 0, 0);// presses
   System.Threading.Thread.Sleep(delay);
   keybd_event((byte)keycode, 0x0, 2, 0); //releases
}
        

With the above code you can now write

KeyPress(VK_A,1000); //1 second
KeyPress(VK_A,3000); //3 second
KeyPress(VK_A,5000); //5 second

to have a delay of 1,3 & 5 seconds. For a complete answer please refer my answer here C# hold key in a game application

Omniscience answered 28/12, 2022 at 12:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.