Sign in to follow this  
Servant of the Lord

Reading mouse movement

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
[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]

Share this post


Link to post
Share on other sites
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,

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

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