Reading mouse movement

Started by
8 comments, last by Servant of the Lord 17 years, 9 months ago
I haven't been programming for a few days, because I am doing art work atm. So I decide to toss together a simple screensaver, but I got stuck when it comes to mouse movement. (Using Windows XP, C++, and the Dev C++ IDE) I checked MSDN, and have been going back and forth between trying to read mouse movement or finding the mouse's current loc, in both SDL and the Window.h way of doing it, but although I found resources on MSDN and SDL.lib's official website, I can't understand it. Key presses are easy enough for me to understand, and the screensaver I made reads most any keyboard key and even the mouse buttons, but I want to be able to move the mouse to quit the program. Could someone please give me an example of how this is done? I would prefer to know the current X, Y of the mouse cursor, but simply detecting motion would work for now, and I'd prefer it in the non-SDL way, as I currently detect key-presses in GetAsyncKeyState. Thanks! I've been up for hours without figuring it out. (4-5, I think...) -Servant of the Lord P.S: What's the commands for hiding/revealing the mouse cursor as well? The one I found on MSDN I'm not using correctly, so if you can give an example of how to use that also, I would be grateful.
Advertisement
You need to be responding to WM_MOUSEMOVE messages really, either directly or through some kind of wrapper.

When you get WM_MOUSEMOVE first time, you need to store the mouse co-ords. When you get subsequent messages, you compare to the stored position and, if it is great enough (i.e. passed a threshold you define), close your program. If it is not, store the new co-ords and continue.

I handle WM_MOUSEMOVE and other Windows messages using the cracker macros in <windowsx.h> personally, as it saves having to mess about casting wParam and lParam.

HTH Paul
I was looking at WM_MOUSEMOTION on MSDN, but I don't understand how to use it. Could you give an example of how it's used or explain it? I'll go check out Windowsx.h, and see if I can understand that.
[EDIT] Actually, read the post below first before I start confusing you with message crackers. Probably not really needed in this case. [/EDIT]

Don't have any code to hand at the moment but basically WM_MOUSEMOVE is sent to your application's WndProc whenever the mouse moves. The parameters in the message contain the new X and Y position of the mouse as well as some other information about the state of the buttons etc.

<windowsx.h> crackers give you macros that you can use that take as parameters the message type and a pointer to a function to handle the message. The function pointer is set up with more meaningful parameters than examining a message directly.

If you look in <windowsx.h>, you can search and find the message you want to respond to, and a comment tells you the signature of the type of function you need.

WM_MOUSEMOVE looks a bit like this:

/* void Cls_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags) */
#define HANDLE_WM_MOUSEMOVE(hwnd, wParam, lParam, fn)

So you create a function with the same parameters as Cls_OnMouseMove in your code, then in your WndProc, inside your message switch, you do

HANDLE_WM_MOUSEMOVE(HWnd,wParam,lParam,MyMouseMoveFunction);

Where HWnd is your window handle and wParam and lParam are the parameters passed into the WndProc. The macro expands in such a way that wParam and lParam are automatically cast into the int x,int y and UINT keyFlags parameters, then your specified function is called with these parameters.

Your mouse-handling code could look a bit like:

int Mx=-1,My=-1;int Threshold=10;void MyMouseMove(HWND Hw,int X,int Y,UNIT Keys){    if(Mx>=0 && My>=0)        {        if(ABS(X-Mx)>10 || ABS(Y-My)>10)){ TellApplicationToClose(); return; }        }    Mx=X; My=Y;}HRESULT WinAPI WndProc(/* ... */){    switch(Msg)         {         HANDLE_WM_MOUSEMOVE(Hw,wParam,lParam,MyMouseMove);         default: return DefWindowProc(/* etc */);         }    return 0;}


So that until the mouse is moved by at least 10 pixels, the function will do nothing.

Sorry above code is not clear and probably full of errors but having to type it all from memory.

[Edited by - EasilyConfused on July 19, 2006 6:47:40 AM]
Not WM_MOUSEMOTION - WM_MOUSEMOVE.

This is a simple Windows message, so all you need to do is to handle it in your message loop. The parameters are not very difficult to understand:
switch (msg) {case WM_MOUSEMOVE:  { // I begin a block here because I want to create a POINT     // structure on the stack    if (wParam & MK_CONTROL) { } // control key is down    if (wParam & MK_SHIFT) { }   // shift key is down    if (wParam & MK_MBUTTON) { } // middle mouse button is down    if (wParam & MK_LBUTTON) { } // left mouse button is down    if (wParam & MK_RBUTTON) { } // right mouse button is down    POINT point;    point.x = lParam & 0x0000ffff; // low order word = x    point.y = lParam >> 16;        // high order word = y    // do what you want with the point structure  }  break;};


HTH,
Ok, I still can't get it to work. I don't understand these handles and messages, perhaps I need to take a step back and understand those first; although mouse movement shouldn't be to much harder than key presses.

Here is the holding point:
bool Quit = false;    tagPOINT OldLoc, NewLoc;    GetCursorPos(&OldLoc);    while(!Quit){    if(Key() != false){Quit = true;}            GetCursorPos(&NewLoc);    if(&NewLoc != &OldLoc){Quit = true;}}


There's a flaw in my logic here somewhere, but I can't spot it. I'm not comrehending how this(mouse movement) works. It's 4:30 in the morning now, so I guess I'll try again tomorrow. Perhaps a lack of sleep is causing the confusion.

Is there a tutorial somewhere on the whole messenge thing? I'll google up some tomorrow if you can't recommend one. What is this type of programming called? Is this Win32?

Many thanks for the help so far. And sorry about my slowness in grasping this.

-Servant of the Lord
When you go:

if(&NewLoc!=&OldLoc)

you are comparing the addresses of the tagPOINTS, not their contents. I'm not sure if you can != tagPOINTs directly. Probably not as I believe they are PODs. You may need to do

if((NewLoc.x!=OldLoc.x) || (NewLoc.y!=OldLoc.y))

or whatever their members are called.

With what you have posted above, the condition should always be true since the ADDRESS of the two tagPOINTs could never be the same.

Unless this was a typo when posting of course, in case what I have just said would be of no use at all [smile].

HTH Paul
Yeah, it works now. Thanks EasilyConfused. I'm still going to go after this particular subject though, I wish to understand it(messages) sooner or later.

Many thanks for all your help guys!

You're welcome.

Quote:Original post by Servant of the Lord
P.S: What's the commands for hiding/revealing the mouse cursor as well? The one I found on MSDN I'm not using correctly, so if you can give an example of how to use that also, I would be grateful.


ShowCursor(TRUE) and ShowCursor(FALSE) always worked for me.
Heh, yeah, but apparently SDL's fullscreen messes it up. So I'm now using SDL_ShowCursor(SDL_DISABLE) and SDL_ShowCursor(SDL_ENABLE).

This topic is closed to new replies.

Advertisement