要发送一个字符,我们可以使用SendInput。如何使用它发送多个字符?
我尝试了这段代码,但没有发送任何内容:
INPUT in;
in.type=INPUT_KEYBOARD;
in.ki.wScan=0;
in.ki.time=0;
in.ki.dwExtraInfo=0;
in.ki.wVk=0x53+0x54;
SendInput(2,&in,sizeof(INPUT));
Run Code Online (Sandbox Code Playgroud)
那么,正确的方法是什么?
第一个参数SendInput()指定INPUT要传入的结构数。您仅传入1,但您却告诉SendInput()您传入2。
您不能在一个中指定两个单独的虚拟键INPUT。您需要声明一个由多个INPUTs组成的数组,每个虚拟键一个,并且不要忘记INPUT为每个虚拟键包括2个-一个用于keydown事件,一个用于keyup事件。因此,在您的示例中,您实际上需要4 INPUT秒钟来发送2个虚拟密钥,如@ user4581301的答案所示。
现在,关于KEYEVENTF_UNICODE,您不再使用虚拟键,而是使用实际的Unicode代码点,它们使用UTF-16代码单元(每个1个)指定INPUT。因此,这意味着如果要发送需要UTF-16代理对的Unicode代码点,则需要2 INPUTs,一个用于高代理,一个用于低代理。即警告被NOT中提到的SendInput()文件,但它是由一个事实,即隐含vScan字段是16位WORD,而KEYEVENTF_UNICODE事件产生WM_CHAR消息,这通过UTF-16替代CODEUNITS作为单独的消息。
因此,要使用发送字符串Unicode字符KEYEVENTF_UNICODE,您可以执行以下操作:
#include <vector>
#include <string>
void SendInputString(const std::wstring &str)
{
int len = str.length();
if (len == 0) return;
std::vector<INPUT> in(len*2);
ZeroMemory(&in[0], in.size()*sizeof(INPUT));
int i = 0, idx = 0;
while (i < len)
{
WORD ch = (WORD) str[i++];
if ((ch < 0xD800) || (ch > 0xDFFF))
{
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = ch;
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx] = in[idx-1];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
}
else
{
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = ch;
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = (WORD) str[i++];
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx] = in[idx-2];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
in[idx] = in[idx-2];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
}
}
SendInput(in.size(), &in[0], sizeof(INPUT));
}
Run Code Online (Sandbox Code Playgroud)