使用SendInput发送两个或更多字符

Kor*_*rdy 2 c++ winapi

要发送一个字符,我们可以使用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)

那么,正确的方法是什么?

Rem*_*eau 5

第一个参数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)