简体   繁体   English

c ++ - SendInput()无法正确管理Alt代码

[英]c++ - SendInput() doesn't manage Alt codes properly

On a program that I'm developing I have to simulate keystrokes, and to do so I use the SendInput() method, passing as argument a vector containing the inputs which are part of the keystroke. 在我正在开发的程序中,我必须模拟击键,为此我使用SendInput()方法,将包含输入的向量作为参数传递,这些输入是击键的一部分。 My current code seems to work properly with all the combinations I'm testing, except Alt codes. 我目前的代码似乎可以正常使用我正在测试的所有组合,除了Alt代码。

This is what I do currently: 这就是我目前所做的事情:

// 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]));

The push_back s are done in a for cycle, that's why I entirely redefine the input variable everytime. push_back是在for循环中完成的,这就是我每次都完全重新定义input变量的原因。

This approach seems to work for every combination excluding Alt codes. 这种方法似乎适用于除Alt代码之外的所有组合。 How can I make them work too? 我怎样才能使它们也起作用? Thank you. 谢谢。

PS: As you can notice, dwFlags never declares ALT (VK_LMENU) as an ExtendedKey since from my understanding only VK_RMENU (and not VK_LMENU ) is such. PS:你可以注意到, dwFlags从不将ALT (VK_LMENU)声明为ExtendedKey,因为根据我的理解,只有VK_RMENU (而不是VK_LMENU )就是这样。 This MSDN page seems to confirm so. 这个MSDN页面似乎证实了这一点。

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. 但是,从本页中间的大表中引用“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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM