winapi — SendInput () не равно нажатию клавиши на клавиатуре вручную в C ++?

Я хотел написать код на C ++ для эмуляции нажатия клавиши «А»:

// 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));

Он отлично работает, когда я запускаю другую программу и жду, пока выполнится моя программа, нажмет «A» и первая программа отреагирует на это. Но я обнаружил, что в другом приложении мои действия каким-то образом были предотвращены (я могу вручную нажать «А» на клавиатуре, но использование моей программы не вызывает никаких действий).

Итак, что я могу сделать, чтобы сделать нажатие «A» из программы более идентичным нажатию «A» вручную (поэтому вторая программа не распознает, что она была вызвана из программы)?

У меня нет исходного кода второй программы и я не знаю, как он распознает, что «A» не был нажат вручную.

Я уверен, что окно, которое я хочу отреагировать на мой код, находится на переднем плане, получает и блокирует мой ключ (поэтому он может решить, что событие приходит не от пользователя, а от программы).

6

Решение

Вы также можете использовать SendInput () для отправки кодов аппаратного сканирования (в отличие от кодов виртуального сканирования, которые DirectInput может игнорировать). Это плохо документировано, но SendInput () действительно может обойти DirectInput. Причина, по которой решение Эрика не сработало, заключается в том, что он установил код аппаратного сканирования, но в итоге использовал код виртуального сканирования (установив dwFlags в 0 и wVk в ненулевое значение).

По сути, для нажатия клавиши вы хотите установить:

ip.ki.dwFlags = KEYEVENTF_SCANCODE;

И чтобы сделать ключ разблокировки, установите:

ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;

Полный рабочий образец приведен ниже и печатает букву «а». Вы можете найти другие коды сканирования Вот.

#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;
}

Примечание. Вы можете комбинировать нажатия клавиш (например, shift + a для A), передавая SendInput () массив структур INPUT.

21

Другие решения

Вам часто нужно установить код сканирования:

// 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));

И создание массива, как предполагает IInspectable, также определенно поможет.

4

Если вы хотите создать игрового бота, вы смотрели программу AutoHotKey?
http://www.autohotkey.com/

Он предлагает язык сценариев, который позволяет вам выполнять множество задач, связанных с созданием «ботов», и это гораздо проще, чем пытаться делать все это в C ++.

(Это, конечно, сыграло для меня в Farmville, когда вся моя семья заставила меня создать аккаунт)

1
По вопросам рекламы [email protected]