Reputation: 1242
Here's a simple, 45 line console application that reproduces the bug on my Win XP 32-bit system.
The relevant parts:
input_watcher_wndproc
belongs to a window that was set-up via RegisterRawInputDevices to watch raw keyboard input events.
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);
}
When compiled with MSVC 9 or 10, the program always incorrectly reports the device handle to be "1".
However, if I apply some seemingly non-functional changes, like transforming the switch-statement into an if-statement...
if (umsg == WM_INPUT) {
analyze_raw_input((HRAWINPUT)lparam);
DefWindowProc(hwnd, umsg, wparam, lparam);
return 0;
}
... or when adding an arbitrary instruction before the call to analyze_raw_input
...
switch(umsg) {
case WM_INPUT:
puts("foo");
analyze_raw_input((HRAWINPUT)lparam);
DefWindowProc(hwnd, umsg, wparam, lparam);
return 0;
}
...the code runs fine and outputs the corrent device handle.
Here's the modified, working source code, with just the print statement added.
Any ideas what might cause this behaviour?
Upvotes: 0
Views: 177
Reputation: 2450
Make sure to initialize 'size' to be sizeof(RAWINPUTHEADER) before calling GetRawInputData since this is an __inout parameter.
Upvotes: 2