SendInput() 不等于在 C++ 中手动按下键盘上的键?
我想编写一个 c++ 代码来模拟按下键盘键A":
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));
当我启动其他程序并等待我的程序执行时,它工作正常,单击A"并且第一个程序对其作出反应.但我发现在另一个应用程序中我的操作被阻止了(我可以手动按键盘上的A",但使用我的程序不会导致任何操作).
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).
那么,我可以做些什么来使从程序中按A"与手动按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"的.
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).
推荐答案
您也可以使用 SendInput() 发送硬件扫描码(与 DirectInput 可能忽略的虚拟扫描码相反).它的文档记录很差,但 SendInput() 确实可以绕过 DirectInput.Eric 的解决方案不起作用的原因是他设置了硬件扫描码,但最终使用了虚拟扫描码(通过将 dwFlags 设置为 0 并将 wVk 设置为非零).
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;
要释放密钥,设置:
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
下面是一个完整的工作示例,它会打印字母a".您可以在这里找到其他扫描码.
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;
}
注意:您可以通过向 SendInput() 传递一个 INPUT 结构数组来组合按键(例如,对于 A,shift + a).
Note: You can combine keypresses (like, shift + a for A) by passing SendInput() an array of INPUT structures.
相关文章