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

我正在尝试向应用程序发送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

我被困在哪里至少有两个职位:

>是否需要将特殊内容传递给raw.data.keyboard.ExtraInformation,或者是GetMessageExtraInfo(),还是不需要传递任何内容?
> WM_INPUT消息的LPARAM参数包含RAWINPUT结构的句柄而不是地址或结构本身……如何创建这样的句柄?

我不想使用SendInput,因为它需要窗口作为活动窗口.
我已经这样做了,它工作正常,但是当我激活另一个窗口 – 当然 – 它停止了前一个工作.

所以我想要实现的是,将输入发送到不需要是活动的应用程序.

最佳答案 所有
raw input documentation都面向如何处理系统发送给您的应用程序的原始消息.如果您的应用程序将此类消息发送到另一个应用程序,则很少有迹象表明它将正常工作接收应用程序必须为
register to receive WM_INPUT messages,而大多数应用程序不必.

您可能想要使用Microsoft UI Automation.

但是如果你想试验WM_INPUT ……

The LPARAM-parameter of the WM_INPUT-message contains a handle to a RAWINPUT-structure not an address or the structure itself… How to create such a handle?

这是一个非常古老的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
点赞