Я создавал игровую программу, которая должна посылать симулированный ввод в игру (это верхнее окно на экране и работает в полноэкранном режиме). После некоторой борьбы, я наконец-то заработал движения мыши (перетаскивание курсора) и ввод с клавиатуры, но по какой-то причине игра не будет реагировать на симулированные щелчки мыши.
Я пробовал следующее:
#if TRUE // SendInput works for keyboard simulation and mouse drag, but not clicks:
INPUT mouse = {0};
mouse.type = INPUT_MOUSE;
mouse.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &mouse, sizeof(INPUT));
Sleep(100);
ZeroMemory(&mouse, sizeof INPUT);
mouse.type = INPUT_MOUSE;
mouse.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &mouse, sizeof(INPUT));
#else // tried this, but it did not work:
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
Sleep(75);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
#endif
Первой дилеммой, с которой я столкнулся, была отправка сообщений в целом, но я понял, что эта проблема была вызвана привилегиями игрового процесса> отправкой привилегий приложения. После этого я столкнулся с другой проблемой с регистрацией нажатий клавиш только на определенных игровых окнах / экранах, но после некоторого поиска я смог использовать сканкоды, чтобы преодолеть это. Например:
void SendSpacePress(bool bHardwareLevel){
INPUT space = {0};
space.type = INPUT_KEYBOARD;
space.ki.time = 0;
space.ki.dwExtraInfo = 0;
if(!bHardwareLevel){
space.ki.wVk = VK_SPACE;
}else{
space.ki.wScan = 0x39; // physical keyboard scan code
}
space.ki.dwFlags = bHardwareLevel ? KEYEVENTF_SCANCODE : 0;
SendInput(1, &space, sizeof(INPUT));
Sleep(rand()%25 + 25);
space.ki.dwFlags = bHardwareLevel ? KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP : KEYEVENTF_KEYUP;
SendInput(1, &space, sizeof(INPUT));
}
Я также смог сделать движение мыши с помощью INPUT, как показано ниже:
void PanMouse(){
INPUT mouse = {0};
mouse.type = INPUT_MOUSE;
mouse.mi.time = 0;
mouse.mi.mouseData = 0;
mouse.mi.dwExtraInfo = 0;
mouse.mi.dwFlags = MOUSEEVENTF_MOVE;
mouse.mi.dx = rand()%10 -5;
mouse.mi.dy = rand()%10 -5;
SendInput(1, &mouse, sizeof(INPUT));
}
Теперь большая проблема, с которой я столкнулся — игра отказывается регистрировать мои симулированные щелчки мышью. Я бы предпочел способ посылать ввод мышью без необходимости погружаться в зацепку. (В игре есть несколько механизмов защиты от мошенничества на стороне клиента, поэтому я рискну предположить, что любой вид перехвата стороннего процесса или внедрения DLL вызовет защиту.) Из того, что я прочитал, мне может понадобиться написать собственный драйвер для аппаратная мышь имитируется, поэтому ввод поступает на уровне ядра. Не предпочтительный вариант, но при необходимости, пусть. (И может ли кто-нибудь предоставить для этого полезную информацию? У меня никогда не было проблем с написанием драйверов, но я полагаю, что это первое время).
TL; DR: Что мне нужно сделать, чтобы получить симулированные щелчки мыши, чтобы зарегистрироваться в игре, которая, кажется, игнорирует не аппаратный ввод? (То есть, как я могу обмануть игру, думая, что щелчки мышью являются законными аналогично использованию KEYEVENTF_SCANCODE
при моделировании ввода с клавиатуры?)
Все предложения, решения и советы приветствуются. Заранее спасибо!
Вместо того, чтобы спать между входами, вам нужно ввести пару входов мыши вместе с time
Участник соответствующим образом настроен для указания «как долго».
Вот что-то близкое к тому, что вы хотите. Это щелкнет текущую позицию курсора с левой имитацией мыши в течение 100 мс.
INPUT inputs[2] = {};
inputs[0].type = INPUT_MOUSE;
inputs[0].mi.time = 0;
inputs[0].mi.dx = 0;
inputs[0].mi.dy = 0;
inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
inputs[1].type = INPUT_MOUSE;
inputs[1].mi.time = 100;
inputs[1].mi.dx = 0;
inputs[1].mi.dy = 0;
inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(2, inputs, sizeof(INPUT));
Событие мыши не произойдет сразу. Вскоре после этого происходит «очередь».
Вы должны использовать ту же технику для ваших событий клавиатуры. Не называй «Спи».
Других решений пока нет …