Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is executed a SendMessage from a different thread?

Tags:

windows

winapi

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.

like image 302
lornova Avatar asked May 31 '10 10:05

lornova


People also ask

Is SendMessage thread safe?

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.

What is SendMessage?

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.

How do I send a thread 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.


1 Answers

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:

  • sent messages never go through DispatchMessage and are handled as soon as possible:
    • in the current thread, they are simply passed to WndProc
    • in another thread, they are handled before any posted message processing
  • to be able to handle sent messages, the target thread still needs a message pump
  • 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 explixitly
  • the only messages handled by DispatchMessage are those created by PostMessage or some system facility (timers, events, user input, etc.)
  • to avoid deadlocks, use SendNotifyMessage, SendMessageTimeout or SendMessageCallback instead of plain SendMessage between different threads

For further reference, study the Remarks section of the MSDN PeekMessage entry.

like image 149
Viktor Svub Avatar answered Oct 03 '22 04:10

Viktor Svub