В программе, которую я разрабатываю, я должен имитировать нажатия клавиш, и для этого я использую SendInput()
метод, передавая в качестве аргумента вектор, содержащий входные данные, которые являются частью нажатия клавиши. Мой текущий код, кажется, работает правильно со всеми тестируемыми комбинациями, кроме кодов Alt.
Это то, что я делаю в настоящее время:
// Press ALT
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_LMENU;
input.ki.wScan = 0;
input.ki.dwFlags = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
// Press NumPad2
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_NUMPAD2;
input.ki.wScan = 0;
input.ki.dwFlags = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
// Release NumPad2
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_NUMPAD2;
input.ki.wScan = 0;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
// Press NumPad1
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_NUMPAD1;
input.ki.wScan = 0;
input.ki.dwFlags = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
// Release NumPad1
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_NUMPAD1;
input.ki.wScan = 0;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
// Press NumPad2
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_NUMPAD2;
input.ki.wScan = 0;
input.ki.dwFlags = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
// Release NumPad2
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_NUMPAD2;
input.ki.wScan = 0;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
// Release ALT
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_LMENU;
input.ki.wScan = 0;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
keystroke.push_back(input);
SendInput(keystroke.size(), &keystroke[0], sizeof(keystroke[0]));
push_back
с сделано в for
цикл, поэтому я полностью переопределить input
переменная каждый раз.
Этот подход, кажется, работает для любой комбинации, исключая коды Alt. Как я могу заставить их работать тоже? Спасибо.
PS: Как вы можете заметить, dwFlags
никогда не объявляет ALT (VK_LMENU)
как ExtendedKey, так как из моего понимания только VK_RMENU
(и не VK_LMENU
) это так. Эта страница MSDN Кажется, чтобы подтвердить это.
Используйте коды сканирования вместо виртуальных ключей. Это вводит ключи в систему на гораздо более низком уровне и имитирует, что реальный пользователь печатает более надежно, чем виртуальные ключи.
Мне потребовалось некоторое время, чтобы найти окончательный список кодов сканирования, поскольку там есть некоторые различия. Но ссылаясь на столбец «установить 1» из большой таблицы в середине эта страница казалось, работает.
INPUT createScanCodeEvent(WORD scancode, bool isDown)
{
INPUT input = {};
input.type = INPUT_KEYBOARD;
input.ki.wVk = 0;
input.ki.wScan = scancode;
input.ki.dwFlags = (isDown ? 0 : KEYEVENTF_KEYUP) | KEYEVENTF_SCANCODE;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
return input;
}
int inject()
{
std::vector<INPUT> keystroke;
const WORD SCANCODE_ALT = 0x38;
const WORD SCANCODE_NUMPAD_1 = 0x4f;
const WORD SCANCODE_NUMPAD_2 = 0x50;
keystroke.push_back(createScanCodeEvent(SCANCODE_ALT, true) );
keystroke.push_back(createScanCodeEvent(SCANCODE_NUMPAD_2, true));
keystroke.push_back(createScanCodeEvent(SCANCODE_NUMPAD_2, false));
keystroke.push_back(createScanCodeEvent(SCANCODE_NUMPAD_1, true));
keystroke.push_back(createScanCodeEvent(SCANCODE_NUMPAD_1, false));
keystroke.push_back(createScanCodeEvent(SCANCODE_NUMPAD_2, true));
keystroke.push_back(createScanCodeEvent(SCANCODE_NUMPAD_2, false));
keystroke.push_back(createScanCodeEvent(SCANCODE_ALT, false));
SendInput(keystroke.size(), keystroke.data(), sizeof(keystroke[0]));
return 0;
}
Других решений пока нет …