如何模拟原始输入/以正确的方式向应用程序发送WM_INPUT消息

How to simulate raw input / Send a WM_INPUT message to an application the right way?

本文关键字:应用程序 方式 消息 INPUT WM 模拟 何模拟 原始 输入      更新时间:2023-10-16

我正在尝试向应用程序发送WM_INPUT消息,但我遇到了一些无法解决的障碍。我创建了如下所示的 RAWINPUT 结构:

//try sending 'W'
    RAWINPUT raw = {0};
    char c = 'W';
    //header
    raw.header.dwSize = sizeof(raw);
    raw.header.dwType = RIM_TYPEKEYBOARD;
    raw.header.wParam = 0; //(wParam & 0xff =0 => 0)
    raw.header.hDevice = hDevice;
    //data
    raw.data.keyboard.Reserved = 0;
    raw.data.keyboard.Flags = RI_KEY_MAKE;      //Key down
    raw.data.keyboard.MakeCode = static_cast<WORD>(MapVirtualKeyEx(c, MAPVK_VK_TO_VSC, GetKeyboardLayout(0)));
    raw.data.keyboard.Message = WM_KEYDOWN;
    raw.data.keyboard.VKey = VkKeyScanEx(c, GetKeyboardLayout(0));
    raw.data.keyboard.ExtraInformation = 0;         //???
    //Send the message
    SendMessage(hPSWnd, WM_INPUT, 0, (LPARAM)raw/*Raw input handle*/);      //TODO: Handle to raw input

我卡在至少两个位置:

  1. 是否需要传递一些特殊的东西给raw.data.keyboard.ExtraInformation,还是GetMessageExtraInfo(),或者没有必要在这里传递任何东西?

  2. WM_INPUT消息的 LPARAM 参数包含 RAWINPUT 结构的句柄,而不是地址或结构本身...如何创建这样的句柄?

我不想使用 SendInput,因为它要求窗口是活动窗口。我已经这样做了,并且工作正常,但是当我激活另一个窗口时 - 当然 - 它在前一个窗口上停止工作。

因此,我试图实现的是,将输入发送到不需要是活动应用程序的应用程序。

所有原始输入文档都针对如何处理系统发送到应用程序的原始消息。 几乎没有迹象表明,如果您的应用程序将此类消息发送到另一个应用程序,它将正常工作。 接收应用程序必须注册才能接收WM_INPUT消息,而大多数应用程序不会。

你可能希望改用 UI 自动化Microsoft。

但是如果你想尝试WM_INPUT...

WM_INPUT消息的 LPARAM 参数包含 RAWINPUT 结构的句柄,而不是地址或结构本身......如何创建这样的句柄?

这是一个非常古老的 API,它要求您使用来自基于句柄的内存管理器之一的句柄。

HGLOBAL hRaw = ::GlobalAlloc(GHND, sizeof(RAWINPUT));
RAWINPUT *pRaw = reinterpret_cast<RAWINPUT*>(::GlobalLock(hRaw));
// initialize the structure using pRaw
::GlobalUnlock(hRaw);
// use hRaw as the LPARAM
相关文章: