relative mouse position with WinApi?

Started by
7 comments, last by erik rostock 16 years, 1 month ago
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
Advertisement
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.
Okay, thank you
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.
-Mike
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
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.

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.
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 );}

Okay, now it works fine. Thank you for your help!!!

This topic is closed to new replies.

Advertisement