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?
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.
Related
I have a utf-8 formatted file that contains a character 'ů', when I read it in c++ using ifstream and cout it, the output is '┼»'. I can solve it by adding 'SetConsoleOutputCP( 65001 );', afterwards Im sending the char using 'SendInput();' to another window. But because the SetConsoleOutput() doesnt affect SendInput() the application recieves the corrupted character '┼»'.
The question is how to SendInput() accented character?
ifstream file(path);
string str;
while (getline (file, str))
{
cout << endl << str <<endl;
for (char &c : str) {
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0;
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
ip.ki.dwFlags = KEYEVENTF_UNICODE;
if (isupper(c)) {
ip.ki.wVk = VK_LSHIFT;
SendInput(1, &ip, sizeof(INPUT));
} else {
ip.ki.dwFlags = KEYEVENTF_KEYUP;
ip.ki.wVk = VK_LSHIFT;
SendInput(1, &ip, sizeof(INPUT));
ip.ki.dwFlags = KEYEVENTF_UNICODE;
}
ip.ki.wVk = VkKeyScanA(c);
SendInput(1, &ip, sizeof(INPUT));
Sleep(100);
}
INPUT enter;
enter.type = INPUT_KEYBOARD;
enter.ki.wScan = 0;
enter.ki.time = 0;
enter.ki.dwExtraInfo = 0;
enter.ki.dwFlags = 0;
enter.ki.wVk = VK_RETURN;
SendInput(1, &enter, sizeof(INPUT));
cout << "enter pressed";
}
UTF-8 and Windows are not good friends. Almost everything you are going to do with Windows requires UTF-16. You need to convert your UTF-8 string to UTF-16. On Windows, that would be "wstring", but you should use the right conversion routine. Alas the C++ standard cannot be bothered to give you a working one one right now, so Windows-specific MultiByteToWideChar seems like a good option.
ip.ki.dwFlags = KEYEVENTF_UNICODE;
if (isupper(c)) {
ip.ki.wVk = VK_LSHIFT;
It doesn't work this way.
If the dwFlags member specifies KEYEVENTF_UNICODE, wVk must be 0.
Unicode characters cannot be combined with Shift or other modifiers. They are not key codes, they are characters. A and a are different characters, there is no need to send shift presses to differentiate between them. You also don't need VkKeyScanA, because you want to send Unicode characters, not scan codes.
You need to convert the UTF-8 data to UTF-16 first, such as with MultiByteToWideChar() or equivalent, and then you can pass the individual UTF-16 codeunits to SendInput() using the KEYEVENTF_UNICODE flag. See my answer to Sending Two or more chars using SendInput for an example of sending UTF-16 strings with SendInput().
I found this c++ script that let you simulate a direct keyboard input, however, I need to simulate two inputs like [Ctrl + A]. I've been looking for ways to make it but I can't find the answer, if someone could help me or give me a clue I'd be grateful.
#include "stdafx.h"
#pragma comment(lib,"user32")
using namespace std;
int main()
{
char ch = 'a';
INPUT key;
memset(&key,0,sizeof(INPUT));//Zero the structure.
key.type = INPUT_KEYBOARD;
key.ki.dwExtraInfo = GetMessageExtraInfo();//<-- you will need to pinvoke this too.
key.ki.wScan =
static_cast<WORD>(MapVirtualKeyEx(VkKeyScanA(ch), MAPVK_VK_TO_VSC, GetKeyboardLayout(0)));//more pinvoking
key.ki.dwFlags = KEYEVENTF_SCANCODE;//<-- you will probably have to declare this constant somewhere-
//in your C# program.
//Ready to send the key-down event.
SendInput(1, &key, sizeof(INPUT));
Sleep(1000);//Wait one second before sending key-up.
//Sending key-up.
key.ki.dwExtraInfo = GetMessageExtraInfo();
key.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;//Key-up need be defined too, or just use the value.
SendInput(1, &key, sizeof(INPUT));
}
I've written this code, Ctrl press isn't working, however, 'W' press does.
int main()
{
Sleep(2000);
INPUT ip;
char key1 = VK_CONTROL, key2 = 'w';
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
ip.ki.wScan = key1;
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Press key2
ip.ki.wScan = key2;
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release key2
ip.ki.wScan = key2;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
// Release key1
ip.ki.wScan = key1;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
}
I've noticed if I delete the VK_CONTROL press lines, 'W' press doesn't work neither.
int main() {
Sleep(2000);
INPUT ip;
char key2 = 'w';
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press key2
ip.ki.wScan = key2;
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release key2
ip.ki.wScan = key2;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
}
To send a ctrl-a, you need to send, in order:
key-down events
VK_CONTROL
virtual code for a
key-up events
virtual code for a
VK_CONTROL
so, using VkKeyScanExW to get the virtual scan code for 'a'
key.ki.wVk = VK_CONTROL;
/* send keystroke */
key.ki.wVk = /* the virtual key code for a that you derived */
/* send keystroke */
/* set flag to keyup */
key.ki.wVk = /* Virtual code for a */
/* send keystroke */
key.ki.wVk = VK_CONTROL;
/* send keystroke */
where VK_CONTROL is the macro defined in Windows that gives you the keyboard virtual code for ctrl. Leave wScan set to 0.
You are sending virtual codes to the scan code parameter. The scan code for w is not 'w'.
In scan code set 1 (US keyboards), w's scan code is 0x11, and left control's scan code is 0x1D. Microsoft's Keyboard Scan Code Specification details sets 1 and 2, and can be found at https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc. There are commonly 3 sets of scan codes, and they are enumerated various places on the web. Or, you can use a utility to capture your own keyboard's scan codes. Sharpkeys or AutoHotkey appear to be popular utilities for doing just this.
I wanted to write a c++ code to emulate pressing a keyboard key "A":
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "..." key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
It works fine when I launch other program and wait to my program execute, the "A" is clicked and first program react to it. But I found that in the other application my action was somehow prevented (I can manually press "A" on keyboard, but using my program do not cause any action).
So, what I can do to make pressing "A" from program more identical to manually pressed "A" (so the second program won't recognize that it was called from program)?
I do not have source code of second program and do not know how it recognize that "A" wasn't pressed manually.
I'm sure that the window I want to react to my code is foreground, receive and block my key (so it can decide that event doesn't come from user but from program).
You can use SendInput() to send hardware scan codes as well (as opposed to virtual scan codes, which DirectInput might ignore). It's poorly documented, but SendInput() can indeed bypass DirectInput. The reason Eric's solution didn't work is he set the hardware scan code, but ended up using a virtual scan code (by setting dwFlags to 0 and wVk to non-zero).
Essentially, to do a key press you want to set:
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
And to do a key release, set:
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
A full working sample is below and it prints the letter 'a'. You can find other scan codes here.
#define WINVER 0x0500
#include <windows.h>
using namespace std;
int main()
{
//Structure for the keyboard event
INPUT ip;
Sleep(5000);
//Set up the INPUT structure
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0; //We're doing scan codes instead
ip.ki.dwExtraInfo = 0;
//This let's you do a hardware scan instead of a virtual keypress
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
ip.ki.wScan = 0x1E; //Set a unicode character to use (A)
//Send the press
SendInput(1, &ip, sizeof(INPUT));
//Prepare a keyup event
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
return 0;
}
Note: You can combine keypresses (like, shift + a for A) by passing SendInput() an array of INPUT structures.
You often need to set the scan code:
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
And building an array as IInspectable suggests is also definitely the way to go.
If you are looking to create a game bot, have you looked at the program AutoHotKey?
http://www.autohotkey.com/
It offers a scripting language, that allows you to do a lot of the tasks involved in 'bot' creation and it's rather easier than trying to do it all in C++
(It certainly played Farmville for me, when all my family pressured me into creating an account)
I wanted to write a c++ code to emulate pressing a keyboard key "A":
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "..." key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
It works fine when I launch other program and wait to my program execute, the "A" is clicked and first program react to it. But I found that in the other application my action was somehow prevented (I can manually press "A" on keyboard, but using my program do not cause any action).
So, what I can do to make pressing "A" from program more identical to manually pressed "A" (so the second program won't recognize that it was called from program)?
I do not have source code of second program and do not know how it recognize that "A" wasn't pressed manually.
I'm sure that the window I want to react to my code is foreground, receive and block my key (so it can decide that event doesn't come from user but from program).
You can use SendInput() to send hardware scan codes as well (as opposed to virtual scan codes, which DirectInput might ignore). It's poorly documented, but SendInput() can indeed bypass DirectInput. The reason Eric's solution didn't work is he set the hardware scan code, but ended up using a virtual scan code (by setting dwFlags to 0 and wVk to non-zero).
Essentially, to do a key press you want to set:
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
And to do a key release, set:
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
A full working sample is below and it prints the letter 'a'. You can find other scan codes here.
#define WINVER 0x0500
#include <windows.h>
using namespace std;
int main()
{
//Structure for the keyboard event
INPUT ip;
Sleep(5000);
//Set up the INPUT structure
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0; //We're doing scan codes instead
ip.ki.dwExtraInfo = 0;
//This let's you do a hardware scan instead of a virtual keypress
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
ip.ki.wScan = 0x1E; //Set a unicode character to use (A)
//Send the press
SendInput(1, &ip, sizeof(INPUT));
//Prepare a keyup event
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
return 0;
}
Note: You can combine keypresses (like, shift + a for A) by passing SendInput() an array of INPUT structures.
You often need to set the scan code:
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
And building an array as IInspectable suggests is also definitely the way to go.
If you are looking to create a game bot, have you looked at the program AutoHotKey?
http://www.autohotkey.com/
It offers a scripting language, that allows you to do a lot of the tasks involved in 'bot' creation and it's rather easier than trying to do it all in C++
(It certainly played Farmville for me, when all my family pressured me into creating an account)
I wanted to write a c++ code to emulate pressing a keyboard key "A":
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "..." key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
It works fine when I launch other program and wait to my program execute, the "A" is clicked and first program react to it. But I found that in the other application my action was somehow prevented (I can manually press "A" on keyboard, but using my program do not cause any action).
So, what I can do to make pressing "A" from program more identical to manually pressed "A" (so the second program won't recognize that it was called from program)?
I do not have source code of second program and do not know how it recognize that "A" wasn't pressed manually.
I'm sure that the window I want to react to my code is foreground, receive and block my key (so it can decide that event doesn't come from user but from program).
You can use SendInput() to send hardware scan codes as well (as opposed to virtual scan codes, which DirectInput might ignore). It's poorly documented, but SendInput() can indeed bypass DirectInput. The reason Eric's solution didn't work is he set the hardware scan code, but ended up using a virtual scan code (by setting dwFlags to 0 and wVk to non-zero).
Essentially, to do a key press you want to set:
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
And to do a key release, set:
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
A full working sample is below and it prints the letter 'a'. You can find other scan codes here.
#define WINVER 0x0500
#include <windows.h>
using namespace std;
int main()
{
//Structure for the keyboard event
INPUT ip;
Sleep(5000);
//Set up the INPUT structure
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0; //We're doing scan codes instead
ip.ki.dwExtraInfo = 0;
//This let's you do a hardware scan instead of a virtual keypress
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
ip.ki.wScan = 0x1E; //Set a unicode character to use (A)
//Send the press
SendInput(1, &ip, sizeof(INPUT));
//Prepare a keyup event
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
return 0;
}
Note: You can combine keypresses (like, shift + a for A) by passing SendInput() an array of INPUT structures.
You often need to set the scan code:
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
And building an array as IInspectable suggests is also definitely the way to go.
If you are looking to create a game bot, have you looked at the program AutoHotKey?
http://www.autohotkey.com/
It offers a scripting language, that allows you to do a lot of the tasks involved in 'bot' creation and it's rather easier than trying to do it all in C++
(It certainly played Farmville for me, when all my family pressured me into creating an account)