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

1

9

i am trying to send a WM_INPUT-message to an application, but i encounter a few hurdles which i fail to solve. I've created the RAWINPUT-structure like the following:

//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

Where i get stuck at are at least two positions:

  1. Is there a need to pass something special to raw.data.keyboard.ExtraInformation , or is it GetMessageExtraInfo(), or is there no need to pass anything in here?

  2. 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?

I do not want to use SendInput, because it requires the window to be the active window. I already did this, and it worked fine, but when i activated another window - of course - it stopped working on the previous one.

So what I am trying to achieve is, sending input to an application that does not need to be the active one.

Enlil answered 25/9, 2012 at 19:55 Comment(1)
Are you sure you don't want to be using the SendInput function?Xylograph
K
9

All of the raw input documentation is geared toward how to handle raw messages sent to your application by the system. There's little indication it will work properly if your application sends such messages to another application. The receiving application must register to receive WM_INPUT messages, and most applications don't.

You probably want to use the Microsoft UI Automation instead.

But if you want to experiment with 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?

This is a very old API that expects you to use handles from one of the handle-based memory managers.

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
Kittiekittiwake answered 25/9, 2012 at 20:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.