Вопрос по c++, hook, keyboard, winapi, sendinput – SendInput () не равно нажатию клавиши на клавиатуре вручную в C ++?

6

Я хотел написать код на C ++ для эмуляции нажатия клавиши «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));

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

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

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

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

насколько мне известно. кажется, что другая программа всегда проверяет hwnd отправителя. это своего рода защита. Maher
Я также использовал keybd_event с тем же результатом. Еще спасибо за указание некоторых советов. PolGraphic
Eстьмало связанные с сообщения на OldNewThing, которые могут представлять интерес ... Bhargav Bhat
Я сомневаюсь, что этот вопрос будет идти куда угодно, пока вы не дадите более подробную информацию об этом "Вторая программа ". Hans Passant
SendInput был изобретен для решения проблем с отправкой отдельных сообщений клавиатуры в отдельных вызовахkeybd_event, Дон»т злоупотреблятьSendInput вызвав его несколько раз однимINPUT состав. Построить массивINPUT структуры и отправить их за один раз. IInspectable

Ваш Ответ

3   ответа
22

го сканирования (в отличие от кодов виртуального сканирования, которые 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;
}
</windows.h>

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

Хорошо. Но что мне нужно передать в качестве параметра wScan? Есть ли символ Unicode, представляющий щелчок мышью? Dave Chandler
Ага. Используйте ip.type = INPUT_MOUSE. David
Несмотря на то, что я знаю лучше, я искал символы юникода вместо кодов сканирования для ключа, который мне нужен. Надеюсь, эта ссылка спасет кого-то еще от временного идиотизма:philipstorr.id.au/pcbook/book3/scancode.htm JR Smith
Можно ли так же симулировать щелчок мышью? Dave Chandler
Не совсем. Структура INPUT - это объединение, а .ki - это то, чтоИспользуется для ввода с клавиатуры. Вместо этого выЯ хочу использовать поле .mi, которое представляет собой структуру, которая принимает положение мыши, событие мыши (колесо прокрутки, щелчок левой кнопкой мыши и т. д.) и длительность. Проверять, выписыватьсяэта страница MSDN David
4

// 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, также определенно поможет.

Спасибо за совет. К сожалению это неТ тоже работает. Я хочу написать игрового бота, но только в окне чата моя программа работает (она может помещать персонажей в окно чата после того, как я активирую это окно, нажав на него), но в игре (отключение чата) клавиши перестают работать (я считаю, что это какой-то фильтр, который решает, что входные данные поступают от программы, а не от пользователя). PolGraphic
@PolGraphic Игра может использовать DirectInput для получения ввода с клавиатуры. DirectInput общается напрямую с драйвером, что делает инъекцию довольно проблематичной. Различает ли игра строчную букву A и прописную букву A? Eric Brown
Когда я использую его для перемещения персонажа с помощью WSAD (я не могу сделать это из кода, работает только ручное нажатие клавиш на клавиатуре), это не делает разницы между строчными и прописными буквами в окне игрового чата (что я могу затронуть своим кодом) , это имеет значение. PolGraphic
Это подразумевает, что игра вполне может использовать DirectInput. впрыскиваниеможет быть все еще возможно, но намного сложнее; вам нужно открыть устройство с необработанной клавиатурой и отправить несколько IOCTL для ввода кодов необработанного сканирования. Я'Я не очень знаком с этими API, поэтому выпо своему усмотрению ... Eric Brown
1

вы смотрели программу AutoHotKey?http://www.autohotkey.com/

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

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

и вы можете посмотреть на это, если игра 3D -autohotkey.com/board/topic/... Strings

Похожие вопросы