Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 391
Juarrow Avatar asked Sep 25 '12 19:09

Juarrow


1 Answers

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
like image 89
Adrian McCarthy Avatar answered Oct 20 '22 04:10

Adrian McCarthy