When we send a message, "if the specified window was created by the calling thread, the window procedure is called immediately as a subroutine".
But "if the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code." (taken from MSDN documentation for SendMessage
).
Now, I don't understand how (or, more appropriately, when) the target windows procedure is called. Of course the target thread will not be preempted (the program counter is not changed). I presume that the call will happen during some wait function (like GetMessage
or PeekMessage
), it is true? That process is documented in detail somewhere?
Update: the rationale behind it is explained by the QS_SENDMESSAGE
flag of GetQueueStatus()
and MsgWaitForMultipleObjects()
:
QS_SENDMESSAGE
A message sent by another thread or application is in the queue.
This, along with additional remarks in MSDN documentation, means that a message sent by another thread is actually posted to the queue. Then, as soon as GetMessage
or PeekMessage
are called, it will be processed before any other posted message by being sent directly to the window procedure.
SendMessage is thread-safe. It is the code that runs when it delivers the message that is never ever thread-safe. Assuming the HWND being sent to is itself thread-safe and not changed while SendMessage/Timeout is busy.
Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
To send a message within a thread, server members will need the “Send Messages in Thread” permission, which allows server members to participate within threads only - not for all general channels in the server. On the other hand, the “Send Message” permission will only apply to messages outside of threads.
I see some confusion here.
According to the MSDN docs, when you touch the message queue of the current thread with the intent of message processing (e.g. if you call PeekMessage
or GetMessage
), all pending sent (i.e. non-queued) messages from other threads are handled - passed to the WndProc
- and then the message queue is checked, so:
DispatchMessage
and are handled as soon as possible:
WndProc
PostThreadMessage
does just what it states - posts a message in a threads queue - such messages are not directed to any window and must be handled explixitlyDispatchMessage
are those created by PostMessage
or some system facility (timers, events, user input, etc.)SendNotifyMessage
, SendMessageTimeout
or SendMessageCallback
instead of plain SendMessage
between different threadsFor further reference, study the Remarks section of the MSDN PeekMessage
entry.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With