简体   繁体   English

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

[英]SendInput() not equal to pressing key manually on keyboard in C++?

I wanted to write a c++ code to emulate pressing a keyboard key "A":我想编写一个 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));

It works fine when I launch other program and wait to my program execute, the "A" is clicked and first program react to it.当我启动其他程序并等待我的程序执行时,它工作正常,单击“A”并且第一个程序对其做出反应。 But I found that in the other application my action was somehow prevented (I can manually press "A" on keyboard, but using my program do not cause any action).但是我发现在另一个应用程序中我的操作以某种方式被阻止(我可以在键盘上手动按“A”,但使用我的程序不会导致任何操作)。

So, what I can do to make pressing "A" from program more identical to manually pressed "A" (so the second program won't recognize that it was called from program)?那么,我该怎么做才能使从程序中按“A”与手动按“A”更相同(因此第二个程序无法识别它是从程序中调用的)?

I do not have source code of second program and do not know how it recognize that "A" wasn't pressed manually.我没有第二个程序的源代码,也不知道它是如何识别没有手动按下“A”的。

I'm sure that the window I want to react to my code is foreground, receive and block my key (so it can decide that event doesn't come from user but from program).我确信我想对我的代码做出反应的窗口是前台,接收并阻止我的密钥(因此它可以确定该事件不是来自用户而是来自程序)。

You can use SendInput() to send hardware scan codes as well (as opposed to virtual scan codes, which DirectInput might ignore).您也可以使用 SendInput() 发送硬件扫描代码(与 DirectInput 可能会忽略的虚拟扫描代码相反)。 It's poorly documented, but SendInput() can indeed bypass DirectInput.它的文档很差,但 SendInput() 确实可以绕过 DirectInput。 The reason Eric's solution didn't work is he set the hardware scan code, but ended up using a virtual scan code (by setting dwFlags to 0 and wVk to non-zero). Eric 的解决方案不起作用的原因是他设置了硬件扫描码,但最终使用了虚拟扫描码(通过将 dwFlags 设置为 0 并将 wVk 设置为非零)。

Essentially, to do a key press you want to set:本质上,要做一个你想设置的按键:

ip.ki.dwFlags = KEYEVENTF_SCANCODE;

And to do a key release, set:要进行密钥发布,请设置:

ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;

A full working sample is below and it prints the letter 'a'.下面是一个完整的工作示例,它打印了字母“a”。 You can find other scan codes here .您可以在此处找到其他扫描码。

#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;
}

Note: You can combine keypresses (like, shift + a for A) by passing SendInput() an array of INPUT structures.注意:您可以通过向 SendInput() 传递一个 INPUT 结构数组来组合按键操作(如 A 的 shift + a)。

You often need to set the scan code:经常需要设置扫码:

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

And building an array as IInspectable suggests is also definitely the way to go.并且按照 IInspectable 的建议构建数组也是绝对可行的方法。

If you are looking to create a game bot, have you looked at the program AutoHotKey?如果您想创建一个游戏机器人,您是否看过 AutoHotKey 程序? http://www.autohotkey.com/ http://www.autohotkey.com/

It offers a scripting language, that allows you to do a lot of the tasks involved in 'bot' creation and it's rather easier than trying to do it all in C++它提供了一种脚本语言,允许您完成“机器人”创建中涉及的许多任务,并且比尝试在 C++ 中完成所有任务要容易得多

(It certainly played Farmville for me, when all my family pressured me into creating an account) (当我所有的家人都迫使我创建一个帐户时,它确实为我播放了《Farmville》)

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

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