4

在我正在开发的程序中,我必须模拟击键,为此我使用该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_backs 是在一个循环中完成的for,这就是为什么我input每次都完全重新定义变量。

这种方法似乎适用于除 Alt 代码之外的所有组合。我怎样才能让它们也工作?谢谢你。

PS:如您所见,dwFlags从不声明ALT (VK_LMENU)为 ExtendedKey,因为据我了解,只有VK_RMENU(而不是VK_LMENU)是这样的。这个 MSDN 页面似乎证实了这一点。

4

1 回答 1

2

Use scan codes instead of virtual keys. That injects keys a much lower level into the system and simulates real user typing more reliably than Virtual Keys.

It took me a while to find the definitive list of scan codes since there's some variances out there. But referencing the "set 1" column from the big table in the middle of this page seemed to work.

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;
}
于 2018-03-11T22:03:07.040 回答