Click to See Complete Forum and Search --> : How to remove WM_QUIT from message queue ?


Ali Imran
July 30th, 2005, 11:05 PM
1. Is there any way we can remove only WM_QUIT message from message queue, if it is existant ?

regards

NoHero
July 31st, 2005, 06:07 AM
You could filter it in your message loop

while ( GetMessage(&msg, hWnd, 0, 0) )
{
if ( msg.message == WM_QUIT )
{
// Do something
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

Ali Imran
July 31st, 2005, 09:31 PM
Cant we clear up the application message queue, if the next message is WM_QUIT ?

for example we have following next messages to be processed

1.WM_QUIT
2.WM_NCPAINT
3.WM_PAINT


means that the very next message is WM_QUIT, can we remove it from queue and let the application process 2 and 3 ?

Actually my need is to do this outside of message loop.

regards

philkr
August 1st, 2005, 03:43 AM
This is exactly what NoHero showed you to do.

Ali Imran
August 1st, 2005, 07:25 AM
I am sure my wordings are not clear enough, ok let me try explaining again.

1. At certain point clear the queue if very next message is WM_QUIT remove it
2. Stop all for a while, and perform few actions (e.g. display messagebox)
3. Then let the applciation continue with same message queue.

Now, does the above code do same thing? I think it dispatches all the not-WM_QUIT messages before I take further action. I want only WM_QUIT be removed from queue, then I perform the action and then let the queue continue.
I would like this be done in global view, keeping in mind that there must not be any window handle 'hWnd' involved.

Btw : thank you so much for your response.

regards

philkr
August 1st, 2005, 07:40 AM
Sorry, but I still don't understand the problem. Do you know that you can't exit your program if you don't respond to WM_QUIT message.
I reviewed NoHero's code again and you are right it does not work. The reason is that GetMessage() return 0, if WM_QUIT is received and so the while condition is not met.
My solution would be like this:

while(TRUE)
{
GetMessage(&msg, hWnd, 0, 0); // This always removes the first message from the queue
if ( msg.message == WM_QUIT )
{
// So the first message was WM_QUIT has been removed and you want to ignore it.
// Therefore you do not call DispatchMessage() here.
// You then do your few actions here.
// After that the loop continues with 'same message queue' except WM_QUIT removed
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

EDIT: If you mean, you want to remove WM_QUIT at an arbitrary position in your code not neccessarily the message loop you can use this.

MSG Msg;
PeekMessage(&Msg, hWnd, 0, 0, PM_NOREMOVE);
if(Msg.message == WM_QUIT)
{
PeekMessage(&Msg, hWnd, 0, 0, PM_REMOVE); // removes WM_QUIT
// Do your stuff here
}

Note that GetMessage() always removes the received message. With PeekMessage you can decide that with the flag (PM_REMOVE or PM_NOREMOVE). Note also: GetMessage() blocks if there is no message waiting in the queue, PeekMessage() returns 0 in that case.

SuperKoko
August 1st, 2005, 07:43 AM
You should not use WM_QUIT message for any other purpose than exiting the application.

Instead you should use a user message (WM_USER+0x1 for example), that you can post on the message queue with PostThreadMessage.
So, in the loop you can test if msg.message==(WM_USER+0x1).

kirants
August 1st, 2005, 01:00 PM
The fact that you are getting a WM_QUIT means you intend to quit. Now, why do you want to prevent that.

If there is any action you need to do before closing, why not handle the WM_CLOSE method and swallow it instead ? Or, in case of dialogs, why not trap WM_COMMAND with IDOK/IDCANCEL to perform necessary action ?

NoHero
August 2nd, 2005, 01:12 PM
while(TRUE)
{
GetMessage(&msg, hWnd, 0, 0); // This always removes the first message from the queue
if ( msg.message == WM_QUIT )
{
// So the first message was WM_QUIT has been removed and you want to ignore it.
// Therefore you do not call DispatchMessage() here.
// You then do your few actions here.
// After that the loop continues with 'same message queue' except WM_QUIT removed
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}


This code is completly correct. (Regardless that SuperKoko is completly right with his statement). Just to fix this code here:

GetMessage() can return -1 on error and that means that the given message is incorrect. Anyway your code will never return.

Just read MSDN:

Warning: Because the return value can be nonzero, zero, or -1, avoid code like this:

while (GetMessage( lpMsg, hWnd, 0, 0)) ...
The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this:

BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

stober
August 2nd, 2005, 02:28 PM
I am sure my wordings are not clear enough, ok let me try explaining again.

1. At certain point clear the queue if very next message is WM_QUIT remove it
2. Stop all for a while, and perform few actions (e.g. display messagebox)
3. Then let the applciation continue with same message queue.


MessageBox() also puts messages in the queue, so I don't think the above will work. I suppose you could put all the remaining messages in a vector or linked list (to empty the queue), do your processing, then repost all the messages. That might render all those messages useless, depending on what they are.

Ali Imran
August 3rd, 2005, 06:48 AM
Actually not the MessageBox, it is soem processing which does not send any message to any window.