Sign in to follow this  
erik rostock

relative mouse position with WinApi?

Recommended Posts

Hello, is it possible to get the relative mouse position with the WinApi? Of course, I could do it like that: vRelative = vCurrent - vLast. But: I would rather like to know if the user moved the mouse, even if the curser is already at the screen border. I know that this is possible if I use DirectInput to capture mouse moves, but I would like to use WinApi for Input only. Maybe someone has a solution for me. Thank you for your answers ;) Erik

Share this post


Link to post
Share on other sites
I believe there is an api to recenter the mouse. That way you can use differences, but recenter every frame, so you don't have to worry about being at the edge of the screen.

Share this post


Link to post
Share on other sites
The mouse is owned by the user. Programmatically changing it's position is the very height of user-unfriendliness.

What you're looking is for is raw input. You can register for notifications that will give you relative mouse moves, even if the cursor is at the edge of the screen and doesn't itself move.

The docs suck but it's not hard to piece together the bits you need from the example they give.

Share this post


Link to post
Share on other sites
Okay, I've implemented Raw Input right now. Basically reading of mouse position works fine, but sometimes I am getting Raw Input data even if I don't move the mouse at all.
Is it possible that if I move the mouse there are many messages sent, and my program isn't fast enough to process all at once - so that there is big time delay between movement and taking action (in my case, move the camera).
I have to admit, I am a bit confused at this moment ... there is something strange going on in my PC :D
Maybe you can help me.
Erik

Share this post


Link to post
Share on other sites
Quote:
Original post by erik rostock
my program isn't fast enough to process all at once


This sounds like you're doing something wrong. Processing messages should be very quick, you should be able to process many messages per frame of rendering. A common mistake with Win32 is to only pull one message off the queue per frame and then update the game logic and perform rendering. Instead, you should be reading messages until the queue is empty and then performing your updates and rendering.

In the specific case of your mouse input, you may want to simply sum the movements of the mouse and come up with one final position, and then use that value to move your camera.

Share this post


Link to post
Share on other sites
Okay,
each frame I call:

-------------------------------------
MSG msg;
ZeroMemory( &msg, sizeof(msg) );

PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );
TranslateMessage( &msg );
DispatchMessage( &msg );
-------------------------------------

The Message Callback function looks as follows:
-------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
// ...
case WM_KEYDOWN:
// ...
case WM_MOUSEMOVE:
// not used any longer -> raw input
case WM_INPUT:
{
// ...
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));

if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize )
// error handling

RAWINPUT* raw = (RAWINPUT*)lpb;

if (raw->header.dwType == RIM_TYPEMOUSE) {
x = raw->data.mouse.lLastX;
y = raw->data.mouse.lLastY;
// ...
}

delete[] lpb;
} break;
}

return DefWindowProc( hWnd, msg, wParam, lParam );
}
-------------------------------------

I am not absolutely sure, but the WM_KEYDOWN / WM_MOUSEMOVE worked coorect, without any time delays.

So, is my code correct? As I said, to get the data is no problem, but it seems that I don't process WM_INPUT often enough.

Share this post


Link to post
Share on other sites
MJP is correct, you're processing one message per frame.


PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );
TranslateMessage( &msg );
DispatchMessage( &msg );


should be


while ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this