-1

I currently have this code

 keybd_event(0x09, 0, 0, 0);
 keybd_event(0x09, 0, 0, 0);
 keybd_event(0x09, 0, 0, 0);

to be able to hit tab three consecutive times, however, it only hits tab the first time and wont hit tab again.

When I try to debug it, whenever I continue to the second and third keybd_event, it shows the message "changes are not allowed while code is running"

  • The key goes down but does it come up again? Why are you calling a deprecated function. SendInput is your guy. From C# call SendKeys. – David Heffernan Nov 04 '16 at 20:37

1 Answers1

0

You are not sending any KEYEVENTF_KEYUP events in between each keystroke, eg:

keybd_event(0x09, 0, 0, 0);
keybd_event(0x09, KEYEVENTF_KEYUP, 0, 0);
keybd_event(0x09, 0, 0, 0);
keybd_event(0x09, KEYEVENTF_KEYUP, 0, 0);
keybd_event(0x09, 0, 0, 0);
keybd_event(0x09, KEYEVENTF_KEYUP, 0, 0);

That being said, keybd_event() is decremented, you should be using SendInput() instead (see Send keys through SendInput in user32.dll), eg:

INPUT input = new INPUT {
    Type = 1
};
input.Data.Keyboard = new KEYBDINPUT() {
    Vk = 0x09,
    Scan = 0,
    Flags = 0,
    Time = 0,
    ExtraInfo = IntPtr.Zero,
};

INPUT input2 = new INPUT {
    Type = 1
};
input2.Data.Keyboard = new KEYBDINPUT() {
    Vk = 0x09,
    Scan = 0,
    Flags = 2,
    Time = 0,
    ExtraInfo = IntPtr.Zero
};

INPUT[] inputs = new INPUT[] { input, input2, input, input2, input, input2 };
SendInput(6, inputs, Marshal.SizeOf(typeof(INPUT)));

Or, you can use SendKeys() instead, eg:

SendKeys.Send("{TAB}{TAB}{TAB}");
Community
  • 1
  • 1
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you for the answer, feels so dumb now to not realize the keyup. – Tony Zeyork Lin Nov 04 '16 at 20:22
  • It's really bad to encourage keybd_event, deprecated as it is. Why can't you recommend SendInput. – David Heffernan Nov 04 '16 at 20:36
  • @DavidHeffernan Um, I did. – Remy Lebeau Nov 04 '16 at 20:47
  • Hmm. Perhaps I am drunk. Sorry. Still I'd encourage never ever including keybd_event. You know that the asker is going to use that code. – David Heffernan Nov 04 '16 at 20:48
  • @DavidHeffernan Can you explain why keybd_event is bad – Tony Zeyork Lin Nov 04 '16 at 20:58
  • I could. But I don't think I could do so better than the documentation already does. – David Heffernan Nov 04 '16 at 20:59
  • 1
    @TonyZeyorkLin: The main reason is that `keybd_event()` suffers from a race condition that can cause corrupted input. Each call to `keybd_event()` is injected into the input queue as a separate event, with no safeguards to prevent other input events from being injected at the same time, either from the user or from other apps. That can cause multiple inputs to intermix events with each other in unpredictable ways. `SendInput()` was designed to eliminate that race condition by allowing multiple input events to be injected atomically at one time so they cannot be interrupted by other events. – Remy Lebeau Nov 04 '16 at 21:24