SendInput()不等于在C++中用键盘手动按键?

Pol*_*hic 6 c++ keyboard hook winapi sendinput

我想编写一个c ++代码来模拟按键盘键"A":

// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));

// Release the "..." key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
Run Code Online (Sandbox Code Playgroud)

当我启动其他程序并等待我的程序执行时,它工作正常,单击"A"并且第一个程序对它做出反应.但是我发现在另一个应用程序中,我的动作以某种方式被阻止了(我可以在键盘上手动按"A",但使用我的程序不会导致任何动作).

那么,我能做些什么来使程序中的"A"与手动按下的"A"更相同(所以第二个程序不会识别它是从程序中调用的)?

我没有第二个程序的源代码,也不知道它是如何识别"A"没有手动按下的.

我确定我想对我的代码作出反应的窗口是前台,接收并阻止我的密钥(因此它可以决定该事件不是来自用户而是来自程序).

Dav*_*vid 22

您也可以使用SendInput()发送硬件扫描代码(与DirectInput可能忽略的虚拟扫描代码相反).它的文档记录很差,但SendInput()确实可以绕过DirectInput.Eric的解决方案不起作用的原因是他设置了硬件扫描码,但最终使用了虚拟扫描码(通过将dwFlags设置为0并将wVk设置为非零).

基本上,要设置按键,您需要设置:

ip.ki.dwFlags = KEYEVENTF_SCANCODE;
Run Code Online (Sandbox Code Playgroud)

要做一个关键版本,请设置:

ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
Run Code Online (Sandbox Code Playgroud)

下面是一个完整的工作样本,它打印字母'a'.您可以在此处找到其他扫描代码.

#define WINVER 0x0500
#include <windows.h>

using namespace std;

int main()
{

    //Structure for the keyboard event
    INPUT ip;

    Sleep(5000);

    //Set up the INPUT structure
    ip.type = INPUT_KEYBOARD;
    ip.ki.time = 0;
    ip.ki.wVk = 0; //We're doing scan codes instead
    ip.ki.dwExtraInfo = 0;

    //This let's you do a hardware scan instead of a virtual keypress
    ip.ki.dwFlags = KEYEVENTF_SCANCODE;
    ip.ki.wScan = 0x1E;  //Set a unicode character to use (A)

    //Send the press
    SendInput(1, &ip, sizeof(INPUT));

    //Prepare a keyup event
    ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
    SendInput(1, &ip, sizeof(INPUT));



    return 0;
}
Run Code Online (Sandbox Code Playgroud)

注意:您可以通过传递SendInput()INPUT结构数组来组合按键(例如,Shift + a表示A).

  • 即使我知道的更好,我搜索了unicode字符而不是扫描代码我需要的密钥.希望这个链接可以使其他人免于临时白痴:http://www.philipstorr.id.au/pcbook/book3/scancode.htm (2认同)

Eri*_*own 5

您经常需要设置扫描码:

// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
Run Code Online (Sandbox Code Playgroud)

按照 IInspectable 的建议构建一个数组也绝对是可行的方法。