SendInput() 不等于在 C 中手动按下键盘上的键?

新手上路,请多包涵

我想编写一个 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));

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

那么,我可以做些什么来使从程序中按“A”与手动按“A”更加相同(这样第二个程序就不会识别出它是从程序中调用的)?

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

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

原文由 PolGraphic 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
1 个回答

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

本质上,要做一个你想要设置的按键:

 ip.ki.dwFlags = KEYEVENTF_SCANCODE;

要释放密钥,请设置:

 ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;

下面是一个完整的工作示例,它会打印字母“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;
}

注意:您可以通过向 SendInput() 传递一个 INPUT 结构数组来组合按键(例如,对于 A 的 shift + a)。

原文由 David 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题