Trouble with various input API's (RAWINPUT, WINAPI)
背景:
在我使用 Windows API 进行开发的大部分时间里,我一直在分别使用
感谢这个网站,键盘实现完美无缺
但是,我现在将注意力转向实现鼠标移动。据我了解,
问题是我还想在类中存储鼠标指针的客户端和屏幕空间坐标,理想情况下我想这样做而不需要同时捕获
我对
Note that the values returned are not screen space values like you get from the WM_MOUSEMOVE message. This is raw data we are getting so the values need interpreting.
这让我相信可以通过使用初始调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | // Somewhere in class header RECT m_screenMouseBounds; POINT m_mouseDelta; POINT m_mouseScreenPosition; POINT m_mouseScreenPositionGETCURSOR; RAWMOUSE m_rawMouse; // ... // Somewhere during class initialisation GetCursorPos(&m_mouseScreenPosition); // Get initial mouse cursor position // Determine maximum and minimum boundaires of current display m_screenMouseBounds.right = GetSystemMetrics(SM_CXSCREEN); m_screenMouseBounds.bottom = GetSystemMetrics(SM_CYSCREEN); m_screenMouseBounds.top = 0; m_screenMouseBounds.left = 0; // Prepare the devices for registering RAWINPUTDEVICE theInputDevices[2]; // 0 = keyboard theInputDevices[0].usUsagePage = 0x01; theInputDevices[0].usUsage = 0x06; theInputDevices[0].dwFlags = RIDEV_NOLEGACY; theInputDevices[0].hwndTarget = theWindowToHandle; // 1 = mouse theInputDevices[1].usUsagePage = 0x01; theInputDevices[1].usUsage = 0x02; theInputDevices[1].dwFlags = 0; // RIDEV_NOLEGACY theInputDevices[1].hwndTarget = theWindowToHandle; // Register each device with raw input if(RegisterRawInputDevices(theInputDevices,2,sizeof(RAWINPUTDEVICE))==FALSE) { // throw exception return false; } // ... // In the WM_INPUT processing function with parameters : (WPARAM wParam, LPARAM lParam) char inputBuffer[sizeof(RAWINPUT)] = {}; UINT inputBufferSize = sizeof(RAWINPUT); GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, inputBuffer, &inputBufferSize, sizeof(RAWINPUTHEADER)); RAWINPUT* rawData = reinterpret_cast<RAWINPUT*>(inputBuffer); if(rawData->header.dwType == RIM_TYPEMOUSE) { m_rawMouse = rawData->data.mouse; // Add the movement deltas acquired from the WM_INPUT message m_mouseDelta.x = m_rawMouse.lLastX; m_mouseDelta.y = m_rawMouse.lLastY; // Update the screen position using the delta values (Does not work as expected!) m_mouseScreenPosition.x += m_mouseDelta.x; m_mouseScreenPosition.y += m_mouseDelta.y; // Ensure mouse coords are within the screens boundaries if (m_mouseScreenPosition.x < m_screenMouseBounds.left) { m_mouseScreenPosition.x = m_screenMouseBounds.left; } if (m_mouseScreenPosition.x > m_screenMouseBounds.right) { m_mouseScreenPosition.x = m_screenMouseBounds.right; } if (m_mouseScreenPosition.y < m_screenMouseBounds.top) { m_mouseScreenPosition.y = m_screenMouseBounds.top; } if (m_mouseScreenPosition.y > m_screenMouseBounds.bottom) { m_mouseScreenPosition.y = m_screenMouseBounds.bottom; } // Double check to make sure that the screen position coordinates calculated // above match the screen coordinates as determined by Windows // using GetCursorPos() (Hint: They don't! :( ) GetCursorPos(&m_mouseScreenPositionGETCURSOR); TCHAR s[256]; swprintf(s, L"MouseDX: %ld MouseDY: %ld\ ", m_mouseDelta.x, m_mouseDelta.y); OutputDebugString(s); swprintf(s, L"MouseX(Screen(WM_INPUT)): %ld MouseY(Screen(WM_INPUT)): %ld\ ", m_mouseScreenPosition.x, m_mouseScreenPosition.y); OutputDebugString(s); swprintf(s, L"MouseX(Screen(GetCursorPos)): %ld MouseY(Screen(GetCursorPos)): %ld\ ", m_mouseScreenPositionGETCURSOR.x, m_mouseScreenPositionGETCURSOR.y); OutputDebugString(s); } |
问题是通过这种方法为
总结
我想我的全部问题是:
如果1的答案与鼠标有关而不是显示坐标:是否可以仅使用
如果 2 的答案是,我将需要使用
如果你已经做到了这一点,我非常感谢你,我很感激你能给我的任何帮助或信息。谢谢!
"请注意,返回的值不是您从 WM_MOUSEMOVE 消息中获得的屏幕空间值。这是我们获得的原始数据,因此需要解释这些值。这些值通常与最后一个位置相关,因此表示运动。确保您可以检查 RAWMOUSE 结构中的 usFlags。"从玩具制造商那里得到这个,我总是觉得很棒。这里
RAWINPUT 仅用于获取相对输入。这就是为什么它是生的。如果您真的不想使用 GetCursorPos,只需使用 WM_MOUSEMOVE 并检查 l/w 参数。
我实际上从未对 GetCursorPos() 进行过性能测试,但我已经为我自己的项目阅读了一些关于它的内容,并且从未看到任何反对意见。调用 GetCursorPos,无论您是否使用 RAWINPUT,每帧一次或每次更新都肯定可以忽略不计。我用它来旋转相机,它一直工作得很好。