在我正在开发的程序中,我必须模拟击键,为此,我使用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
s是在for
周期中完成的,这就是为什么我每次都完全重新定义input
变量的原因。
这种方法似乎适用于除 Alt 代码以外的所有组合。我怎样才能让它们也工作?谢谢。
PS:正如您所注意到的,dwFlags
从不将ALT (VK_LMENU)
声明为扩展密钥,因为据我了解,只有VK_RMENU
(而不是VK_LMENU
(是这样的。此 MSDN 页面似乎证实了这一点。
使用扫描码而不是虚拟键。这会将按键注入到系统中的级别要低得多,并且比虚拟键更可靠地模拟真实用户键入。
我花了一段时间才找到扫描代码的最终列表,因为那里有一些差异。 但是引用本页中间大表中的"set 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;
}