Can it be done? I am not familiar enough with the queue servicing
functions. They all seem to have little catch-22's that make me hesitant to
fill in the empty "else" clause below.

BOOL MyWaitWithMessageLoop(HANDLE hEvent) {
MSG msg;
DWORD dwWaitResult;
while ( TRUE ) {
dwWaitResult = MsgWaitForMultipleObjects(1, &hEvent, FALSE,
INFINITE, QS_SENDMESSAGE | QS_POSTMESSAGE);
if ( dwWaitResult == WAIT_OBJECT_0 ) return TRUE;
else {
/* empty the queue; check for WM_QUIT */
}
}
}

For example, I am tempted to say

while ( PeekMessage(&msg, hWndMe, 0, 0, TRUE) {
if ( msg.message == WM_QUIT ) return FALSE;
DispatchMessage(&msg);
}

but I read that PeekMessage() **automatically** dispatches 'sent' messages.
I also read, of GetQueueStatus(), that "The presence of a QS_ flag in the
return value does not guarantee that a subsequent call to the GetMessage or
PeekMessage function will return a message" and that makes me hesitant to
use GetQueueStatus(). How can I finish off this emulation of
AtlWaitWithMessageLoop()? Thanks.

Note that my window needn't worry about any input, timers, or anything that
deals with it's being shown (it's never shown).
--
- Vince

Re: Emulating AtlWaitWithMessageLoop? by William

William
Mon Feb 06 20:15:10 CST 2006

"Vincent Fatica" <abuse@localhost.com> wrote in message
news:43e7fcdc$1@news.vefatica.net...
> Can it be done? I am not familiar enough with the queue servicing
> functions. They all seem to have little catch-22's that make me hesitant
> to
> fill in the empty "else" clause below.

I'm not sure what you need to emulate.

> but I read that PeekMessage() **automatically** dispatches 'sent'
> messages.

That's true. There is nothing that you can do about that. SendMessage()
blocks the sender. When the receiver is in a position to receive a message,
the message will be delivered to the recipient window. And after it
processes it, the sender is unblocked and receives the result.

> I also read, of GetQueueStatus(), that "The presence of a QS_ flag in the
> return value does not guarantee that a subsequent call to the GetMessage
> or
> PeekMessage function will return a message" and that makes me hesitant to
> use GetQueueStatus(). How can I finish off this emulation of
> AtlWaitWithMessageLoop()?

It is as though only the transition from 0 messages in queue to 1 in queue
generates an notable event. You can avoid having to worry about that if you
drain the queue.

Try this:

// You'll need to special case WM_QUIT, I'm too lazy

while ( SomeConditionYouNeedToWaitOnIsTrue )
{
// Drain the queue or else

while ( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

// Wait for something an event or a message

dwStatus = MsgWaitForMultipleObjects(1, &hWhatever, FALSE, INFINITE,
QS_ALLINPUT);

// An event happened

if ( dwStatus == WAIT_OBJECT_0 )
{
// break out?
}

if ( dwStatus == WAIT_FAILED )
{
// ut oh
}
}

Regards,
Will




Re: Emulating AtlWaitWithMessageLoop? by Vincent

Vincent
Mon Feb 06 20:40:46 CST 2006

On Mon, 6 Feb 2006 21:15:10 -0500, "William DePalo [MVP VC++]"
<willd.no.spam@mvps.org> wrote:

> while ( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
> {
> TranslateMessage(&msg);
> DispatchMessage(&msg);
> }

That was part of my question. Is it OK to do that (above) considering that
"the PeekMessage function dispatches incoming sent messages" (?) ?

As I read it, any sent message will be **automatically** dispatched; it
looks like the code will try to dispatch it again.

Is that a standard way to empty the queue?
--
- Vince

Re: Emulating AtlWaitWithMessageLoop? by Doug

Doug
Mon Feb 06 21:07:50 CST 2006

On 6 Feb 2006 21:40:46 -0500, Vincent Fatica <abuse@localhost.com> wrote:

>On Mon, 6 Feb 2006 21:15:10 -0500, "William DePalo [MVP VC++]"
><willd.no.spam@mvps.org> wrote:
>
>> while ( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
>> {
>> TranslateMessage(&msg);
>> DispatchMessage(&msg);
>> }
>
>That was part of my question. Is it OK to do that (above) considering that
>"the PeekMessage function dispatches incoming sent messages" (?) ?
>
>As I read it, any sent message will be **automatically** dispatched; it
>looks like the code will try to dispatch it again.

No, the message you peeked and which is held in "msg" is not a pending sent
message. You can think of Windows maintaining a separate queue of messages
sent by other threads, that it empties when you call certain functions,
including PeekMessage, GetMessage, etc, which are considered "safe" spots
for interthread sent messages to be dispatched. Usually that's correct, but
if you're using PeekMessage in a context where you don't want to dispatch
pending interthread sent messages, you've got a bit of a Catch-22, because
AFAIK, you can't avoid dispatching them.

>Is that a standard way to empty the queue?

Yes.

--
Doug Harrison
Visual C++ MVP

Re: Emulating AtlWaitWithMessageLoop? by William

William
Mon Feb 06 21:08:54 CST 2006

"Vincent Fatica" <abuse@localhost.com> wrote in message
news:43e808ae$1@news.vefatica.net...
> On Mon, 6 Feb 2006 21:15:10 -0500, "William DePalo [MVP VC++]"
> <willd.no.spam@mvps.org> wrote:
>
>> while ( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
>> {
>> TranslateMessage(&msg);
>> DispatchMessage(&msg);
>> }
>
> That was part of my question. Is it OK to do that (above) considering
> that
> "the PeekMessage function dispatches incoming sent messages" (?) ?

Yup. GetMessage() does the same. Maybe WaitMessage() too, I forget.

> As I read it, any sent message will be **automatically** dispatched; it
> looks like the code will try to dispatch it again.

I think there is a disconnect here, but I'm not sure where exactly. :-) But
no, there is no double dipping, queue-wise.

You see, posted messages are deposited into the thread's queue, one after
the next. And in the absence of the "filter arguments" (my words) on
GetMessage() or PeekMessage() they are retrieved in their natural temporal
order.

Way back when, in the dark old days of the "co-operative" scheduler, when
all Windows applications ran on the same thread and when there was no
task-switch until a thread called GetMessage() or PeekMessage(), messages
that were sent with SendMessage() jumped the queue and were routed to a
window directly.

Nowadays, a sent message, and the sender too, is in a kind of limbo until
the receiver is ready to receive. That ready state is detected inside of
GetMessage() and PeekMessage() by Windows itself. If there is a sent message
waiting, it gets delivered post-haste.

> Is that a standard way to empty the queue?

Well, to the extent that anything is standard in Windows, I guess.

It is always a good idea to process messages as fast as you can and draining
the queue does that. If you are too slow, your user will get mad at you. :-)

On the other hand, you want to go idle, too, and not be in a constant
polling state. Polling burns cycles needlessly, hinders multi-tasking
responsiveness, drains the battery, etc. GetMessage() and
MsgWaitForMultipleEvents() do that. PeekMessage() does not.

So, GetMessage() is usually preferable because it is simple and it doesn't
pool.

The loop I wrote is not bad in that in processes messages as they arrive, is
sensitive to an event, and goes idle, too.

Does that help?

Regards,
Will




Re: Emulating AtlWaitWithMessageLoop? by Vincent

Vincent
Mon Feb 06 21:30:22 CST 2006

On Mon, 6 Feb 2006 22:08:54 -0500, "William DePalo [MVP VC++]"
<willd.no.spam@mvps.org> wrote:

>Does that help?

Yes! Thanks, Will ... Doug also.
--
- Vince

Re: Emulating AtlWaitWithMessageLoop? by Alexander

Alexander
Mon Feb 06 22:46:39 CST 2006

I think specifying PM_QS_INPUT | PM_QS_PAINT | PM_QS_POSTMESSAGE (no
PM_QS_SENDMESSAGE) in PeekMessage will not process sent messages.

"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
news:1b3gu1t2b1ut2ij8nsj5gn7eqnq18r57sv@4ax.com...
> On 6 Feb 2006 21:40:46 -0500, Vincent Fatica <abuse@localhost.com> wrote:
>
>>On Mon, 6 Feb 2006 21:15:10 -0500, "William DePalo [MVP VC++]"
>><willd.no.spam@mvps.org> wrote:
>>
>>> while ( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
>>> {
>>> TranslateMessage(&msg);
>>> DispatchMessage(&msg);
>>> }
>>
>>That was part of my question. Is it OK to do that (above) considering
>>that
>>"the PeekMessage function dispatches incoming sent messages" (?) ?
>>
>>As I read it, any sent message will be **automatically** dispatched; it
>>looks like the code will try to dispatch it again.
>
> No, the message you peeked and which is held in "msg" is not a pending
> sent
> message. You can think of Windows maintaining a separate queue of messages
> sent by other threads, that it empties when you call certain functions,
> including PeekMessage, GetMessage, etc, which are considered "safe" spots
> for interthread sent messages to be dispatched. Usually that's correct,
> but
> if you're using PeekMessage in a context where you don't want to dispatch
> pending interthread sent messages, you've got a bit of a Catch-22, because
> AFAIK, you can't avoid dispatching them.
>
>>Is that a standard way to empty the queue?
>
> Yes.
>
> --
> Doug Harrison
> Visual C++ MVP



Re: Emulating AtlWaitWithMessageLoop? by Doug

Doug
Mon Feb 06 23:21:25 CST 2006

On Mon, 6 Feb 2006 20:46:39 -0800, "Alexander Grigoriev"
<alegr@earthlink.net> wrote:

>I think specifying PM_QS_INPUT | PM_QS_PAINT | PM_QS_POSTMESSAGE (no
>PM_QS_SENDMESSAGE) in PeekMessage will not process sent messages.

Yep, you're right. It is possible to use PeekMessage without dispatching
interthread sent messages. That's very good news.

--
Doug Harrison
Visual C++ MVP