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

Inc*_*bus 5 c++ windows raw-input keyboard-events visual-c++

我正在尝试向应用程序发送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
Run Code Online (Sandbox Code Playgroud)

我卡住的位置至少是两个位置:

  1. 是否需要将特殊的东西传递给raw.data.keyboard.ExtraInformation,或者是GetMessageExtraInfo(),或者是否不需要在这里传递任何东西?

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

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

因此,我想实现的目标是,将输入发送到不需要处于活动状态的应用程序。

Adr*_*thy 6

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

您可能希望改用Microsoft UI 自动化

但如果你想尝试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
Run Code Online (Sandbox Code Playgroud)