Problem in changed mouse relative/absolute mode
KittoChanKC opened this issue · comments
I have some problem in changed mouse relative/absolute mode
In absolute Mode:
I used SetMode(MODE_RELATIVE);
when the mouse not moved, it will still is absolute Mode and still showing mouse cursor.
and i just move the mouse a little bit, it correctly changed to relative and hide the mouse,
how to solve this problem without moving the mouse?
Make sure you are passing all relevant Win32 messages to Mouse::ProcessMesage
including WM_MOUSEHOVER
in your WndProc.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
case WM_INPUT:
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEWHEEL:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP:
case WM_MOUSEHOVER:
Mouse::ProcessMessage(message, wParam, lParam);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
yes, I just copied this from document and make sure the mouse is hovering in application.
Did you also call Mouse::SetWindow
?
I came here with the same problem and think I've found the why, just not entirely sure what the best solution is.
In Mouse::SetMode()
you set the event of the new mode (mAbsoluteMode
or mRelativeMode
), then send a message to trigger Mouse::ProcessMessage()
:
Lines 1056 to 1066 in b116b58
Then in Mouse::ProcessMessage()
:
Lines 1196 to 1197 in b116b58
For me at least, the problem was occuring because Mouse::ResetScrollWheelValue()
had also been called at some point, meaning the mScrollWheelValue
event was also set, which meant that WaitForMultipleObjectsEx
returned WAIT_OBJECT_0
and handled that, and the message triggered by Mouse::SetMode
got swallowed. The actual mode change wouldn't occur until the next message handled, which was the WM_MOUSEMOVE
.
In the code I was working with, Mouse::ResetScrollWheelValue()
was being called every frame (as it seems to be in the example at https://github.com/walbourn/directxtk-tutorials/blob/c596a4785f96fd8335a06ba08d7bc2b3a04036b5/DX11/KeyboardMouseTest/Game.cpp#L90?) Which would mean the mScrollWheelValue
is going to be set every frame.
In this instance, I "fixed" it by only calling Mouse::ResetScrollWheelValue()
when the wheel value was non-zero, but it seems like there should be something more... generic? For example, would it be bad to change the order of events sent to WaitForMultipleObjectsEx
and put mScrollWheelValue
last? That way the mode change events would take priority.
Thanks for the detailed investigation. I should probably have the event handler run multiple times if something is found... Or maybe just check the wheel separately.