I understand that when a message is sent, it has hwnd value so that the systems knows which window is responsible for dealing with that message. And when hwnd is NULL then it means that this is a thread message. So what is the procedure function that is called to deal with that message?
Note that it is only documented under PostMessage (not SendMessage) that sending with HWND as NULL will cause the function to "behave like PostThreadMessage with dwThreadId as the current thread".
See here for how a thread can implement a message queue.
In response to your original question:
So what is the procedure function that is called to deal with that message?
PostThreadMessage posts to the message queue of the thread.
Note for PostThreadMessage: "The function fails if the specified thread does not have a message queue. The system creates a thread's message queue when the thread makes its first call to one of the User or GDI functions."
Related
While handling WM_TIMER, I called MessageBox. As a result, a message box popped up with the frequency of the timer. So I believe that the application was trying to continue to process queued/non-queued messages even during MessageBox.
Am I right?
I know that according to MSDN, while an application is sending a message to a different thread from the sending thread, the sending thread will try to process non-queued messages it receives before SendMessage returns --- i.e. before the target thread replies.
Are there any other functions that could try to continue to process queued/non-queued messages before they return, besides MessageBox and SendMessage? I need to know about that to determine whether any functions called in the Window procedure should be reentrant.
Another two relevant questions are
1) Does DispatchMessage not return until the window procedure has returned?
2) Will GetMessage not be called again if the current DispatchMessage hasn't returned yet?
A modal dialog runs its own message loop internally, using the calling thread's message queue. You are calling MessageBox() inside your WM_TIMER handler, so the message loop inside of MessageBox() is receiving and dispatching subsequent WM_TIMER messages while the message box is running.
searching the web for the difference between these two function calls, I've found that:
The difference between these two API calls is the way that they return control to the calling application. With SendMessage control is not returned to the calling application until the window that the message was sent to has completed processing the sent message, however with PostMessage control is returned to the calling application immediately, regardless of weather or not the sent message has been processes.
postMessage: Sends a message in the message queue associated with the thread and returns without waiting for the thread to process that messaage.
SendMessage: calls the window procedure for the specified window and does not return until the window procedure has processed the message.
PostMessage is a Asynchronous function where as SendMessage is a synchronous function.
Now the question is for my application ( which needs high performance ) which function is better to be used?
Note that I'm using MFC in visual studio 2010 and for this code:
CWnd *pParentOfClass = CWnd::GetParent();
pParentOfClass ->
I just have these functions for sending messsages:
PostMessageW
SendMessage
SendMessageW
More questions:
Can you tell me the difference between SendMessage and SendMessageW?
You actually already answered your own question by describing SendMessage and PostMessage.
SendMessage: Sends a message and waits until the procedure which is responsible for the message finishes and returns.
PostMessage: Sends a message to the message queue and returns immediately. But you don't know when that message is actually being processed. Therefore, if you should be expecting an answer from that processed message, you will most likely get it through a message as well.
It really depends which one to use, but the end results are pretty much the same, it's just about timing. Also, PostMessage is especially useful in multi-threaded applications, which allows you to safely communicate between threads via their created windows.
PostMessage or SendMessage that end with A or W are just indicators how strings will be interpreted, i.e. single or multibyte, respectively. The ones without the A or W ending are preprocessor macros and will delegate to whatever you're application is set up to.
I don't quite understand how GetWindowText can work for a window on the same thread as the caller. If GetWindowText blocks until the message is processed, how can the thread call DispatchMessage? It's been blocked inside GetWindowText. Does this mean that GetWindowText must always be called from a separate thread from the one operating the message loop?
GetWindowText is just a thin wrapper for SendMessage(WM_GETTEXT).
Messages sent to a window are always processed in the thread which created the window (windows have "thread affinity"). Sent messages do not go through DispatchMessage, rather GetMessage (or PeekMessage or MsgWaitForMultipleObjects) will call the window procedure directly, for messages sent from another thread. If the message is sent from the same thread, SendMessage will call the window procedure.
The SendMessage documentation says:
The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
And the GetMessage documentation says:
Retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.
From the PeekMessage docs:
Dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).
The behavior of sending messages has previously been highlighted on Raymond Chen's excellent blog, The Old New Thing, which all Win32 developers ought to subscribe to:
If you use any of the above send-type functions to send a message to a window that belongs to the sending thread, the call is made synchronously.
http://blogs.msdn.com/b/oldnewthing/archive/2004/11/19/266664.aspx
Recall that SendMessage delivers the message directly to the window procedure; the message pump never sees it.
http://blogs.msdn.com/b/oldnewthing/archive/2008/12/23/9248851.aspx
And of course, there are related questions found here on StackOverflow:
SendMessage vs PostMessage + WaitForSingleObject
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.
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.
Short answer: When the target thread calls GetMessage (or PeekMessage) followed by DispatchMessage, then the SendMessage from the other thread is received and handled.
I am not certain if the received SendMessage preempts other messages in the queue or not. Either way, a SendMessage from one thread to another is like saying: "Post this message to the other thread's message queue. Return when that thread has finished processing it".
An now for an answer you didn't ask for:
In general, when I program interactions between the main UI thread and a worker thread, I try to avoid using SendMessage. If you aren't careful, you can get into a situation where both threads are deadlocked on each other. (Think of the case where the main thread is calling WaitForSingleObject to wait for the worker thread to complete, but the worker thread is blocked on SendMessage back to the UI thread).
Every windows is associated with a thread. You can use GetWindowThreadProcessId to retrieves the thread of every window. If you send a message to a windows from the other thread with respect of PostThreadMessage the message will be placed in the thread's message queue. The thread must have a get-message loop (with GetMessage for example) to get the messages and dispatch there to the window procedure of the window.
It you call SendMessage instead of PostThreadMessage you call the Windows Procedure directly without placing it in the message queue. Some nonqueued messages are sent also immediately to the destination window procedure, bypassing the system message queue and thread message queue. (see http://msdn.microsoft.com/en-us/library/ms644927(VS.85).aspx#nonqueued_messages). The main reason to use SendMessage instead of PostThreadMessage if you want to give some information from another windows (control) like read a text from an another control during processing of another message. You should do this only if it really needed. So if you use SendMessage to send a message to a windows from another thread your current thread must be blocked for some time.
It can be a good idea to use PostThreadMessage or SendMessageCallback instead of SendMessage if it is possible.
How precisely does windows decide that SendMessage should return- that is, how does it decide the receiving thread has finished processing the sent message?
Detailed scenario:
I've got thread A using SendMessage to send a thread to thread B. Obviously SendMessage doesn't return until thread B finishes processing the message. Thread B pops up a dialog box and starts pumping messages. In my scenario, there is a WM_KILLFOCUS message on the queue which gets pumped by thread B. This results is a WM_COMMAND message on thread B. Thread B passes this WM_COMMAND message to the default window proc. When it does this, SendMessage returns back to thread A, even though the original message hasn't finished processing yet! What is going on? It looks like somehow the default window proc is confusing windows into thinking the original sent message is finished.
So are there known scenarios where pumping messages and calling the default window proc can trick SendMessage into returning?
Thanks!
Phil
As long as processing of the message has started, the WindowProc processing the interthread message can call ReplyMessage to allow the calling thread to continue while processing continues.
Since SendMessage has a return value, it is always after the message is processed.
PostMessage on the other hand will not wait for the message to be processed.
From MSDN on SendMessage:
The SendMessage function calls the
window procedure for the specified
window and does not return until the
window procedure has processed the
message.
There is no case where it will return before the message is processed.
From the MSDN, it sounds like that the problem may be that displaying a dialog box in thread B may cause deadlocks. See Message Deadlocks.
Possibly it is because the message received by thread A was a nonqueued message. From MSDN:
However, the sending thread will
process incoming nonqueued messages
while waiting for its message to be
processed. To prevent this, use
SendMessageTimeout with SMTO_BLOCK
set. For more information on nonqueued
messages, see Nonqueued Messages.
It sounds as if your original SendMessage has NOT returned but rather than the WindowProc in thread A has been called during the processing of the message sent. There is no requirement that a message handler must refrain from calling SendMessage in response to receipt of a message.
You should be able to see the original call to SendMessage in your callstack at the point where you receive the WM_COMMAND that you sent in response to the focus change message.