Archived

This topic is now archived and is closed to further replies.

Syrillix

PostQuitMessage() not actually posting a quit message?

Recommended Posts

Syrillix    122
This is a strange problem, but its only cropped up in the last day or so, before that it was fine. whenever i make a call to PostQuitMessage() for some reason it doesnt get posted or it gets posted at some obscure time. however if i move the window and then call it (via a key press) it gets posted properly and the app quits? does this sound strange to anyone and more importantly do any windows gurus have any idea why this could be happening? im using your usual message loop with PeekMessage() Translate and dispatch. the message loop checks for a WM_QUIT and exits the loop. every other message is handled in the WinProc. The winproc itself is just calling DefWindowProc() anyway. is windows actually holding off sending the message or is there something else wrong? Get busy livin'' or get busy dyin''... - Shawshank Redemption If a man is talking in the forest, and no woman is around to hear him, is he still wrong? - Unknown Fulcrum

Share this post


Link to post
Share on other sites
f8k8    171
It''s hard to tell without any code or anything, but maybe your PostQuitMessage() is what is being called late, rather than the actual posting of the message. Or maybe your app is waiting for something to happen before it does its'' whole PeekMessage() thing.

---------------------------------------

Let''s struggle for our dream of Game!

http://andrewporritt.4t.com

Share this post


Link to post
Share on other sites
izzo    437
As f8k8 said it''s hard to tell without any code. Where are you calling PostQuitMessage such that it doesn''t seem to be working? I assume it''s from some message in your window procedure, but which one? Post your window procedure (if it''s long just cut out the unnecessary bits).

cheers
sam

Share this post


Link to post
Share on other sites
Ademan555    361
I KNOW THE PROBLEM!!!!

I had this too, this SHOULD fix it, put PostQuitMessage(0) under a case called WM_CLOSE as well, it should make the program shut down fine

Share this post


Link to post
Share on other sites
izzo    437
WM_CLOSE is sent when the 'X' is clicked. It isn't necessary to handle this message as the default window procedure will do it for you; the default is to call DestroyWindow. DestroyWindow sends the WM_DESTROY message, thus you should make sure that you call PostQuitMessage from WM_DESTROY.

If you need to handle WM_CLOSE yourself (for example, you want to free resources or ask the user if they really want to quit) you should remember to call DestroyWindow yourself.

All you need in your window procedure is something like:


...

case WM_DESTROY:
PostQuitMessage(0);
return 0;

case WM_CLOSE:
if (MessageBox(hwnd, "Are you sure you want to exit?", "Note", MB_YESNO | MB_ICONQUESTION) == IDYES)
{
DestroyWindow(hwnd);
}
return 0;

case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
DestroyWindow(hwnd);
return 0;
}
break;


...


and then of course your message loop will terminate when it receives WM_QUIT.

It can be confusing what with all the messages going around, but the above is the "correct" way to do it (by "correct" I mean standard/Microsoft-approved/you shouldn't run into problems if you do it that way). You'll need to call DestroyWindow if you want to exit via some mechanism other than the window 'X' also (see the WM_KEYDOWN label above).

cheers
sam


[edited by - izzo on January 5, 2004 2:24:52 AM]

Share this post


Link to post
Share on other sites
JD    208
Make sure you don''t pass a valid hwnd param into GetMessage() or PeekMessage() win32 calls. Set the param to NULL. Other than that everything should go as planned.

Share this post


Link to post
Share on other sites
Syrillix    122
ok here goes..
this is the msg pump

MSG msg;
while(1){
if( PeekMessage(&msg, m_hWnd,0,0, PM_REMOVE)){
if(msg.messsage == WM_QUIT) break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
//execute is where PostQuitMessage() is being called-|

Execute();//<----------------------------------------|

}


The WinProc is, as i mentioned, in my original post just calling DefWindowProc().
Im calling PostQuitMessage() from Execute which is overridden in the subclass.
It was my understanding that PostQuitMessage() would just post a WM_QUIT message in the message queue and that it would be picked up by the message pump. Ive been using this for years without incident up until last night.
So apart from being not-MS-approved, why else would windows suddenly do this?

at any rate, im using a boolean in the base window class to test for a user quit now. now to find my copy of linux...

Get busy livin'' or get busy dyin''... - Shawshank Redemption
If a man is talking in the forest, and no woman is around to hear him, is he still wrong? - Unknown
Fulcrum

Share this post


Link to post
Share on other sites
izzo    437
Hmm yeah as the guys suggested, change the window handle parameter in PeekMessage to NULL.

That doesn''t make sense though. According to the documentation it should work both ways; specifying NULL or specifying a window handle. In fact after some testing it quits properly using either way under Windows 2000 but only quits properly using NULL under Windows XP. However if you specify a window handle, under XP it seems to quit if you move the window around (similar to what you said in your first post Syrillix).

Does anyone have any ideas as to what''s going on? The docs are somewhat confusing, in typical Microsoft fashion.

sam

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
I had a similar problem under WinXP where calling PostQuitMessage wouldn''t actually cause the program to close until I moved the window and tried again

Turned out that since the function that called PostQuitMessage was being called through Python it was in a seperate thread''s context.

I''m not 100% sure since this was some time ago, but I believe I was passing my main hWnd into PeekMessage rather than passing NULL. This caused it not to register the WM_QUIT message that was called by the Python thread (or any messages from any threads . All I know for sure is that it works fine now and PeekMessage is passing NULL for the hWnd parameter.

So if there''s a chance that you''re calling PostQuitMessage outside of the main thread (and this can be pretty well hidden), changing the hWnd to NULL would work.

Share this post


Link to post
Share on other sites
Syrillix    122
if it works, it works... i suppose.

but i dont get it. of course, i was under the assumption that windows would keep a message queue for each window handle, so passing NULL instead of the window handle would mean you were requesting messages from the desktop? as was stated above, it doesnt make sense to pass a NULL HWND to PeekMessage().

at any rate, i''d still like to know why this is the case.

Share this post


Link to post
Share on other sites
Extrarius    1412
WM_QUIT is a message that is not associated with a window, so when you only ask for messages for a certain window you should never get WM_QUIT.

[edited by - extrarius on January 5, 2004 9:34:15 PM]

Share this post


Link to post
Share on other sites
Hail to the manual:

quote:

If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread.



quote:

The WM_QUIT message indicates a request to terminate an application and is generated when the application calls the PostQuitMessage function. It causes the GetMessage function to return zero.

[...]

The WM_QUIT message is not associated with a window and therefore will never be received through a window''s window procedure. It is retrieved only by the GetMessage or PeekMessage functions.



Try checking if PeekMessage returns zero instead of checking for WM_QUIT.

Share this post


Link to post
Share on other sites
JD    208
That makes sense to me.

Syrillix, I want to apologize for my tone of voice. I didn''t realized that you were probably writing your post when I posted mine. Take care.

Share this post


Link to post
Share on other sites
izzo    437
Extrarius, I guess that makes sense but the documentation is definately still vague, despite the section that Duke posted (it doesn''t really say that explicitely, rather it says something that could mean a couple of things).

Thanks for the help!

sam


Share this post


Link to post
Share on other sites
reaction    100
This is my normal message loop...


MSG msg;
bool bQuit = false;
do
{
WaitMessage();
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT) bQuit = true;
}
if (bQuit) break;
} while (1);



... which ensures _all_ waiting messages are processed before shutdown.

Some Microsoft examples are actually _wrong_ I think, if I remember rightly.

R



[edited by - reaction on January 7, 2004 7:16:24 AM]

Share this post


Link to post
Share on other sites