У меня есть приложение, которое делает некоторые сложные вещи с необработанным вводом, и я хотел бы иметь некоторые автоматизированные тесты для него. Это код, который отправляет входные данные, хотя и немного урезанные, чтобы им было легче следовать.
Посылка:
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, и это все тот же результат, и у меня сейчас нет идей.
WM_INPUT
сообщение не может быть отправлено между процессами. подобно WM_PAINT
, это синтезированное сообщение, которое может быть правильно сгенерировано только самой системой. lParam
это не просто HGLOBAL
содержащий данные, это непрозрачный дескриптор, понятный только необработанному входному коду.
Исходные входные сообщения генерируются непосредственно GetMessage
/PeekMessage
внутренние органы и связанные с ними объекты очищаются DefWindowProc
, SendMessage
не будет маршал LPARAM
за WM_INPUT
потому что код для этого не был написан, поскольку он не предназначен для использования таким образом.
Других решений пока нет …