RAWINPUT奇怪的行为

RAWINPUT strange behaviour

本文关键字:RAWINPUT      更新时间:2023-10-16

我有一些奇怪的行为与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有两个功能。在进入时,它指定可用缓冲区的长度。退出时,它包含实际使用的数据的长度。

在第一种情况下,第一次调用,不使用输入值,只在退出时存储所需的长度。第二次调用可以工作,因为所需的长度仍然存在。

但是在第二个和第三个示例中,您没有初始化变量,因此它包含来自堆栈的随机垃圾。显然是接近0的东西,使功能失效。但这只是猜测,当然有很多方法不能工作,崩溃等。

你应该像这样初始化变量:

RAWINPUT inputBuffer;
UINT rawInputSize = sizeof(inputBuffer);
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));

作为一个旁注,在使用BYTE[]数组时要小心,就像你的第二个例子一样——一些Alexander Belyakov在API文档页面上做了这个有用的评论:

在Win64上,GetRawInputData将返回-1和ERROR_NOACCESS,除非pData缓冲区对齐8字节。