如何通过程序发送硬件级键盘输入?

How to send hardware level keyboard input by program?

我一直在使用 keybd_event 通过命令行进行键盘输入。但是,想要一些可以发送硬件级输入的东西,就像真正的键盘一样。

有什么适合我的目的吗?

我正在使用 Windows 作为操作系统。

我曾经用SendInput控制过一个游戏角色。游戏(冰塔?)正在使用 directx 输入系统(我认为?)并且它以某种方式忽略了 keybd_event 调用,但此方法有效。我不知道你需要多接近硬件,但这对我来说是个把戏。我使用了虚拟键码,但将它们变成了这个答案的扫描码。

UINT PressKeyScan(WORD scanCode)
{
    INPUT input[1] = {0};
    input[0].type = INPUT_KEYBOARD;
    input[0].ki.wVk = NULL;
    input[0].ki.wScan = scanCode;
    input[0].ki.dwFlags = KEYEVENTF_SCANCODE;

    UINT ret = SendInput(1, input, sizeof(INPUT));

    return ret;
}

UINT ReleaseKeyScan(WORD scanCode)
{
    INPUT input[1] = {0};
    input[0].type = INPUT_KEYBOARD;
    input[0].ki.wVk = NULL;
    input[0].ki.wScan = scanCode;
    input[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;


    UINT ret = SendInput(1, input, sizeof(INPUT));

    return ret;
}

要模拟按下和释放,您可以按顺序使用它们(或者您可以为使用相同 INPUT 结构的按下和释放创建一个单独的函数)。

WORD scanCodeSpace = 0x39;
PressKeyScan(scanCodeSpace);
ReleaseKeyScan(scanCodeSpace)

您可以使用MapVirtualKeyA从虚拟键码中获取扫描码。

keybd_event() 已弃用,请改用 SendInput()

SendInput() 将其模拟事件发布到硬件驱动程序将其事件发布到的同一队列,如下图来自 Raymond Chen 的博客:

When something gets added to a queue, it takes time for it to come out the front of the queue