在Windows上模拟原始输入

Simulating Raw Input on Windows

本文关键字:原始 输入 模拟 Windows      更新时间:2023-10-16

我有一个应用程序,用原始输入做一些复杂的事情,我想对它进行一些自动化测试。这是发送输入的代码,尽管为了更容易理解,它被删减了一点。

发送:

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).aspxlParam: RAWINPUT结构的句柄。这来自于WM_INPUT中的lParam。"

我试过只是使用一个指针,我得到相同的错误信息。我尝试过/没有解锁,以及使用LocalAlloc/LocalLock代替。我已经尝试过与PostMessage和它都是相同的结果,我现在没有主意了。

不能在进程间发送WM_INPUT消息。像WM_PAINT一样,它是一个只能由系统本身正确生成的合成消息。lParam不只是包含数据的HGLOBAL,它是一个只有原始输入代码才能理解的不透明句柄。

原始输入消息由GetMessage/PeekMessage内部直接生成,相关对象由DefWindowProc清理。SendMessage不会为WM_INPUT封送LPARAM,因为没有编写这样做的代码,因为它不打算以这种方式使用。