c++ - 使用 SendInput 发送两个或多个字符

标签 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));

那么,怎样才是正确的做法呢?

最佳答案

SendInput()的第一个参数指定了你传入了多少个INPUT结构。你只传入了1,但是你是在告诉SendInput( ) 你正在传入 2.

您不能在单个 INPUT 中指定两个单独的虚拟键。您需要声明一个包含多个 INPUT 的数组,每个虚拟键有 2 个 INPUT - 一个用于 keydown 事件,一个用于 keyup 事件。因此,在您的示例中,您实际上需要 4 个 INPUT 来发送 2 个虚拟键,如 @user4581301 的回答所示。

现在,关于 KEYEVENTF_UNICODE,您不使用虚拟键,而是使用实际的 Unicode 代码点,它们使用 UTF-16 代码单元指定,每个 INPUT。所以这意味着如果你想发送一个需要 UTF-16 代理对的 Unicode 代码点,你需要 2 组向下/向上 INPUT,一组用于高代理,一组用于低代理。 SendInput() 文档中没有提到这个警告,但是 vScan 字段是 16 位 的事实暗示了这一点WORDKEYEVENTF_UNICODE 事件生成 WM_CHAR 消息,该消息将 UTF-16 代理代码单元作为单独的消息传递。

因此,要使用 KEYEVENTF_UNICODE 发送一串 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));
}

关于c++ - 使用 SendInput 发送两个或多个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31305404/

相关文章:

c - 我如何使用 Win32 API 启动带参数的进程?

c++ - 在 OS X 上与 clang++ 链接会产生大量未找到符号的错误

c++ - 关于C++运算符优先级的问题

windows - 在另一个窗口中运行 Windows 应用程序

CreateThread 中的转换错误

vba - 通过串口excel-vba发送字节数组失败

c++ - lldb 没有启动应用程序

c++ - Linux:未找到 Sendmail 的错误代码

c++ - std::string 在字符串中搜索数字并在前后插入空格

windows - 我是否需要分别为每个 opengl 上下文加载函数?