Отправка нажатий клавиш с перехватом
Я перепробовал все обычные способы подделки действий клавиатуры (SendInput/SendKeys/etc), но ни один из них, похоже, не работал для игр, использующих DirectInput. После долгих чтений и поисков я наткнулся на Interception, который представляет собой библиотеку C++, позволяющую подключаться к вашим устройствам.
Прошло очень много времени с тех пор, как я работал с C++ (для C# ничего не существовало), поэтому у меня возникли некоторые проблемы с этим. Я вставил в пример кода ниже.
Похоже, что в любом случае было бы инициировать ключевые действия из кода, используя это? Все примеры просто подключаются к устройствам и перезаписывают действия (x печатает клавишу y, инвертирует ось мыши и т. Д.).
enum ScanCode
{
SCANCODE_X = 0x2D,
SCANCODE_Y = 0x15,
SCANCODE_ESC = 0x01
};
int main()
{
InterceptionContext context;
InterceptionDevice device;
InterceptionKeyStroke stroke;
raise_process_priority();
context = interception_create_context();
interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);
/*
for (int i = 0; i < 10; i++)
{
Sleep(1000);
stroke.code = SCANCODE_Y;
interception_send(context, device, (const InterceptionStroke *)&stroke, 1);
}
*/
while(interception_receive(context, device = interception_wait(context), (InterceptionStroke *)&stroke, 1) > 0)
{
if(stroke.code == SCANCODE_X) stroke.code = SCANCODE_Y;
interception_send(context, device, (const InterceptionStroke *)&stroke, 1);
if(stroke.code == SCANCODE_ESC) break;
}
Код, который я закомментировал, был тем, что я попробовал, но это не сработало.
2 ответа
Вам нужно настроить состояния клавиш для состояний ВВЕРХ и ВНИЗ, чтобы получить нажатия клавиш. Обратите внимание, что в цикле while переменное устройство возвращается через interception_wait, ваш закомментированный код будет отправлять события на что?? устройство не инициализировано! Забудьте свой код и попробуйте более простой. Посмотрите на строку внутри цикла с вызовом interception_send, сделайте еще два вызова после него, но не забывайте менять значение stroke.state перед каждым вызовом, используя INTERCEPTION_KEY_DOWN и INTERCEPTION_KEY_UP, чтобы вы имитировали события down и up. Вы получите дополнительные клавиши на каждом событии клавиатуры.
Кроме того, вы можете попробовать использовать INTERCEPTION_FILTER_KEY_ALL вместо INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP. Клавиши со стрелками могут быть специальными, как указано на сайте.
void ThreadMethod()
{
while (true)
{
if (turn)
{
for (int i = 0; i < 10; i++)
{
Sleep(1000);
InterceptionKeyStroke stroke;
stroke.code = SCANCODE_Y;
stroke.state = 0;
interception_send(context, device, (const InterceptionStroke *)&stroke, 1);
Sleep(1);
stroke.state = 1;
interception_send(context, device, (const InterceptionStroke *)&stroke, 1);
turn = false;
}
}
else Sleep(1);
}
}
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadMethod, NULL, NULL, NULL);
while (interception_receive(context, device = interception_wait(context), (InterceptionStroke*)&stroke, 1) > 0)
{
if (stroke.code == SCANCODE_F5) turn = true;
interception_send(context, device, (InterceptionStroke*)&stroke, 1);
if (stroke.code == SCANCODE_ESC) break;
}