0

I would like to write a function that receives a char and presses it on the keyboard.

void pressKey(const char key){
        INPUT ip;
        ip.type = INPUT_KEYBOARD;
        ip.ki.wScan = 0; 
        ip.ki.time = 0;
        ip.ki.dwExtraInfo = 0;
        ip.ki.wVk  = //What to put here? (receives WORD of the hex value)
        ip.ki.dwFlags = 0;
        SendInput(1, &ip, sizeof(INPUT));
}

How can I press the key 'a' (for example) and press it using this method or any other method?

Guy zvi
  • 77
  • 1
  • 6
  • When simulating keyboard input for text, you should use the `KEYEVENTF_UNICODE` flag to send Unicode characters, not virtual key codes. See [my earlier answer](https://stackoverflow.com/a/31307429/65863) about that. Also see [Is it a bug to pass a single-element array to SendInput?](https://stackoverflow.com/questions/46744894/) – Remy Lebeau Feb 27 '22 at 01:18
  • I tried this: ```cpp INPUT ip; WORD ch = (WORD)'a'; ip.type = INPUT_KEYBOARD; ip.ki.wScan = ch; ip.ki.dwFlags = KEYEVENTF_UNICODE; ip.ki.wScan = ch; SendInput(1, &ip, sizeof(INPUT)); ``` but it does now do anything. Any errors? @RemyLebeau – Guy zvi Feb 27 '22 at 19:11
  • 1
    You didn't follow the instructions in my [earlier answer](https://stackoverflow.com/a/31307429/65863). Specifically, that you need separate DOWN and UP events for each UTF-16 codeunit. You are only sending the DOWN event, not the UP event. You are also not initializing the unused fields of the `INPUT`, either. Did you even try the code I had provided in that answer? – Remy Lebeau Feb 27 '22 at 19:20
  • I tried the code which worked but I tried fitting it to my char uses. I seem to not understand the use of DOWN and UP in this context. How would I modify the function to receive an only char – Guy zvi Feb 27 '22 at 19:29
  • seriously? You need to send **2** `INPUT`s, one without the `KEYEVENTF_KEYUP` flag, and one with that flag. Exactly as I showed in my earlier example. – Remy Lebeau Feb 27 '22 at 19:38
  • Ok, that clears that up. I'm pretty new to c++ sorry for not understanding your first explanation. The code works – Guy zvi Feb 27 '22 at 19:43

1 Answers1

1

When simulating keyboard input for text, you should use the KEYEVENTF_UNICODE flag to send Unicode characters as-is, use virtual key codes only for non-textual keys. And you need to send 2 input events per character, one event to press the key down, and one event to release it.

For example:

void pressKey(const char key){
    INPUT ip[2] = {};

    ip[0].type = INPUT_KEYBOARD;
    ip[0].ki.wScan = key;
    ip[0].ki. dwFlags = KEYEVENTF_UNICODE;

    ip[1] = ip[0];
    ip[1].ki.dwFlags |= KEYEVENTF_KEYUP;

    SendInput(2, ip, sizeof(INPUT));
}

That being said, since this approach requires Unicode characters, if your key will ever contain a non-ASCII character then you will need to first convert it to Unicode UTF-16, such as with MultiByteToWideChar() or equivalent, and then you can send down/up events for each UTF-16 codeunit, as shown in this answer.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770