Jump to content
  • Advertisement
Sign in to follow this  
bughunter2

App doesn't close when removing WM_MOUSEMOVE ?

This topic is 4149 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've stumbled upon a weird problem... For example I have this as main loop:
while(TRUE)
{
	Sleep(1);

	/* remove WM_MOUSEMOVE messages */
	while(PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));

	PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)
	{
            if (msg.message == WM_QUIT)
            {
                break;
            }

            TranslateMessage(&msg);
            DispatchMessage(&msg);
	}
}

However, WM_QUIT is never received. BUT.. if I remove the while loop of the PeekMessage (with WM_MOUSEMOVE) then WM_QUIT is received as normal. The rest of the application works just fine, only when quitting the application I never receive WM_QUIT. Could the WM_MOUSEMOVE message needed internally to quit the application? Any help would be appreciated... [Edited by - bughunter2 on May 12, 2007 9:09:30 AM]

Share this post


Link to post
Share on other sites
Advertisement
Yes, I use PostQuitMessage at WM_DESTROY and then return 0;

I want to remove the mouse messages, because when the mouse is moved inside the client area, the whole application hangs because it's only busy receiving/processing WM_MOUSEMOVE messages (even though the WM_MOUSEMOVE is passed to DefWindowProc and not handled individually).

Share this post


Link to post
Share on other sites
There's a little note in the MSDN to PeekMessage:

Note that PeekMessage always retrieves WM_QUIT messages, no matter which values you specify for wMsgFilterMin and wMsgFilterMax.


So you need to check for WM_QUIT in the WM_MOUSEMOVE loop as well.

But seriously i advise you to find the cause of the hang problem. Hang on WM_MOUSEMOVE is not usual.

Share this post


Link to post
Share on other sites
The cause might be that my mouse polling rate is at 500hz (I have a gamers mouse).
So when it receives WM_MOUSEMOVE it just keeps busy processing these.

But oops... I think I see the problem now, I have Sleep(1) at the start of my loop (I've added it in the first post too), I have the Sleep(1) there because then the CPU usage is not 99% :)

But now, when I remove that Sleep(1), the mouse stutters a little bit, but the application works fine even when moving the mouse.

Any ideas?

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
But seriously i advise you to find the cause of the hang problem. Hang on WM_MOUSEMOVE is not usual.


Because actually only the drawing hangs, this is because WM_PAINT is a lower priority message, so it is usual.

I have fixed it and could even keep Sleep(1) there to make sure the CPU usage is not rising to 99% (the application itself also doesn't need to check messages faster than 1ms, so...)

I've added PeekMessage() to the start of the loop with WM_MOUSEMOVE and PM_REMOVE.

Oh and I deleted the second check for WM_QUIT since WM_QUIT is a low-priority message and no WM_MOUSEMOVE messages will precede it, so I only need to check for WM_QUIT _after_ the first while loop that removes WM_MOUSEMOVE messages.

This is how the full loop looks now:


/* message check & dispatch loop */
while (TRUE)
{
/* short pause between each loop iteration to not overload the CPU */
Sleep(1);

while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
{}

/* check if we're quitting */
if (msg.message == WM_QUIT)
{
break;
}

/* check for a message */
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
/* we have a message */

/* translate and dispatch message */
TranslateMessage(&msg);
DispatchMessage(&msg);
}

/* run main game loop */
cMyBlocks->GameLoop();
}




So everything is fixed.

But by the way, if I would remove Sleep(1), the mouse stutters a little bit (only if it's moved inside the client area of the window). Any ideas on this?

Share this post


Link to post
Share on other sites
There's no reason to filter WM_MOUSEMOVE messages from your queue. They always represent screen pixel motion and all machines will recieve them at the same maximum rate: See Taking Advantage of High-Definition Mouse in MSDN.

You should really process all the messages in the queue and then sleep, not sleep between each individual message. A standard message pump has been fine for me (and most of the rest of the world) for years, if you find it's running to quickly then use Sleep(0) or SwitchToThread() after your game loop call.


while (true)
{
while ( ::PeekMessage(&msgTemp, NULL, 0, 0, PM_NOREMOVE) )
{
if ( !::GetMessage(&msgTemp, NULL, 0, 0 ) )
return false;
::TranslateMessage(&msgTemp);
::DispatchMessage(&msgTemp);
}
cMyBlocks->GameLoop();
}


Jans.

Share this post


Link to post
Share on other sites
Quote:
Original post by Jansic
*** Source Snippet Removed ***
Jans.


I have to tell you, I've tried the loop and it works.

However, why first PeekMessage and then GetMessage? Why not PeekMessage with PM_REMOVE?

Oh and a notice to the code, you shouldn't check if GetMessage is FALSE with a '!' in the 'if' statement. You should do if(TRUE != GetMessage(...)) because GetMessage can return -1 too, it's explained at the MSDN website.

[Edited by - bughunter2 on July 8, 2008 8:53:55 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by bughunter2I have the Sleep(1) there because then the CPU usage is not 99% :)

That's not a reason. A valid reason might be "I don't need the game to run at more than x fps, and it can do that with hardly any CPU usage". 99% CPU usage is not in itself a problem, and it won't starve out other processes. That is one of the main jobs of the OS. To ensure that all running processes get a fair chunk of CPU time. Your game can only use 99% CPU when no other processes use the CPU. If they do, they'll take their share, and you won't be able to use that much. So unless you think your name is Windows XP, you don't need to worry about this.


Quote:
But now, when I remove that Sleep(1), the mouse stutters a little bit, but the application works fine even when moving the mouse.

Don't sleep between every message. Especially not when processing messages such as WM_MOUSEMOVE, which may be sent very frequently. Read all messages, and then sleep (if you absolutely want to sleep, which, as I said above, is often pointless or self-defeating for games)

the quit message is only received when there are no other messages in the message queue. So if you insist on sleeping in between every message, you may never empty the queue, and then you'll never see the quit message floating at the end of it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Spoonbender
Quote:
Original post by bughunter2I have the Sleep(1) there because then the CPU usage is not 99% :)

That's not a reason. A valid reason might be "I don't need the game to run at more than x fps, and it can do that with hardly any CPU usage". 99% CPU usage is not in itself a problem, and it won't starve out other processes.


I _do_ think it's a valid reason because when the CPU usage is 99% it will consume more power (and get hotter) while it's unnecessary!

Quote:

the quit message is only received when there are no other messages in the message queue. So if you insist on sleeping in between every message, you may never empty the queue, and then you'll never see the quit message floating at the end of it.


Untrue, because I used PM_REMOVE before which will remove WM_MOUSEMOVE messages and finally WM_QUIT will show up.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!