After reading the answers I received during the staging phase, I realized I had fallen into a misconception.
case WM_INPUT:
{
UINT dwSize = sizeof(RAWINPUT);
static BYTE lpb[sizeof(RAWINPUT)];
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
RAWINPUT* raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEMOUSE)
{
RAWMOUSE& mouse = raw->data.mouse;
if ((mouse.usButtonFlags & RI_MOUSE_WHEEL) || (mouse.usButtonFlags & RI_MOUSE_HWHEEL))
{
short wheelDelta = (short)mouse.usButtonData;
float scrollDelta = (float)wheelDelta / WHEEL_DELTA;
if (mouse.usButtonFlags & RI_MOUSE_HWHEEL) // Horizontal
{
unsigned long scrollChars = 1; // 1 is the default
SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
scrollDelta *= scrollChars;
...
}
else // Vertical
{
unsigned long scrollLines = 3; // 3 is the default
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
if (scrollLines != WHEEL_PAGESCROLL)
scrollDelta *= scrollLines;
...
}
}
...
}
return 0;
}
This is the sample provided in the
RAWMOUSE structure documentation
for handling raw mouse input.
I had been trying to figure out how to ensure that the same physical rotation of the mouse wheel would always produce the same wheelDelta, so that the scrolling behavior in my application would be consistent. Now I realize that this may depend on the user’s own settings. For example, if the user configures a higher wheel sensitivity in the mouse driver software, the wheelDelta received in WM_INPUT will also be larger.
Rather than forcing a perfectly uniform scrolling behavior across all devices, it makes more sense to respect the user’s configuration and allow them to adjust the wheel sensitivity according to their own needs.