Kai*_*aan 3 c++ winapi raw-input
我对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
}
Run Code Online (Sandbox Code Playgroud)
但以下不起作用:
case WM_INPUT:
{
UINT rawInputSize;
BYTE inputBuffer[40];
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER)); // returns error code
RAWINPUT* inp = (RAWINPUT*)inputBuffer;
}
Run Code Online (Sandbox Code Playgroud)
也不:
case WM_INPUT:
{
UINT rawInputSize;
RAWINPUT inputBuffer;
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER)); // returns error code
}
Run Code Online (Sandbox Code Playgroud)
两者都失败GetRawInputData(),返回一般错误代码(没有详细信息).
我首先发布的工作解决方案不是一个选项,我不能在每次按键或鼠标操作时进行堆分配,我必须使用堆栈.
为什么这两个最后都失败了?
Yir*_*kha 10
第四届参数GetRawInputData,pcbSize有两个功能.输入时,它指定可用缓冲区的长度.退出时,它包含实际使用数据的长度.这是Windows API中相当常见的概念.
在第一种情况下,第一次调用时,不使用输入值,并且在退出时仅存储所需的长度.第二个调用有效,因为所需的长度仍然存在.
但是在你的第二个和第三个例子中,你将变量保持为未初始化,因此它包含来自堆栈的随机垃圾.显然近在咫尺0,这使得功能失败了.但这只是猜测,当然有很多方法可以解决这个问题,崩溃等等.
你应该像这样初始化变量:
RAWINPUT inputBuffer;
UINT rawInputSize = sizeof(inputBuffer);
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));
Run Code Online (Sandbox Code Playgroud)
作为附注,BYTE[]在第二个示例中使用该数组时要小心- 一些Alexander Belyakov在API文档页面上做了这个有用的评论:
在Win64上,GetRawInputData将使用ERROR_NOACCESS返回-1,除非pData缓冲区由8个字节对齐.
| 归档时间: |
|
| 查看次数: |
1124 次 |
| 最近记录: |