Имитация необработанного ввода в Windows

У меня есть приложение, которое делает некоторые сложные вещи с необработанным вводом, и я хотел бы иметь для него несколько автоматических тестов. Это код, который отправляет ввод, хотя и немного урезан, чтобы было легче следовать.

Отправка:

GetRawInputDeviceList(nullptr, &numDevices, sizeof(RAWINPUTDEVICELIST));
rawInputDeviceList = new RAWINPUTDEVICELIST[numDevices];
GetRawInputDeviceList(rawInputDeviceList, &numDevices, sizeof(RAWINPUTDEVICELIST));

HGLOBAL hRaw = ::GlobalAlloc(GHND, sizeof(RAWINPUT));
RAWINPUT *pRaw = reinterpret_cast<RAWINPUT*>(::GlobalLock(hRaw));
pRaw->data.keyboard.MakeCode = 30;
pRaw->data.keyboard.Flags = 0;
pRaw->data.keyboard.Reserved = 0;
pRaw->data.keyboard.VKey = 0x43;
pRaw->data.keyboard.Message = WM_KEYDOWN;
pRaw->data.keyboard.ExtraInformation = 0;
pRaw->header.dwType = RIM_TYPEKEYBOARD;
pRaw->header.dwSize = sizeof(RAWINPUT);
pRaw->header.hDevice = rawInputDeviceList[0].hDevice;
pRaw->header.wParam = (WPARAM)RIM_INPUT;
::GlobalUnlock(hRaw);

SendMessage(hWnd_, WM_INPUT, (WPARAM)RIM_INPUT, (LPARAM)hRaw);

Получение:

case WM_INPUT:
  UINT size = 0;  
  if(GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)))
    return GetLastError();

Возвращаемое значение GetLastError () - ERROR_INVALID_HANDLE (6). Однако я могу нормально прочитать ручку, если сам использую GlobalLock.

Согласно http://msdn.microsoft.com/en-us/library/windows/desktop/ms645596(v=vs.85).aspx "lParam: дескриптор структуры RAWINPUT. Это происходит из lParam в WM_INPUT."

Я пробовал просто использовать указатель и получаю то же сообщение об ошибке. Я пробовал с / без разблокировки, а также вместо этого использовал LocalAlloc / LocalLock. Я пробовал с PostMessage, и все тот же результат, и теперь у меня нет идей.


person ChrisWard1000    schedule 23.03.2014    source источник
comment
Вы пробовали вызывать GetRawInputData напрямую вместо использования SendMessage?   -  person cup    schedule 23.03.2014
comment
Вы делаете это из внешнего процесса?   -  person Ben    schedule 23.03.2014


Ответы (1)


Сообщение WM_INPUT не может быть отправлено между процессами. Как и WM_PAINT, это синтезированное сообщение, которое может быть правильно сгенерировано только самой системой. lParam - это не просто HGLOBAL, содержащий данные, это непрозрачный дескриптор, понятный только необработанному входному коду.

Сообщения Raw Input генерируются непосредственно внутренними _5 _ / _ 6_, а связанные объекты очищаются DefWindowProc. SendMessage не будет маршалировать LPARAM для WM_INPUT, потому что код для этого не был написан, поскольку он не предназначен для использования таким образом.

person Ben    schedule 23.03.2014
comment
Мое тестовое приложение - это тот же процесс, что и тестируемое. Я понимаю вашу другую точку зрения, которая мешает мне делать то, что я хочу. Я думаю, что все еще могу протестировать свое приложение, если я создам виртуальное устройство, которое может создавать сообщения с точки зрения драйверов. - person ChrisWard1000; 23.03.2014