Discussion:
How does PeekMessage really work?
(too old to reply)
Denis Adamchuk
2008-09-08 09:12:00 UTC
Permalink
Hi everyone,

I'm writing an application where Windows messages are used in a special
manner and want to clarify how flexible is access to the thread message queue.
I've read the MSDN article about PeekMessage and many web sites where
different opinions are expressed. My questions are the following...

1) What really does PeekMessage()?
Does it process messages sent from other threads by means of
SendMessage-family routines or just picks a message from the queue (or from
where?) and give me a chance to analyze it and process it by myself?

2) Does PeekMessage process ALL sent messages that are available now or only
one of them?

3) According to the MSDN - PeekMessage() does both things I've mentioned
above.
But what do wMsgFilterMin and wMsgFilterMax arguments mean?
Does PeekMessage pick from the queue messages from identifiers from the
range or does it process only such messages sent to the current thread?

4) The most confusing one :)
What is tuned by PM_QS_*** flags - behavior for implicit message processing
or behavior for message picking?
If PM_QS*** define what messages I want to proceed why there are any flags
except the PM_QS_SENDMESSAGE (since PeekMessage() is devoted to process only
SendMessage() messages)?
Otherwise if PM_QS*** define what messages I want to pick why there is the
PM_QS_SENDMESSAGE flag if the messages that were sent will be processed
implicitly and I never get them as a result?

5) PeekMessage() does not fill lpMsg output parameter with a message(s) it
has processed?

6) Is it possible to disable an implicit message processing inside
PeekMessage() and make it to return as lpMsg messages that were sent from
another threads via SendMessage-routines BUT only within a defined range?

7) What is PM_NOYIELD?

Thanks in advance!
It will be great if this post become a consolidated place of information
about PeekMessage() for those who search...
AliR (VC++ MVP)
2008-09-08 15:38:55 UTC
Permalink
See Below.....
Post by Denis Adamchuk
Hi everyone,
I'm writing an application where Windows messages are used in a special
manner and want to clarify how flexible is access to the thread message queue.
I've read the MSDN article about PeekMessage and many web sites where
different opinions are expressed. My questions are the following...
1) What really does PeekMessage()?
Does it process messages sent from other threads by means of
SendMessage-family routines or just picks a message from the queue (or from
where?) and give me a chance to analyze it and process it by myself?
PeekMessage retrieves a message from the calling thread's message queue, it
doesn't care if was sent view SendMessage or PostMessage. PeekMessage does
not process the message, that's job of the winproc to process messages (this
happens during the call to DispatchMessage), PeekMessage simply returns the
message that is at the top of the queue.
Post by Denis Adamchuk
2) Does PeekMessage process ALL sent messages that are available now or only
one of them?
PeekMessage returns one message at a time. Again it does not process message
simply returns a message. Not that wRemoveMsg parameter let you tell it to
either remove the message if you are calling PeekMessage to process the
message after you receive it, or to leave it in the queue, if you are
calling PeekMessage just out of curiousity and won't really be processing
the message. See GetMessage if you always want to remove the message from
the queue.
Post by Denis Adamchuk
3) According to the MSDN - PeekMessage() does both things I've mentioned
above.
But what do wMsgFilterMin and wMsgFilterMax arguments mean?
Does PeekMessage pick from the queue messages from identifiers from the
range or does it process only such messages sent to the current thread?
wMsgFilterMin and wMsgFilterMax is used to only receive back message in the
specified range. And simply won't return any messages outside of that
range.
Post by Denis Adamchuk
4) The most confusing one :)
What is tuned by PM_QS_*** flags - behavior for implicit message processing
or behavior for message picking?
If PM_QS*** define what messages I want to proceed why there are any flags
except the PM_QS_SENDMESSAGE (since PeekMessage() is devoted to process only
SendMessage() messages)?
Otherwise if PM_QS*** define what messages I want to pick why there is the
PM_QS_SENDMESSAGE flag if the messages that were sent will be processed
implicitly and I never get them as a result?
I have never used these before, but the docs say that they filter message by
type. Kind of like FilterMin and FilterMax
Post by Denis Adamchuk
5) PeekMessage() does not fill lpMsg output parameter with a message(s) it
has processed?
I don't understand questions 5, and 6
Post by Denis Adamchuk
6) Is it possible to disable an implicit message processing inside
PeekMessage() and make it to return as lpMsg messages that were sent from
another threads via SendMessage-routines BUT only within a defined range?
7) What is PM_NOYIELD?
PM_NOYIELD will make user that no other threads are released during the call
to PeekMessage. Explaining this one will take a couple of pages. each
thread in your application gets a time slice of the processer. So a thread
will run for a while and when it becomes idle the processor is given to
another thread in your app, and so far and so forth. Callling PeekMessage
might cause another thread to take over momentarily, PM_NOYIELD will pervent
that from happening.
Post by Denis Adamchuk
Thanks in advance!
It will be great if this post become a consolidated place of information
about PeekMessage() for those who search...
AliR.
Malachy Moses
2008-09-08 17:51:44 UTC
Permalink
See in-line, below ...
Post by AliR (VC++ MVP)
Post by Denis Adamchuk
Hi everyone,
I'm writing an application where Windows messages are used in a special
manner and want to clarify how flexible is access to the thread message queue.
I've read the MSDN article about PeekMessage and many web sites where
different opinions are expressed. My questions are the following...
1) What really does PeekMessage()?
Does it process messages sent from other threads by means of
SendMessage-family routines or just picks a message from the queue (or from
where?) and give me a chance to analyze it and process it by myself?
PeekMessage retrieves a message from the calling thread's message queue, it
doesn't care if was sent view SendMessage or PostMessage.  PeekMessage does
not process the message, that's job of the winproc to process messages (this
happens during the call to DispatchMessage), PeekMessage simply returns the
message that is at the top of the queue.
This incorrectly infers that a message sent by SendMessage somehow
ends up in the message queue. It doesn't. A message sent by
SendMessage is a non-queued message that does not end up in the
message queue, and is not retrievable by a call to PeekMessage (or a
call to GetMessage).

A message sent by SendMessage calls the target window's WinProc
directly, without going through the message queue. If the thread
calling SendMessage is the same thread as the target window, then a
call to SendMessage is very much like a simple function call, that
calls the WinProc for the target window. If the are in different
threads, then the process is more complicated, but the end result is
the same in that sent messages are non-queued messages that bypass the
message queue and do not somehow end up in the message queue.

On the other hand, messages posted by PostMessage end up in the
message queue, together with other messages that get routed through
the message queue (like timer messages, paint messages, system
messages, keyboard messages, etc.) It's only if the message resides
in the message queue that the message can be retrived by calls to
PeekMessage or GetMessages.

As one explanation, see Paul DiLascia's C++ Q&A column from December
2000, "Sending Messages in Windows" at http://msdn.microsoft.com/en-us/magazine/cc301431.aspx
Post by AliR (VC++ MVP)
Post by Denis Adamchuk
2) Does PeekMessage process ALL sent messages that are available now or only
one of them?
PeekMessage returns one message at a time. Again it does not process message
simply returns a message.  Not that wRemoveMsg parameter let you tell it to
either remove the message if you are calling PeekMessage to process the
message after you receive it, or to leave it in the queue, if you are
calling PeekMessage just out of curiousity and won't really be processing
the message.  See GetMessage if you always want to remove the message from
the queue.
PeekMessage will not process *any* sent messages, for the reason that
messages sent by using SendMessage will not go into the message queue.


<snip, I am not responding to the remainder of this post.>
AliR (VC++ MVP)
2008-09-08 18:48:54 UTC
Permalink
My bad, I keep forgetting that.

BTW, here is a link that explains all of this in more detail. Also some
difference between PeekMessage and GetMessage:

http://msdn.microsoft.com/en-us/library/ms644928(VS.85).aspx

AliR.




"Malachy Moses" <***@gmail.com> wrote in message news:7d1a0aff-3fa0-41d3-851f-***@q26g2000prq.googlegroups.com...
See in-line, below ...
Post by AliR (VC++ MVP)
Post by Denis Adamchuk
Hi everyone,
I'm writing an application where Windows messages are used in a special
manner and want to clarify how flexible is access to the thread message queue.
I've read the MSDN article about PeekMessage and many web sites where
different opinions are expressed. My questions are the following...
1) What really does PeekMessage()?
Does it process messages sent from other threads by means of
SendMessage-family routines or just picks a message from the queue (or from
where?) and give me a chance to analyze it and process it by myself?
PeekMessage retrieves a message from the calling thread's message queue, it
doesn't care if was sent view SendMessage or PostMessage. PeekMessage does
not process the message, that's job of the winproc to process messages (this
happens during the call to DispatchMessage), PeekMessage simply returns the
message that is at the top of the queue.
This incorrectly infers that a message sent by SendMessage somehow
ends up in the message queue. It doesn't. A message sent by
SendMessage is a non-queued message that does not end up in the
message queue, and is not retrievable by a call to PeekMessage (or a
call to GetMessage).

A message sent by SendMessage calls the target window's WinProc
directly, without going through the message queue. If the thread
calling SendMessage is the same thread as the target window, then a
call to SendMessage is very much like a simple function call, that
calls the WinProc for the target window. If the are in different
threads, then the process is more complicated, but the end result is
the same in that sent messages are non-queued messages that bypass the
message queue and do not somehow end up in the message queue.

On the other hand, messages posted by PostMessage end up in the
message queue, together with other messages that get routed through
the message queue (like timer messages, paint messages, system
messages, keyboard messages, etc.) It's only if the message resides
in the message queue that the message can be retrived by calls to
PeekMessage or GetMessages.

As one explanation, see Paul DiLascia's C++ Q&A column from December
2000, "Sending Messages in Windows" at
http://msdn.microsoft.com/en-us/magazine/cc301431.aspx
Post by AliR (VC++ MVP)
Post by Denis Adamchuk
2) Does PeekMessage process ALL sent messages that are available now or only
one of them?
PeekMessage returns one message at a time. Again it does not process message
simply returns a message. Not that wRemoveMsg parameter let you tell it to
either remove the message if you are calling PeekMessage to process the
message after you receive it, or to leave it in the queue, if you are
calling PeekMessage just out of curiousity and won't really be processing
the message. See GetMessage if you always want to remove the message from
the queue.
PeekMessage will not process *any* sent messages, for the reason that
messages sent by using SendMessage will not go into the message queue.


<snip, I am not responding to the remainder of this post.>
Denis Adamchuk
2008-09-08 20:53:01 UTC
Permalink
Guys, I'm totally confused now.

At http://msdn.microsoft.com/en-us/library/ms644943(VS.85).aspx
I see the following in the Remarks section:
"During this call, the system delivers pending, nonqueued messages, that is,
messages sent to windows owned by the calling thread using the SendMessage,
SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then
the first queued message that matches the specified filter is retrieved. The
system may also process internal events."

Doesn't it mean that PeekMessage DO process sent messages?

Malachy, you insist that PeekMessage() does not process sent messages and
retrieves only posted messages from the message queue (I understand that sent
messages go to "another place" anyway). Could you please tell me what is the
purpose of the PM_QS_SENDMESSAGE flag?

Concerning PM_NOYIELD. AliR, do you mean that this flag prevents the context
switching? I thought its impossible.

Thanks.
AliR (VC++ MVP)
2008-09-08 21:02:26 UTC
Permalink
Post by Denis Adamchuk
Guys, I'm totally confused now.
Concerning PM_NOYIELD. AliR, do you mean that this flag prevents the context
switching? I thought its impossible.
Thanks.
Thats what the doc says:
"You can optionally combine the value PM_NOYIELD with either PM_NOREMOVE or
PM_REMOVE. This flag prevents the system from releasing any thread that is
waiting for the caller to go idle (see WaitForInputIdle)."
Alexander Grigoriev
2008-09-10 03:28:31 UTC
Permalink
This is different thing. WaitForInputIdle waits for a special event
associated with a process, which is set on any GetMessage-type call. THis
flag makes sure the event won't be set at PeekMessage,
Post by AliR (VC++ MVP)
Post by Denis Adamchuk
Guys, I'm totally confused now.
Concerning PM_NOYIELD. AliR, do you mean that this flag prevents the context
switching? I thought its impossible.
Thanks.
"You can optionally combine the value PM_NOYIELD with either PM_NOREMOVE
or PM_REMOVE. This flag prevents the system from releasing any thread that
is waiting for the caller to go idle (see WaitForInputIdle)."
Malachy Moses
2008-09-08 22:12:17 UTC
Permalink
See in-line below ....

On Sep 8, 1:53 pm, Denis Adamchuk
Post by Denis Adamchuk
Guys, I'm totally confused now.
Athttp://msdn.microsoft.com/en-us/library/ms644943(VS.85).aspx
"During this call, the system delivers pending, nonqueued messages, that is,
messages sent to windows owned by the calling thread using the SendMessage,
SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then
the first queued message that matches the specified filter is retrieved. The
system may also process internal events."
Doesn't it mean that PeekMessage DO process sent messages?
No it doesn't mean that. Read the documentation again carefully. The
system *delivers* these messages *during* the call to PeekMessage.
Thus, before PeekMessage returns, all sent messages are dispatched
automatically. You don't get these messages back as a result from the
call to PeekMessage. In fact, the documentation explicitly states
that such messages are "nonqueued".

This is the "more complicated" part that I mentioned above, and refers
to a situation where SendMessage has been called from a thread
different from the thread that manages the window's message queue.
Such messages are accumulated in a "separate place" (using the words
of Raymond Chen) that is different from the message queue. Since they
are not queued messages, they must be processed separately from the
message queue. The timing at which they are processed is a priority
timing, ahead of messages in the queue. Thus, when the thread that
manages the window's queue is re-awakened, as soon as it calls a
function like PeekMessage or GetMessage, any messages that are in the
"separate place" are dispatched automatically to the WindProc, after
which queued messages are returned for manual dispatching by your
program (i.e., in your program's call to DispatchMessage).

For more information, read this thread from Raymond Chen's blog Old
New Thing: "The various ways of sending a message" at
http://blogs.msdn.com/oldnewthing/archive/2004/11/19/266664.aspx .
The comments are where the meat of the information resides. For
example, selected and re-ordered comments tell us the following:

"When SendMessage() is used to send a message to a window in *this*
thread, the window procedure is called immediately by SendMessage().

"When you post messages using PostMessage, regardless of whether you
are posting from *this* thread or another thread, the messages go into
"the message queue".

"When you send messages to another thread using SendMessage, they
don't technically go into "the message queue" but rather a "separate
place".

"When the thread that owns the window calls a Win32 API function that
directly or indirectly looks at this "separate place" (such as
PeekMessage or GetMessage), the system first checks if there are any
messages in the "separate place" and dispatches them all automatically
(i.e., automatically calls the window procedure). The system then
checks "the message queue" and returns the first matching message."
Post by Denis Adamchuk
Malachy, you insist that PeekMessage() does not process sent messages and
retrieves only posted messages from the message queue (I understand that sent
messages go to "another place" anyway). Could you please tell me what is the
purpose of the PM_QS_SENDMESSAGE flag?
I have never used PM_QS_SENDMESSAGE, and can't talk definitively.
That was one of the questions in the blog I linked to, and the
question remained unanswered. However, according to the documentation
that you linked to, it apparently "Process[es] all sent messages",
which fits into the explanation quoted above.
Denis Adamchuk
2008-09-09 16:39:01 UTC
Permalink
Malachy, thanks for your explanation.

I've carefully read the article by Raymond.

In the OldNewThing discussion I found a similar question about inter-thread
sent messages which are kept in a "separate place". This one is very
important for me now but it is still unanswered:
"Can I retrieve sent messages as if they were posted messages, and then
dispatch them? I would like to be able to filter out, for example, Shatter
attacks. "

In other words I would like to disable sent messages to be processed
(dispatched) within PeekMessage or allow it only for group of messages
(filter by ID).

I suppose the root cause of my confusion is the PM_QS_SENDMESSAGE.
I still don't understand how this flag affect the PeekMessage() execution.
In my application PeekMessage() delivers sent messages to the WndProc in the
both cases:
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_SENDMESSAGE);

Moreover, when I set all PM_QS_* flags except PM_QS_SENDMESSAGE
PeekMessage() does the same.

Don't you know any newsgroup where could I address my question?
May be microsoft.public.vc.mfc is not the appropriate one but my post to the
microsoft.public.win32.programmer.ui didn't recieve any replies at all.

Thanks a lot!
Post by Malachy Moses
See in-line below ....
On Sep 8, 1:53 pm, Denis Adamchuk
Post by Denis Adamchuk
Guys, I'm totally confused now.
Athttp://msdn.microsoft.com/en-us/library/ms644943(VS.85).aspx
"During this call, the system delivers pending, nonqueued messages, that is,
messages sent to windows owned by the calling thread using the SendMessage,
SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then
the first queued message that matches the specified filter is retrieved. The
system may also process internal events."
Doesn't it mean that PeekMessage DO process sent messages?
No it doesn't mean that. Read the documentation again carefully. The
system *delivers* these messages *during* the call to PeekMessage.
Thus, before PeekMessage returns, all sent messages are dispatched
automatically. You don't get these messages back as a result from the
call to PeekMessage. In fact, the documentation explicitly states
that such messages are "nonqueued".
This is the "more complicated" part that I mentioned above, and refers
to a situation where SendMessage has been called from a thread
different from the thread that manages the window's message queue.
Such messages are accumulated in a "separate place" (using the words
of Raymond Chen) that is different from the message queue. Since they
are not queued messages, they must be processed separately from the
message queue. The timing at which they are processed is a priority
timing, ahead of messages in the queue. Thus, when the thread that
manages the window's queue is re-awakened, as soon as it calls a
function like PeekMessage or GetMessage, any messages that are in the
"separate place" are dispatched automatically to the WindProc, after
which queued messages are returned for manual dispatching by your
program (i.e., in your program's call to DispatchMessage).
For more information, read this thread from Raymond Chen's blog Old
New Thing: "The various ways of sending a message" at
http://blogs.msdn.com/oldnewthing/archive/2004/11/19/266664.aspx .
The comments are where the meat of the information resides. For
"When SendMessage() is used to send a message to a window in *this*
thread, the window procedure is called immediately by SendMessage().
"When you post messages using PostMessage, regardless of whether you
are posting from *this* thread or another thread, the messages go into
"the message queue".
"When you send messages to another thread using SendMessage, they
don't technically go into "the message queue" but rather a "separate
place".
"When the thread that owns the window calls a Win32 API function that
directly or indirectly looks at this "separate place" (such as
PeekMessage or GetMessage), the system first checks if there are any
messages in the "separate place" and dispatches them all automatically
(i.e., automatically calls the window procedure). The system then
checks "the message queue" and returns the first matching message."
Post by Denis Adamchuk
Malachy, you insist that PeekMessage() does not process sent messages and
retrieves only posted messages from the message queue (I understand that sent
messages go to "another place" anyway). Could you please tell me what is the
purpose of the PM_QS_SENDMESSAGE flag?
I have never used PM_QS_SENDMESSAGE, and can't talk definitively.
That was one of the questions in the blog I linked to, and the
question remained unanswered. However, according to the documentation
that you linked to, it apparently "Process[es] all sent messages",
which fits into the explanation quoted above.
Malachy Moses
2008-09-09 19:18:31 UTC
Permalink
On Sep 9, 9:39 am, Denis Adamchuk
Post by Denis Adamchuk
Malachy, thanks for your explanation.
I've carefully read the article by Raymond.
In the OldNewThing discussion I found a similar question about inter-thread
sent messages which are kept in a "separate place". This one is very
"Can I retrieve sent messages as if they were posted messages, and then
dispatch them? I would like to be able to filter out, for example, Shatter
attacks. "
In other words I would like to disable sent messages to be processed
(dispatched) within PeekMessage or allow it only for group of messages
(filter by ID).
< snip >

I don't have an answer for you, but I have some more information.

First, there might be a real name for the "separate place" mentioned
in Raymond Chen's blog. The name might be "send-message queue", and
the thread that sent the message might have a correspondingly-named
"reply-message queue". Both of these queues are distinctly different
from the so-called "message queue" that is serviced by GetMessage and
PeekMessage. Here are two links that talk about these topics, and
about the algorithm that the Windows system uses to service these
three queues.

"Sending Messages to a Window" at http://www.jamajm.com/e-books/cpprichter/HTML/ch26d.htm
"Waking a Thread" at
http://ymei.freeshell.org/gopher/Book/Programming%20Applications%20for%20MS%20Windows%204thed/ch26e.htm

Second, with respect to protection against shatter attacks, I think
the right place to do this is inside the WinProc itself. The WinProc
will get all messages, regardless of how they are sent/posted. Inside
the WinProc, you sill need to determine the origin of the message
(thread ID, maybe). Windows must somehow know of the origin, since
Windows needs to know where to send the LRESULT of your WinProc. I
don't know how to get the originating thread ID, however. It would be
nice if the API had a GetOriginOfMSg function, or if the MSG structure
included this information, but it doesn't. You probably will need to
look to undocumented Windows internals. Probably, the internal
structure for MSG must have some sort of identifier on where to send
the LRESULT, so that it ends up in the correct thread's reply-message
queue (per new terminology above).

Third, when I am trying to figure out how Windows works internally, I
often look at the source code for the WINE windows emulator. This
often provides good hints to me on what Windows is probably doing. In
your case, the files you might want to start with are windows/queue.c
and windows/message.c . See the explanation of the WINE messaging sub-
system, at the bottom of this link:

"Chapter 10. Windowing system" at http://www.winehq.org/site/docs/winedev-guide/c3764

Good luck. If you find an answer, please let us know.
Denis Adamchuk
2008-09-10 09:26:15 UTC
Permalink
Thanks for your links!

It's a good idea to analyze messages in WndProc or have a hook, say
WH_CALLWNDPROC for this purpose. But unfortunately it's too late to analyze a
message when it's already retrieved from the send-message queue because if I
don't want to handle it NOW - I cannot just return it to the queue, its
impossible.
On Sep 9, 9:39 am, Denis Adamchuk
Post by Denis Adamchuk
Malachy, thanks for your explanation.
I've carefully read the article by Raymond.
In the OldNewThing discussion I found a similar question about inter-thread
sent messages which are kept in a "separate place". This one is very
"Can I retrieve sent messages as if they were posted messages, and then
dispatch them? I would like to be able to filter out, for example, Shatter
attacks. "
In other words I would like to disable sent messages to be processed
(dispatched) within PeekMessage or allow it only for group of messages
(filter by ID).
< snip >
I don't have an answer for you, but I have some more information.
First, there might be a real name for the "separate place" mentioned
in Raymond Chen's blog. The name might be "send-message queue", and
the thread that sent the message might have a correspondingly-named
"reply-message queue". Both of these queues are distinctly different
from the so-called "message queue" that is serviced by GetMessage and
PeekMessage. Here are two links that talk about these topics, and
about the algorithm that the Windows system uses to service these
three queues.
"Sending Messages to a Window" at http://www.jamajm.com/e-books/cpprichter/HTML/ch26d.htm
"Waking a Thread" at
http://ymei.freeshell.org/gopher/Book/Programming%20Applications%20for%20MS%20Windows%204thed/ch26e.htm
Second, with respect to protection against shatter attacks, I think
the right place to do this is inside the WinProc itself. The WinProc
will get all messages, regardless of how they are sent/posted. Inside
the WinProc, you sill need to determine the origin of the message
(thread ID, maybe). Windows must somehow know of the origin, since
Windows needs to know where to send the LRESULT of your WinProc. I
don't know how to get the originating thread ID, however. It would be
nice if the API had a GetOriginOfMSg function, or if the MSG structure
included this information, but it doesn't. You probably will need to
look to undocumented Windows internals. Probably, the internal
structure for MSG must have some sort of identifier on where to send
the LRESULT, so that it ends up in the correct thread's reply-message
queue (per new terminology above).
Third, when I am trying to figure out how Windows works internally, I
often look at the source code for the WINE windows emulator. This
often provides good hints to me on what Windows is probably doing. In
your case, the files you might want to start with are windows/queue.c
and windows/message.c . See the explanation of the WINE messaging sub-
"Chapter 10. Windowing system" at http://www.winehq.org/site/docs/winedev-guide/c3764
Good luck. If you find an answer, please let us know.
Pascal Dallongeville
2011-10-06 07:55:33 UTC
Permalink
I know this post is from 3 years but I never found an answer to this question :

Is there a way to prevent "PeekMessage" from dispatch sent messages that come from others threads ?

I want to do this because I need to flush timer message in a olemessagefilter and sometimes I got error "It is illegal to call out while inside a message filter" (error 0x80010005).
I guess this error happen because PeekMessage dispatch a sent from another thread message. I don't know at all how this message come to my thread and what exactly this message has done to permit outgoing call. Maybe this is a WM_CLOSE from system that show a dialog that made WM_TIMER messages proceeded possible...

Does someone can explain what does PM_QS_SENDMESSAGE flag do in "PeekMessage" function ?
Post by Denis Adamchuk
Hi everyone,
I'm writing an application where Windows messages are used in a special
manner and want to clarify how flexible is access to the thread message queue.
I've read the MSDN article about PeekMessage and many web sites where
different opinions are expressed. My questions are the following...
1) What really does PeekMessage()?
Does it process messages sent from other threads by means of
SendMessage-family routines or just picks a message from the queue (or from
where?) and give me a chance to analyze it and process it by myself?
2) Does PeekMessage process ALL sent messages that are available now or only
one of them?
3) According to the MSDN - PeekMessage() does both things I've mentioned
above.
But what do wMsgFilterMin and wMsgFilterMax arguments mean?
Does PeekMessage pick from the queue messages from identifiers from the
range or does it process only such messages sent to the current thread?
4) The most confusing one :)
What is tuned by PM_QS_*** flags - behavior for implicit message processing
or behavior for message picking?
If PM_QS*** define what messages I want to proceed why there are any flags
except the PM_QS_SENDMESSAGE (since PeekMessage() is devoted to process only
SendMessage() messages)?
Otherwise if PM_QS*** define what messages I want to pick why there is the
PM_QS_SENDMESSAGE flag if the messages that were sent will be processed
implicitly and I never get them as a result?
5) PeekMessage() does not fill lpMsg output parameter with a message(s) it
has processed?
6) Is it possible to disable an implicit message processing inside
PeekMessage() and make it to return as lpMsg messages that were sent from
another threads via SendMessage-routines BUT only within a defined range?
7) What is PM_NOYIELD?
Thanks in advance!
It will be great if this post become a consolidated place of information
about PeekMessage() for those who search...
Post by AliR (VC++ MVP)
See Below.....
PeekMessage retrieves a message from the calling thread's message queue, it
doesn't care if was sent view SendMessage or PostMessage. PeekMessage does
not process the message, that's job of the winproc to process messages (this
happens during the call to DispatchMessage), PeekMessage simply returns the
message that is at the top of the queue.
PeekMessage returns one message at a time. Again it does not process message
simply returns a message. Not that wRemoveMsg parameter let you tell it to
either remove the message if you are calling PeekMessage to process the
message after you receive it, or to leave it in the queue, if you are
calling PeekMessage just out of curiousity and won't really be processing
the message. See GetMessage if you always want to remove the message from
the queue.
wMsgFilterMin and wMsgFilterMax is used to only receive back message in the
specified range. And simply won't return any messages outside of that
range.
I have never used these before, but the docs say that they filter message by
type. Kind of like FilterMin and FilterMax
I don't understand questions 5, and 6
PM_NOYIELD will make user that no other threads are released during the call
to PeekMessage. Explaining this one will take a couple of pages. each
thread in your application gets a time slice of the processer. So a thread
will run for a while and when it becomes idle the processor is given to
another thread in your app, and so far and so forth. Callling PeekMessage
might cause another thread to take over momentarily, PM_NOYIELD will pervent
that from happening.
AliR.
Post by AliR (VC++ MVP)
My bad, I keep forgetting that.
BTW, here is a link that explains all of this in more detail. Also some
http://msdn.microsoft.com/en-us/library/ms644928(VS.85).aspx
AliR.
See in-line, below ...
This incorrectly infers that a message sent by SendMessage somehow
ends up in the message queue. It doesn't. A message sent by
SendMessage is a non-queued message that does not end up in the
message queue, and is not retrievable by a call to PeekMessage (or a
call to GetMessage).
A message sent by SendMessage calls the target window's WinProc
directly, without going through the message queue. If the thread
calling SendMessage is the same thread as the target window, then a
call to SendMessage is very much like a simple function call, that
calls the WinProc for the target window. If the are in different
threads, then the process is more complicated, but the end result is
the same in that sent messages are non-queued messages that bypass the
message queue and do not somehow end up in the message queue.
On the other hand, messages posted by PostMessage end up in the
message queue, together with other messages that get routed through
the message queue (like timer messages, paint messages, system
messages, keyboard messages, etc.) It's only if the message resides
in the message queue that the message can be retrived by calls to
PeekMessage or GetMessages.
As one explanation, see Paul DiLascia's C++ Q&A column from December
2000, "Sending Messages in Windows" at
http://msdn.microsoft.com/en-us/magazine/cc301431.aspx
PeekMessage will not process *any* sent messages, for the reason that
messages sent by using SendMessage will not go into the message queue.
<snip, I am not responding to the remainder of this post.>
Post by Denis Adamchuk
Guys, I'm totally confused now.
At http://msdn.microsoft.com/en-us/library/ms644943(VS.85).aspx
"During this call, the system delivers pending, nonqueued messages, that is,
messages sent to windows owned by the calling thread using the SendMessage,
SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then
the first queued message that matches the specified filter is retrieved. The
system may also process internal events."
Doesn't it mean that PeekMessage DO process sent messages?
Malachy, you insist that PeekMessage() does not process sent messages and
retrieves only posted messages from the message queue (I understand that sent
messages go to "another place" anyway). Could you please tell me what is the
purpose of the PM_QS_SENDMESSAGE flag?
Concerning PM_NOYIELD. AliR, do you mean that this flag prevents the context
switching? I thought its impossible.
Thanks.
Post by AliR (VC++ MVP)
"You can optionally combine the value PM_NOYIELD with either PM_NOREMOVE or
PM_REMOVE. This flag prevents the system from releasing any thread that is
waiting for the caller to go idle (see WaitForInputIdle)."
Post by Malachy Moses
See in-line, below ...
wrote in message
it
does
his
he
This incorrectly infers that a message sent by SendMessage somehow
ends up in the message queue. It doesn't. A message sent by
SendMessage is a non-queued message that does not end up in the
message queue, and is not retrievable by a call to PeekMessage (or a
call to GetMessage).
A message sent by SendMessage calls the target window's WinProc
directly, without going through the message queue. If the thread
calling SendMessage is the same thread as the target window, then a
call to SendMessage is very much like a simple function call, that
calls the WinProc for the target window. If the are in different
threads, then the process is more complicated, but the end result is
the same in that sent messages are non-queued messages that bypass the
message queue and do not somehow end up in the message queue.
On the other hand, messages posted by PostMessage end up in the
message queue, together with other messages that get routed through
the message queue (like timer messages, paint messages, system
messages, keyboard messages, etc.) It's only if the message resides
in the message queue that the message can be retrived by calls to
PeekMessage or GetMessages.
As one explanation, see Paul DiLascia's C++ Q&A column from December
2000, "Sending Messages in Windows" at http://msdn.microsoft.com/en-us/maga=
zine/cc301431.aspx
age
t to
rom
PeekMessage will not process *any* sent messages, for the reason that
messages sent by using SendMessage will not go into the message queue.
<snip, I am not responding to the remainder of this post.>
Post by Malachy Moses
See in-line below ....
On Sep 8, 1:53=A0pm, Denis Adamchuk
is,
e,
hen
The
No it doesn't mean that. Read the documentation again carefully. The
system *delivers* these messages *during* the call to PeekMessage.
Thus, before PeekMessage returns, all sent messages are dispatched
automatically. You don't get these messages back as a result from the
call to PeekMessage. In fact, the documentation explicitly states
that such messages are "nonqueued".
This is the "more complicated" part that I mentioned above, and refers
to a situation where SendMessage has been called from a thread
different from the thread that manages the window's message queue.
Such messages are accumulated in a "separate place" (using the words
of Raymond Chen) that is different from the message queue. Since they
are not queued messages, they must be processed separately from the
message queue. The timing at which they are processed is a priority
timing, ahead of messages in the queue. Thus, when the thread that
manages the window's queue is re-awakened, as soon as it calls a
function like PeekMessage or GetMessage, any messages that are in the
"separate place" are dispatched automatically to the WindProc, after
which queued messages are returned for manual dispatching by your
program (i.e., in your program's call to DispatchMessage).
For more information, read this thread from Raymond Chen's blog Old
New Thing: "The various ways of sending a message" at
http://blogs.msdn.com/oldnewthing/archive/2004/11/19/266664.aspx .
The comments are where the meat of the information resides. For
"When SendMessage() is used to send a message to a window in *this*
thread, the window procedure is called immediately by SendMessage().
"When you post messages using PostMessage, regardless of whether you
are posting from *this* thread or another thread, the messages go into
"the message queue".
"When you send messages to another thread using SendMessage, they
don't technically go into "the message queue" but rather a "separate
place".
"When the thread that owns the window calls a Win32 API function that
directly or indirectly looks at this "separate place" (such as
PeekMessage or GetMessage), the system first checks if there are any
messages in the "separate place" and dispatches them all automatically
(i.e., automatically calls the window procedure). The system then
checks "the message queue" and returns the first matching message."
sent
the
I have never used PM_QS_SENDMESSAGE, and can't talk definitively.
That was one of the questions in the blog I linked to, and the
question remained unanswered. However, according to the documentation
that you linked to, it apparently "Process[es] all sent messages",
which fits into the explanation quoted above.
Post by Bogdan
[...]
Another thing worth noting in this case is that, in some cases, message
queue might be flushed (e.g. when you destroy COM objects) so in practice
you have posted messages delivered to your window as if they were sent.
Bogdan
Post by Denis Adamchuk
Malachy, thanks for your explanation.
I've carefully read the article by Raymond.
In the OldNewThing discussion I found a similar question about inter-thread
sent messages which are kept in a "separate place". This one is very
"Can I retrieve sent messages as if they were posted messages, and then
dispatch them? I would like to be able to filter out, for example, Shatter
attacks. "
In other words I would like to disable sent messages to be processed
(dispatched) within PeekMessage or allow it only for group of messages
(filter by ID).
I suppose the root cause of my confusion is the PM_QS_SENDMESSAGE.
I still don't understand how this flag affect the PeekMessage() execution.
In my application PeekMessage() delivers sent messages to the WndProc in the
Moreover, when I set all PM_QS_* flags except PM_QS_SENDMESSAGE
PeekMessage() does the same.
Don't you know any newsgroup where could I address my question?
May be microsoft.public.vc.mfc is not the appropriate one but my post to the
microsoft.public.win32.programmer.ui didn't recieve any replies at all.
Thanks a lot!
Post by Doug Harrison [MVP]
On Tue, 9 Sep 2008 09:39:01 -0700, Denis Adamchuk
I think those are two different questions. I don't know how to accomplish
the former (maybe a message hook?), but you're supposed to be able to
accomplish the latter with PeekMessage. Note that it won't help with MFC's
or Windows' internal GetMessage loops, use of WaitMessage, etc.
Yeah, the documentation is confusing, because the default is to process
sent messages! It may be that specifying nothing processes everything,
while if you specify PM_QS_POSTMESSAGE, you will suppress the processing of
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_POSTMESSAGE);
processes pending interthread sent messages?
--
Doug Harrison
Visual C++ MVP
Post by Alexander Grigoriev
This is different thing. WaitForInputIdle waits for a special event
associated with a process, which is set on any GetMessage-type call. THis
flag makes sure the event will not be set at PeekMessage,
Post by Denis Adamchuk
Hi
I'm going to describe briefly my situation and to show you a stack.
I have two threads and in the second thread I create a dialog. Parent window
for the dialog belongs to the first thread.
Collaboration between threads is based on a custom message queue which is
handled insided WM_TIMER message handler. It doesn't matter essentially.
- It places a request to the message queue of the 2nd thread;
- and waits for an event to be signaled when a dialog is created.
While it's waiting I have to pump the first thread message queue to avoid
hang up. I'm trying to do it by means of ::PeekMessage(&msg, NULL, 0, 0,
Primary.exe!CWnd::OnParentNotify( <cut arguments> )
Primary.exe!CWnd::OnWndMsg( <cut arguments> )
Primary.exe!CWnd::WindowProc( <cut arguments> )
Primary.exe!AfxCallWndProc( <cut arguments> )
Primary.exe!AfxWndProc( <cut arguments> )
Support.dll!CTransportManager::pumpWindowsMessages()
So WM_PARENTNOTIFY is sent by CreateDialogIndirect and is dispatched by
PeekMessage...
Post by Denis Adamchuk
Thanks for your links!
It's a good idea to analyze messages in WndProc or have a hook, say
WH_CALLWNDPROC for this purpose. But unfortunately it's too late to analyze a
message when it's already retrieved from the send-message queue because if I
don't want to handle it NOW - I cannot just return it to the queue, its
impossible.
On Sep 9, 9:39=A0am, Denis Adamchuk
ad
r
< snip >
I don't have an answer for you, but I have some more information.
First, there might be a real name for the "separate place" mentioned
in Raymond Chen's blog. The name might be "send-message queue", and
the thread that sent the message might have a correspondingly-named
"reply-message queue". Both of these queues are distinctly different
from the so-called "message queue" that is serviced by GetMessage and
PeekMessage. Here are two links that talk about these topics, and
about the algorithm that the Windows system uses to service these
three queues.
"Sending Messages to a Window" at http://www.jamajm.com/e-books/cpprichter/=
HTML/ch26d.htm
"Waking a Thread" at
http://ymei.freeshell.org/gopher/Book/Programming%20Applications%20for%20MS=
%20Windows%204thed/ch26e.htm
Second, with respect to protection against shatter attacks, I think
the right place to do this is inside the WinProc itself. The WinProc
will get all messages, regardless of how they are sent/posted. Inside
the WinProc, you sill need to determine the origin of the message
(thread ID, maybe). Windows must somehow know of the origin, since
Windows needs to know where to send the LRESULT of your WinProc. I
don't know how to get the originating thread ID, however. It would be
nice if the API had a GetOriginOfMSg function, or if the MSG structure
included this information, but it doesn't. You probably will need to
look to undocumented Windows internals. Probably, the internal
structure for MSG must have some sort of identifier on where to send
the LRESULT, so that it ends up in the correct thread's reply-message
queue (per new terminology above).
Third, when I am trying to figure out how Windows works internally, I
often look at the source code for the WINE windows emulator. This
often provides good hints to me on what Windows is probably doing. In
your case, the files you might want to start with are windows/queue.c
and windows/message.c . See the explanation of the WINE messaging sub-
"Chapter 10. Windowing system" at http://www.winehq.org/site/docs/winedev-g=
uide/c3764
Good luck. If you find an answer, please let us know.
Doug Harrison [MVP]
2008-09-09 20:59:27 UTC
Permalink
On Tue, 9 Sep 2008 09:39:01 -0700, Denis Adamchuk
Post by Denis Adamchuk
Malachy, thanks for your explanation.
I've carefully read the article by Raymond.
In the OldNewThing discussion I found a similar question about inter-thread
sent messages which are kept in a "separate place". This one is very
"Can I retrieve sent messages as if they were posted messages, and then
dispatch them? I would like to be able to filter out, for example, Shatter
attacks. "
In other words I would like to disable sent messages to be processed
(dispatched) within PeekMessage or allow it only for group of messages
(filter by ID).
I think those are two different questions. I don't know how to accomplish
the former (maybe a message hook?), but you're supposed to be able to
accomplish the latter with PeekMessage. Note that it won't help with MFC's
or Windows' internal GetMessage loops, use of WaitMessage, etc.
Post by Denis Adamchuk
I suppose the root cause of my confusion is the PM_QS_SENDMESSAGE.
I still don't understand how this flag affect the PeekMessage() execution.
In my application PeekMessage() delivers sent messages to the WndProc in the
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_SENDMESSAGE);
Moreover, when I set all PM_QS_* flags except PM_QS_SENDMESSAGE
PeekMessage() does the same.
Yeah, the documentation is confusing, because the default is to process
sent messages! It may be that specifying nothing processes everything,
while if you specify PM_QS_POSTMESSAGE, you will suppress the processing of
sent messages. Are you sure that:

::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_POSTMESSAGE);

processes pending interthread sent messages?
--
Doug Harrison
Visual C++ MVP
Denis Adamchuk
2008-09-10 09:17:00 UTC
Permalink
Hi

I'm going to describe briefly my situation and to show you a stack.

I have two threads and in the second thread I create a dialog. Parent window
for the dialog belongs to the first thread.
Collaboration between threads is based on a custom message queue which is
handled insided WM_TIMER message handler. It doesn't matter essentially.

The first thread performs a kind of "synchronous call":
- It places a request to the message queue of the 2nd thread;
- and waits for an event to be signaled when a dialog is created.

While it's waiting I have to pump the first thread message queue to avoid
hang up. I'm trying to do it by means of ::PeekMessage(&msg, NULL, 0, 0,
Separate.dll!CWnd::CreateDlgIndirect( <cut arguments> )
Primary.exe!CWnd::Default()
Primary.exe!CWnd::OnParentNotify( <cut arguments> )
Primary.exe!CWnd::OnWndMsg( <cut arguments> )
Primary.exe!CWnd::WindowProc( <cut arguments> )
Primary.exe!AfxCallWndProc( <cut arguments> )
Primary.exe!AfxWndProc( <cut arguments> )
user32.dll!***@20()
user32.dll!***@32()
user32.dll!***@20()
user32.dll!***@4()
ntdll.dll!***@12()
user32.dll!***@20()
user32.dll!***@20()
Support.dll!CTransportManager::pumpWindowsMessages()

So WM_PARENTNOTIFY is sent by CreateDialogIndirect and is dispatched by
PeekMessage...
On Tue, 9 Sep 2008 09:39:01 -0700, Denis Adamchuk
Post by Denis Adamchuk
Malachy, thanks for your explanation.
I've carefully read the article by Raymond.
In the OldNewThing discussion I found a similar question about inter-thread
sent messages which are kept in a "separate place". This one is very
"Can I retrieve sent messages as if they were posted messages, and then
dispatch them? I would like to be able to filter out, for example, Shatter
attacks. "
In other words I would like to disable sent messages to be processed
(dispatched) within PeekMessage or allow it only for group of messages
(filter by ID).
I think those are two different questions. I don't know how to accomplish
the former (maybe a message hook?), but you're supposed to be able to
accomplish the latter with PeekMessage. Note that it won't help with MFC's
or Windows' internal GetMessage loops, use of WaitMessage, etc.
Post by Denis Adamchuk
I suppose the root cause of my confusion is the PM_QS_SENDMESSAGE.
I still don't understand how this flag affect the PeekMessage() execution.
In my application PeekMessage() delivers sent messages to the WndProc in the
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_SENDMESSAGE);
Moreover, when I set all PM_QS_* flags except PM_QS_SENDMESSAGE
PeekMessage() does the same.
Yeah, the documentation is confusing, because the default is to process
sent messages! It may be that specifying nothing processes everything,
while if you specify PM_QS_POSTMESSAGE, you will suppress the processing of
::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_POSTMESSAGE);
processes pending interthread sent messages?
--
Doug Harrison
Visual C++ MVP
Bogdan
2008-09-09 13:39:58 UTC
Permalink
Post by Denis Adamchuk
I'm writing an application where Windows messages are used in a special
manner and want to clarify how flexible is access to the thread message queue.
[...]

Another thing worth noting in this case is that, in some cases, message
queue might be flushed (e.g. when you destroy COM objects) so in practice
you have posted messages delivered to your window as if they were sent.

Bogdan
Loading...