microsoft / DirectXTK

The DirectX Tool Kit (aka DirectXTK) is a collection of helper classes for writing DirectX 11.x code in C++

Home Page:https://walbourn.github.io/directxtk/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Win32 mouse input issue: WM_MOUSEWHEEL and WM_MOUSEHWHEEL

Demonese opened this issue · comments

WM_MOUSEWHEEL and WM_MOUSEHWHEEL using screen coordinate system:

lParam
The low-order word specifies the x-coordinate of the pointer, relative to the upper-left corner of the screen.
The high-order word specifies the y-coordinate of the pointer, relative to the upper-left corner of the screen.

but other mouse messages are:

lParam
The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

so it is wrong:

    if (pImpl->mMode == MODE_ABSOLUTE)
    {
        // All mouse messages provide a new pointer position
        int xPos = static_cast<short>(LOWORD(lParam)); // GET_X_LPARAM(lParam);
        int yPos = static_cast<short>(HIWORD(lParam)); // GET_Y_LPARAM(lParam);

        pImpl->mState.x = static_cast<int>(static_cast<float>(xPos) * pImpl->mScale);
        pImpl->mState.y = static_cast<int>(static_cast<float>(yPos) * pImpl->mScale);
    }

in my application, I specialize WM_MOUSEWHEEL and WM_MOUSEHWHEEL message:

	case WM_MOUSEHWHEEL:
		if (_event)
		{
			POINT pos = { GET_X_LPARAM(arg2), GET_Y_LPARAM(arg2) };
			MapWindowPoints(NULL, window, &pos, 1); // should always succeed
			_event->onPointerWheel(f32x2(0.0f, (f32)GET_WHEEL_DELTA_WPARAM(arg1) / (f32)WHEEL_DELTA), f32x2(pos.x, pos.y));
		}
		return 0;
	case WM_MOUSEWHEEL:
		if (_event)
		{
			POINT pos = { GET_X_LPARAM(arg2), GET_Y_LPARAM(arg2) };
			MapWindowPoints(NULL, window, &pos, 1); // should always succeed
			_event->onPointerWheel(f32x2(0.0f, (f32)GET_WHEEL_DELTA_WPARAM(arg1) / (f32)WHEEL_DELTA), f32x2(pos.x, pos.y));
		}
		return 0;

The documentation on Microsoft Docs for both WM_MOUSEWHEEL and WM_MOUSEHWHEEL state the exact same thing for the coordinates:

The low-order word specifies the x-coordinate of the pointer, relative to the upper-left corner of the screen.

The high-order word specifies the y-coordinate of the pointer, relative to the upper-left corner of the screen.

I also see no difference at all in your code for handling these messages. Both cases are identical. In fact, your onPointerWheel method doesn't know the difference between the scroll wheel and the horizonal scroll wheel which are independent controls when present.

In any case, I don't currently expose the horizonal scroll wheel through the Mouse abstraction since it's not a common feature on most mice. If I ever get a mouse that supports it, I'll try it out.

I have a new mouse with the HWHEEL, so I'll try that out now...

I did find a bug where in the UWP implementation of Mouse, I was merging the Vertical and Horizonal scroll wheel together, but that shouldn't impact your Win32 scenario.