我对 RAWINPUT 有一些奇怪的行为。以下代码有效:
case WM_INPUT:
{
UINT rawInputSize;
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, nullptr, &rawInputSize, sizeof(RAWINPUTHEADER));
LPBYTE inputBuffer = new BYTE[rawInputSize];
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));
RAWINPUT* inp = (RAWINPUT*)inputBuffer; // valid
}
但以下不起作用:
case WM_INPUT:
{
UINT rawInputSize;
BYTE inputBuffer[40];
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER)); // returns error code
RAWINPUT* inp = (RAWINPUT*)inputBuffer;
}
也不:
case WM_INPUT:
{
UINT rawInputSize;
RAWINPUT inputBuffer;
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER)); // returns error code
}
两者都在
GetRawInputData()
处失败,返回一般错误代码(没有详细信息)。我首先发布的工作解决方案不是一个选项,我无法在每次击键或鼠标操作时进行堆分配,我必须使用堆栈。
为什么最后两个失败?
最佳答案
GetRawInputData 的第四个参数 pcbSize
有两个功能。进入时,它指定可用缓冲区的长度。退出时,它包含真正使用的数据的长度。这是 Windows API 中相当普遍的概念。
在您的第一种情况下,第一次调用时,不使用输入值,退出时仅存储所需的长度。第二个调用有效,因为所需的长度仍然存在。
但是在您的第二个和第三个示例中,您未初始化变量,因此它包含来自堆栈的随机垃圾。显然是 0
附近的东西,这使得函数失败。但这只是猜测,当然有很多方法无法正常工作,崩溃等。
您应该像这样初始化变量:
RAWINPUT inputBuffer;
UINT rawInputSize = sizeof(inputBuffer);
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));
作为旁注,在第二个示例中使用
BYTE[]
数组时要小心——一些 Alexander Belyakov 在 API 文档页面上发表了这个有用的评论:关于c++ - RAWINPUT 奇怪的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24499477/