【发布时间】:2011-06-07 00:35:37
【问题描述】:
这是一个简单的45 line console application,它重现了我的 Win XP 32 位系统上的错误。
相关部分:
input_watcher_wndproc 属于一个通过 RegisterRawInputDevices 设置的窗口,用于观察原始键盘输入事件。
LRESULT APIENTRY
input_watcher_wndproc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) {
switch(umsg) {
case WM_INPUT:
analyze_raw_input((HRAWINPUT)lparam);
DefWindowProc(hwnd, umsg, wparam, lparam);
return 0;
}
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
void analyze_raw_input(HRAWINPUT raw_input) {
RAWINPUTHEADER header;
UINT size;
GetRawInputData(raw_input, RID_HEADER, &header, &size, sizeof(RAWINPUTHEADER));
printf("raw input device handle: %d\n", header.hDevice);
}
使用 MSVC 9 或 10 编译时,程序总是错误地将设备句柄报告为“1”。
但是,如果我应用一些看似非功能性的更改,例如将 switch 语句转换为 if 语句...
if (umsg == WM_INPUT) {
analyze_raw_input((HRAWINPUT)lparam);
DefWindowProc(hwnd, umsg, wparam, lparam);
return 0;
}
...或者在调用analyze_raw_input之前添加任意指令时...
switch(umsg) {
case WM_INPUT:
puts("foo");
analyze_raw_input((HRAWINPUT)lparam);
DefWindowProc(hwnd, umsg, wparam, lparam);
return 0;
}
...代码运行良好并输出正确的设备句柄。
这是修改后的工作 source code,只添加了打印语句。
有什么可能导致这种行为的想法吗?
【问题讨论】:
-
在调用 GetRawInputData 之前尝试将 size 初始化为 sizeof(RAWINPUTHEADER)
-
完美,谢谢!我不敢相信我错过了这个。我在哪里可以了解更多关于此类错误的幕后情况?
-
每当添加或移动代码改变行为时,我总是怀疑初始化或内存践踏。当我查看GetRawInputData 的文档时,我看到 pcbSize 是 __inout 并且该大小没有初始化,所以......
-
@ribram:眼睛不错。你应该把它作为一个答案,这样它才能被接受。
标签: visual-studio winapi visual-c++