Using RawInput to get absolute mouse position

Started by
13 comments, last by MarkS_ 7 years, 2 months ago

Running into an odd issue. I'm using RawInput to calculate absolute mouse screen coordinates but for some reason it always reaches max dimensions (1920x1080) before the mouse actually reaches the screen.

See this - http://imgur.com/a/0qLC7 - for reference, the red rectangle is where I reach the max screen resolution (1920x1080) which is not yet at the end of the screen.

Relevant parts of the code:


WindowManager::WindowManager(const WindowSettings& settings, Logger& logger) :

	{
		assert(SetProcessDPIAware());
		
                ...

		// get initial mouse position
		POINT p;
		ZeroMemory(&p, sizeof(p));
		assert(GetCursorPos(&p));
		mMouseData.mAbsolutePos = { p.x, p.y };

		...
	}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
		switch (message)
		{

		case WM_INPUT:
		{
			RAWINPUT rawInput;
			UINT rawInputSize = sizeof(rawInput);

			GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &rawInput, &rawInputSize, sizeof(RAWINPUTHEADER));

			if (rawInput.header.dwType == RIM_TYPEKEYBOARD)
			    ProcessKeyboardInput(rawInput.data.keyboard);
			else if (rawInput.header.dwType == RIM_TYPEMOUSE)
			    ProcessMouseInput(rawInput.data.mouse);

			break;
		}

void WindowManager::ProcessMouseInput(const tagRAWMOUSE& mouseInput)
	{
		if (!mMouseButtonCallback && !mMousePositionCallback)
			return;

		mMouseData.mRelativePos.x += mouseInput.lLastX;
		mMouseData.mRelativePos.y += mouseInput.lLastY;
		mMouseData.mAbsolutePos.x += mouseInput.lLastX;
		mMouseData.mAbsolutePos.y += mouseInput.lLastY;
		VerifyAbsoluteMousePosition();

	}

void WindowManager::VerifyAbsoluteMousePosition()
	{
		static int32_t right = static_cast<int32_t>(GetSystemMetrics(SM_CXSCREEN));
		static int32_t bottom = static_cast<int32_t>(GetSystemMetrics(SM_CYSCREEN));
		static int32_t top = 0;
		static int32_t left = 0;

		// Ensure mouse coords are within the screens boundaries
		if (mMouseData.mAbsolutePos.x < left)	mMouseData.mAbsolutePos.x = left;
		if (mMouseData.mAbsolutePos.x > right)	mMouseData.mAbsolutePos.x = right;
		if (mMouseData.mAbsolutePos.y < top)	mMouseData.mAbsolutePos.y = top;
		if (mMouseData.mAbsolutePos.y > bottom)	mMouseData.mAbsolutePos.y = bottom;

		_RPT1(0, "%dx%d\n", mMouseData.mAbsolutePos.x, mMouseData.mAbsolutePos.y);
	}

Funny thing is if I replace the incrementing of absolute mouse coordinates with simply GetCursorPos() it works as expected.

Any idea what is causing this?

Advertisement
You do not want to increment the absolute position. That is the actual position of the mouse.

This:

        mMouseData.mAbsolutePos.x += mouseInput.lLastX;
        mMouseData.mAbsolutePos.y += mouseInput.lLastY;

should be:

        mMouseData.mAbsolutePos.x = mouseInput.lLastX;
        mMouseData.mAbsolutePos.y = mouseInput.lLastY;
Also, your relative mouse position is suspect. Relative to what? All you are doing is adding the current mouse position to the old relative position. For example, if your cursor is at the right edge of the screen and you move the mouse vertically, you are adding 1920 to the relative x axis with each move. Is that what you are going for?

You do not want to increment the absolute position. That is the actual position of the mouse.

This:


        mMouseData.mAbsolutePos.x += mouseInput.lLastX;
        mMouseData.mAbsolutePos.y += mouseInput.lLastY;

should be:


        mMouseData.mAbsolutePos.x = mouseInput.lLastX;
        mMouseData.mAbsolutePos.y = mouseInput.lLastY;
Also, your relative mouse position is suspect. Relative to what? All you are doing is adding the current mouse position to the old relative position. For example, if your cursor is at the right edge of the screen and you move the mouse vertically, you are adding 1920 to the relative x axis with each move. Is that what you are going for?

RAWMOUSE contains relative mouse movement afaik? (or rather it has a bit set for either absolute/relative but on my machine its definately relative)

mMouseData.mRelativePos is the mouse movement relative to last time it was queried

I did some testing and dug through Google (do you know how hard it is to find RAWPINUT examples on Google?!). It would seem that RawInput only returns relative data. It has the option to return absolute data, but doesn't.

I compiled your code without my modification and the absolute position works as expected.
This is weird, it's such a simple algorithm so I don't understand why it doesn't behave as expected

This is weird, it's such a simple algorithm so I don't understand why it doesn't behave as expected


That's what I'm saying. It DOES behave as expected, at least for me. The error has got to be at some part of your code that you're not showing. Or, try cleaning/rebuilding you project and see if that helps.

"The disadvantage is that WM_INPUT has no ballistics applied to its data, so if you want to drive a cursor with this data, extra effort will be required to make the cursor behave like it does in Windows. For more information about applying pointer ballistics, see Pointer Ballistics for Windows XP."

https://msdn.microsoft.com/en-us/library/windows/desktop/ee418864(v=vs.85).aspx

Too bad the pointer ballistics link is removed, though. Why do you want to use rawinput if you want the cursor position?

Derp

Why not get the mouse position from WM_MOUSEMOVE? You can use it in conjunction with raw input.

Why not get the mouse position from WM_MOUSEMOVE? You can use it in conjunction with raw input.

Despite what Microsoft's documentation claims, pointer acceleration isn't always desirable. Sure you can disable it using SystemParametersInfo, but that's a global setting rather than per-application.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Despite what Microsoft's documentation claims, pointer acceleration isn't always desirable.

That's an interesting detail that I didn't think of. I'm having trouble thinking of a situation where you'd want that though, do you have example?

This topic is closed to new replies.

Advertisement