Jump to content
  • Advertisement
Sign in to follow this  
CDProp

PostQuitMessage() not posting quit message, or something (Win32)

This topic is 3452 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

Has anyone ever had any trouble exiting a Win32 application with PostQuitMessage? For some strange reason, my application will keep running sometimes, even after I close it. I set up the window's callback procedure so that it will catch the WM_KEYDOWN message, and if the wParam is VK_ESCAPE (the escape key), then it calls PostQuitMessage(0). So far, this has worked 99% of the time (but every once in a while the program seems to continue running the background and I have to terminate itself by hitting the "stop" button in Visual Studio). I also catch the WM_CLOSE message, which is posted whenever I click the red "X" button at the top right of my window, and during the handling of this message, I also call PostQuitMessage(0). This hardly ever works. Almost always, the program continues running int the background. I can test this by putting a breakpoint in my main loop, and I can see that it's still running. What's worse about this particular situation is that, if I hit the "stop" button in Visual Studio, the IDE itself freezes until I go to my task manager and end the process (my program's process, not visual studio's process). Now, I've been reading that it's not proper just to post a quit message in these situations; that I should properly destroy the window first (it has no children). So, what I now do instead is I call DestroyWindow() for both the WM_KEYDOWN/VK_ESCAPE message and the WM_CLOSE message. Then, I handle the WM_DESTROY message, and I call PostQuitMessage(0) from there. Now, nothing works. Whether I try to close the program by hitting the Esc key or by clicking the red "X", the window disappears but the program continues running in the background, and I have to use task manager to stop it, because even though I'm running it from Visual Studio, the "stop" button in Visual Studio fails to stop the program and clicking it will actually cause VS to freeze until I manually end my program's process with the task manager. Here are some code snippets. First is my message loop, which is inside my WinMain() function. As you can see, I'm using PeekMessage, which should return false if there are no messages, and according to MSDN, it always retrieves the WM_QUIT message, if it exists.
	while(1)
	{
		if(PeekMessage(&msg, GetWindowHandle(), 0, 0, PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
				break;

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



Here are my message handlers. I have them each separated into global functions to make them easier to read:
int HandleMessage_WM_CLOSE(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
	// Just post a quit message.
	DestroyWindow(hwnd);

	return 1;
}

int HandleMessage_WM_KEYDOWN(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
	switch(wParam)
	{
	case VK_ESCAPE	:	DestroyWindow(hwnd);
						break;
	default			:	break;
	}

	return 1;
}

int HandleMessage_WM_DESTROY(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
	PostQuitMessage(0);

	return 1;
}



Those global functions are called by the window procedure. I could post the Window Procedure here, but it probably isn't important, because I've set breakpoints in each of the above functions just to make sure that the window procedure is calling them properly, and in the proper sequence, and it does. Bottom line: the WM_DESTROY handler is called, and PostQuitMessage(0) is called, but my main message loop never breaks. So, it would seem that PostQuitMessage(0) is either failing because of something awful I did, or PeekMessage() isn't retrieving it because of something awful I did. P.S. >> If you really want me to post the Window Procedure, I will, it's just a little complicated how its set up, because my GameWindow class has a list of "message handler" objects, each of which contains a function pointer to one of the above global functions, as well as a UINT to hold the ID of the message that it is meant to handle. So, each time the window procedure is called, it iterates through this list, and if the message dispatched to the window procedure matches one of the UINT id's on the list, it will call the associated function pointer. Much too complicated for my purposes, I know, but I don't think the bug lies therein, because like I said, the message handler functions are being called properly, it seems. [Please do not mark threads 'solved.' -- jpetrie] [Edited by - jpetrie on January 9, 2009 6:21:09 PM]

Share this post


Link to post
Share on other sites
Advertisement
Ugh, nevermind. After all that, I decided to change the if(PeekMessage) to a while(PeekMessage) so that it will handle all messages each loop, rather than just the first. It works now.

WM_QUIT is a low-priority message and so I guess there are just some instances where your message loop will never handle it if you don't make sure and handle all messages every frame.

Of course, I meant to do that anyway. Clearly a bug.

Oh well, haha.

Share this post


Link to post
Share on other sites
Arrgh, unsolved!

It's doing it again. Even though I've replaced the if(PeekMessage) with a while(PeekMessage), the above bug continues to occur. The only difference now (and I honestly can't tell if the difference is caused by my change) is that I can now hit the "stop debugging" button without VS freezing.

So, again, I run the program. A window comes up. If I hit the red "X" or hit escape, the window disappears, but the program continues to run and I can even place a breakpoint in my message loop and get it to break.

I can verify that PostQuitMessage(0) is being called. It's just that PeekMessage never seems to retrieve WM_QUIT.

Share this post


Link to post
Share on other sites
Try replacing GetWindowHandle() with NULL in the PeekMessage call. When destroying your window your window-handle will be invalid, which might be the cause of PeekMessage failing.
There is seldom a reason to specify the window-handle to PeekMessage. Usually, if you add more windows, you want them to be handled by the same message loop anyway. When you pass NULL, messages for all windows created by your thread will be handled by the same PeekMessage.
Here is a link to the documentation for PeekMessage, it has a lot of valuable information: http://msdn.microsoft.com/en-us/library/ms644943(VS.85).aspx

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!