SendInput () does not match manually pressing a key on a keyboard in C ++?

I wanted to write C ++ code to emulate the keyboard key press "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 great when I run another program and wait for my program to execute, clicking “A” and the first program react to it. But I found that in another application my action was somehow prevented (I can manually press "A" on the keyboard, but using my program does not cause any action).

So, what can I do to make pressing "A" from a program more identical to manually pressing "A" (so that the second program does not recognize that it was called from the program)?

I do not have the source code of the second program and I do not know how it recognizes that "A" was not pressed manually.

I am sure that the window in which I want to respond to my code is the foreground, receiving and blocking my key (so that it can decide that this event is not from the user, but from the program).

+4
source share
3 answers

You can use SendInput () to send hardware scan codes (as opposed to virtual scan codes that DirectInput can ignore). It is poorly documented, but SendInput () can actually bypass DirectInput. The reason Eric's solution doesn't work is to set the hardware scan code, but in the end it uses the virtual scan code (by setting dwFlags to 0 and wVk to a non-zero value).

Essentially, for a keypress you want to set:

 ip.ki.dwFlags = KEYEVENTF_SCANCODE; 

And to make a key release, install:

 ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; 

The following is a complete working sample, 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 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 keystrokes (e.g. shift + a for A) by passing SendInput () an array of INPUT structures.

+17
source

You often need to set a 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 sentences is also a definite way out.

+3
source

If you want to create a game bot, have you looked at AutoHotKey? http://www.autohotkey.com/

He offers a scripting language that allows you to perform many tasks related to creating a "bot", and this is easier than trying to do all this in C ++

(Of course, he played Farmville for me when my whole family pressed to create an account)

+1
source

Source: https://habr.com/ru/post/1500825/


All Articles