NewBieS
NewBieS

Reputation: 157

Simulating input: key pressed, hold and release

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");
}

Upvotes: 6

Views: 8833

Answers (2)

Vinod Srivastav
Vinod Srivastav

Reputation: 4263

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

Upvotes: 2

Peter Duniho
Peter Duniho

Reputation: 70701

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().

Upvotes: 2

Related Questions