Sign in to follow this  
Shadowflare

PeekMessage()

Recommended Posts

Shadowflare    132
Greetings, I have a problem that's been hounding me and I can't figure out it's source. Basically, in a simple windows application, I'm using PeekMessage() in my main program loop to handle incoming messages. The problem is that it doesn't seem to be picking up the WM_QUIT message. Here is my WndProc and my loop:
// The WndProc function
LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	switch(nMsg)
	{
	case WM_CLOSE:
		DestroyWindow(hWnd);
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}

	return DefWindowProc(hWnd, nMsg, wParam, lParam);
}

// My program loop
BOOL bDone = FALSE;
MSG  msg;

// ...unimportant code...

while(bDone == FALSE)
{
        PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE);

	if(msg.message == WM_QUIT)
		bDone = TRUE;
        else {
             // ...game handling code...
        }

	TranslateMessage(&msgMessage);
	DispatchMessage(&msgMessage);

}

If I close my program, it destroys the window but continues to run. I'm obviously doing something wrong. Any help would be appreciated!

Share this post


Link to post
Share on other sites
Aardvajk    13207
I think you need to return 0; after you handle WM_CLOSE and WM_DESTROY, rather than let the case drop through to DefWindowProc(). Otherwise your loop and so on look very similar to some code I have to hand so I don't see any other potential causes.

I'm not sure about that though. Worth a try.


LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
switch(nMsg)
{
case WM_CLOSE:
DestroyWindow(hWnd);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hWnd, nMsg, wParam, lParam);
}




I'm also not sure if you need to call DestroyWindow() as part of WM_CLOSE. I've never handled WM_CLOSE directly and always passed that along to DefWindowProc() personally.

HTH

[EDIT] The SDK help has just confirmed that if you handle WM_CLOSE, you should return 0; after calling DestroyWindow() rather than letting DefWindowProc() have another bash at it. It also confirms that if you handle WM_DESTROY, you should return 0; I'd guess those are your problem.

Share this post


Link to post
Share on other sites
Shadowflare    132
I modified my code thus to try out your solution:


LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
switch(nMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hWnd, nMsg, wParam, lParam);

}

return 0;
}





You were right about WM_CLOSE, my program doesn't seem to even encounter it, so why clutter? :P

Returning 0 instead of DefWindowProc() didn't work though.

I actually discovered that the WM_QUIT message must be getting sent, because if I change my loop to use GetMessage() instead:


while(GetMessage(&msg, hWnd, 0, 0) > 0) // This is a no-no, I know, just for testing purposes =P
{
// ...code...

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





the program exits the way it's supposed to, even using my former WndProc(). I'm baffled by this O,o

The problem here is that my program is a game, and so GetMessage() will not work since I've got rendering going on.

Share this post


Link to post
Share on other sites
Evil Steve    2017
You should pass NULL for the hWnd parameter. WM_QUIT is a thread message, not a window message, and passing a non-NULL window handle will only give you window messages.

So always pass NULL for the hWnd parameter to PeekMessage() and GetMessage() unless you have a reason to do otherwise.

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