SendInput()不等于在C ++中在键盘上手动按下键? [英] SendInput() not equal to pressing key manually on keyboard in C++?

查看:246
本文介绍了SendInput()不等于在C ++中在键盘上手动按下键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 键盘事件。 
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; //硬件扫描代码为
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

//按...键
ip.ki.wVk = code; //a键的虚拟键代码
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1,& ip,sizeof(INPUT));

//释放...键
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1,& ip,sizeof(INPUT));

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



所以,我可以做什么让程序中的A与手动按下A相同(因此第二个程序不会识别它是从程序中调用的)。



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



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

解决方案

您可以使用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()
{

//键盘事件的结构
INPUT ip;

睡眠(5000);

//设置INPUT结构
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0; //我们正在执行扫描代码
ip.ki.dwExtraInfo = 0;

//这让你做硬件扫描而不是虚拟按键
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
ip.ki.wScan = 0x1E; //设置要使用的unicode字符(A)

//发送新闻
SendInput(1,& ip,sizeof(INPUT));

//准备keyup事件
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1,& ip,sizeof(INPUT));



return 0;注意:您可以组合按键(例如,shift + a for A)和传递SendInput()一个INPUT结构的数组。


I wanted to write a c++ code to emulate pressing a keyboard key "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. 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).

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)?

I do not have source code of second program and do not know how it recognize that "A" wasn't pressed manually.

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). It's poorly documented, but SendInput() can indeed bypass 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).

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'. 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()不等于在C ++中在键盘上手动按下键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆