Do PostMessage() messages appear in order in Windows? - windows

The general question, is if I post several messages to the windows message pump from a separate worker thread, will they appear at their destination in the order I sent? ie..
::PostMessage(m_hUsers, WM_BULKPROCESS, 0, 0);
// ... some processing here ...
::PostMessage(m_hUsers, WM_BULKDONE, 0, 0);
m_hUsers is a handle (HWND) to a window I'm sending the messages to from my worker thread. So, will WM_BULKPROCESS always show up first in the window (and therefore be processed by the handler in that dialog class), or is it possible for them to get out of order, ie WM_BULKDONE gets processed before WM_BULKPROCESS, even though it was sent last?

There are a few exceptions (like WM_PAINT), but generally, the order of messages is kept.
Imaging trying to make sense of mouse input if messages appeared in the wrong order!
Quote from GetMessage
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. If no filter is specified, messages are processed in
the following order:
Sent messages
Posted messages
Input (hardware) messages and system internal events
Sent messages (again)
WM_PAINT messages
WM_TIMER messages

Window messages are stored in a queue. So you can rely on FIFO mechanism.

They should be unless you have code in the message pump that specifically dispatch the messages (either intentionally or not) differently e.g. somehow pick two messages and dispatch them out of order. Normally programmers call DispatchMessage for each message in the order you get from the queue.

I suspect the issue is synchronization and not the message queue. If your code allows multitple invocations of the worker thread proc you have to manage this more tightly to know which "instance" of the worker thread is posting the messages.
Have you checked to make sure you only one worker thread executing at a time, or that the m_hUsers window handle is protected from being changed between BULKPROCESS and BULKDONE?
SendMessage can be useful for managing the BULKDONE because it will block until the message has been processed allowing the code invoking the worker thread to synchronize the invokation of worker threads and truely know that one worker thread has finsished before invoking another. Postmessage will not block but remember the time sensitive part of your worker thread is
`// ... some processing here ...
not sending the windows messages.

Related

Is it possible to put custom message in win32 message queue in FIFO order?

There are few ways I can put a message for GUI thread.
PostMessage: according to docs, these messages are processed first (before most other messages). If I use this too often, the GUI thread may get stuck in processing only my messages and nothing else (will not respond to keyboard\mouse etc). This is too high-priority method.
SetTimer: WM_TIMER messages are processed last after everything else, so if there is any painting happening (like if I move a window continuously) all time will be spend for processing common messages and WM_TIMER will trigger too late.
This is too low-priority method.
I need something in-between to have my custom message processed ASAP but still leave room for the rest of messages to keep the GUI responsive.
What I'd like to try is to put some message to be processed just in same order as normal messages.
So here is the question, how can I do that?
Added:
I have one thread that prepares video frames and it needs to notify main (UI) thread that a new frame is ready and maybe display it. In a typical game loop it would be something like
process messages until queue is empty
process 1 frame
repeat
But now I can't control message loop because it may be in modal popup or menu.
Assume the answer is "no" (no other way to insert message).
However, in processing posted message I can monitor time passed and immediately signal the same message through WM_TIMER instead of processing it.
update
After some observation it seems no given time (1 ms? 5 ms?) guarantees that input will be processed. What works instead is explicitly checking message queue for input messages:
case MY_MSG:
{
MSG msg;
if(PeekMessage(&msg,0,0,0,PM_NOREMOVE|PM_QS_INPUT))
SetTimer(hwnd,MY_TIMER,0,0);
else
DoWork();
}
return 0;

Windows messages and their deterministic properties

I'd like to confirm what I think to be true. When I use Windows SendMessage(), this is a deterministic call in that it will execute immediately (will not return until the message is processed) as opposed to PostMessage() which is non-deterministic as it can be preempted by any other message that happens to be in the queue at that moment in time (in fact it will not be executed until it hits the message loop).
Is this a fair assessment, or am I missing something?
That is essentially true for in-process calls. Cross-process SendMessage works similar, but processing of the message doesn't begin until the receiver process calls GetMessage (or its kin).
Your UI thread has a message pump that looks something like:
while (GetMessage(&msg))
DispatchMessage(&msg);
PostMessage causes the message to be put onto the message queue. GetMessage removes the oldest message from the queue (FIFO*).
DispatchMessage causes the WndProc associated with the message's target window to be called with the message.
SendMessage basically bypasses this chain and calls the WndProc directly (more or less).
A lot of standard window messages result in a chain of SendMessage calls where sending one message sends another which sends another. That chain is often referred to as "the current dispatch". If you need your message to be processed inside the chain, use SendMessage. If you need it to be processed after the current dispatch has completed, use PostMessage.
You can use a tool like Spy++ to see Windows messaging in action, or to debug problems you're having with message order of operations.
[*] It's not strictly a FIFO queue because certain kinds of messages (i.e. timer, mouse, keyboard) are not actually posted to the queue, but rather generated on the fly. For the sake of simplicity, you can think of it as a FIFO.

If PostMessage Succeeded, is the message guaranteed to be processed by the window?

I have a background thread to process data and want to send the result to the main Window, but the window may be destroyed before the background thread exits.
I use PostMessage to deliver some newly created objects (created in heap), if it succeed, does the message get processed by the main Window surely?
If not, what is the best practice for this kind of situation?
ps: My concern is that when posting messages, the Window is valid, but then it is destroyed before the message get delivered. If so, I cannot delete the objects.
I use PostMessage to deliver some newly created objects (created in heap), if it succeed, does the message get processed by the main Window surely?
If the call to PostMessage succeeds, then the message is placed in the queue. The message will then be processed when the thread pumps its message queue. If the thread fails to pump its queue, or if the recipient window no longer exists when the message is processed, then it will not be delivered.

How is executed a SendMessage from a different thread?

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 is Win32 event-driven programming implemented under the hood?

In a Win32 C++ application, we start a message loop that fetches messages from a queue, translates them and then dispatches them. Eventually, each message reaches our WndProc where the associated event can be handled.
I understand that part. What I don't understand is the in between goings-on. Specifically:
Different kinds of OS interrupt handlers must be placing messages in the said 'message queue', but where within the process address space does this queue reside? How is it exposed to the interrupt handler code?
What does it mean to 'translate' the message? What does the call to TranslateMessage() really do?
Once dispatched by DispatchMessage(), what all places does the message swing by before reaching my WndProc (i.e. what does the OS do with it)?
If anyone knows the answers to the above, kindly satisfy my curiosity. Thanks.
The OS maintains a message queue, where it puts the events (e.g., from interrupts or other sources). It then sends the messages from that queue to all windows, depending on the message (e.g., it won't send key messages to a window that doesn't have focus).
Applications can have their own queue to process messages. Those queues are created on request (only if needed).
Translating a message is used to create messages that are not 'real' events. For example, the WM_CONTEXTMENU message is 'translated' from either a mouse right-click, or the context menu key, or shift-F10. The WM_CHAR is translated from WM_KEYDOWN messages. And of course many other messages are 'translated' that way.
A message is posted to every window that should receive it. The OS decides depending on the type of message whether a window should receive that message or not. Most messages are waited for by the system, i.e., the message won't get posted to another window until it was processed by the window. This has a great impact for broadcast messages: if one window doesn't return when handling that message, the queue is blocked and other windows won't receive the message anymore.
It depends on how your message is sent and how it's handled.
When you call SendMessage, if the target window is owned by the current thread, the call bypasses the message queue for the window and the window manager directly calls the windowproc on the target window. If the target window is owned by another thread, the window manager effectively calls PostMessage and pumps window messages until the target window returns from the window proc.
When you call PostMessage, the window manager marshals the message parameters and inserts the corresponding object onto the message queue for the target window. When it next calls GetMessage the message is removed from the message queue.
The window manager also registers for raw input events from the input devices (keyboard and/or mouse) and it generates messages for those input events. It then inserts those messages in the queue as appropriate (the processing of input events is complicated because it depends on what messages are already in the message queue for the window).
As Stefan indicated, TranslateMessage just translates accelerator keys - for instance it converts key sequences to WM_COMMAND messages.
Different kinds of OS interrupt handlers must be placing messages in the said 'message queue', but where within the process address space does this queue reside? How is it exposed to the interrupt handler code?
Windows are associated with threads. Each thread with a window has a thread queue in the process's address space. The OS has an internal queue in its own address space for the hardware-generated events. Using details of the event and other state information (e.g., which window has the focus), the OS translates the hardware events into messages that are then placed in the appropriate thread queue.
Messages that are posted are placed directly in the thread queue for the target window.
Messages that are sent are usually processed directly (bypassing the queue).
The details get hairy. For example, the thread queues are more than lists of messages--they also maintain some state information. Some messages (like WM_PAINT) aren't really queued, but synthesized from the additional state information when you query the queue and it's empty. Messages sent to windows owned by other threads are actually posted to the receiver's queue rather than being processed directly, but the system makes it appear like a regular blocking send from the caller's point of view. Hilarity ensues if this can cause deadlock (because of circular sends back to the original thread).
The Jeffrey Richter books have a lot (all?) of the gory details. My edition is old (Advanced Windows). The current edition seems to be called Windows via C/C++.
The OS does a LOT of work to make the message stream appear rational (and relatively simple) to the caller.
What does it mean to 'translate' the message? What does the call to TranslateMessage() really do?
It watches for virtual key messages and, when it recognizes a key-down/key-up combination, it adds character messages. If you don't call TranslateMessage, you won't receive character messages like WM_CHAR.
I suspect it sends the character message directly before returning (as opposed to posting them). I've never checked, but I seem to recall that the WM_CHAR messages arrive just before the WM_KEYUP.
Once dispatched by DispatchMessage(), what all places does the message swing by before reaching my WndProc (i.e. what does the OS do with it)?
DispatchMessage passes the message to the WndProc for the target window. Along the way, it some hooks may get a chance to see the message (and possibly interfere with it).
To address the last subquestion, a dispatched message will go to your WindowProc after it's been piped through all hooks (WH_CALLWNDPROC)
Not absolutely positive about this but my best guess says:
The queue is a system object that you access with Win32 API calls. It is not in your process address space at all. So the interrupt handlers can access it (probably through the HAL (Hardware Abstraction Layer) of the kernel).
In Win16, that call took the various subparts of a bigger message and mashed them into a whole. So TranslateMessage would add the WM_KEYPRESS when it found the corresponding WM_KEYDOWN WM_KEYUP sequence. It would also turn various button click messages into doubleclick messages based on internal setting and the timestamps of the messages. Whether it still does this in Win32, I don't know.
DispatchMessage is probably where Window message hooks get processed. So if there's a hook on your window, it is either called here or when the GetMessage is called. I'm not sure. Other than that, DispatchMessage just looks up the WndProc address associated with the window and calls it. There's not much else for it to do.
Hope that helps.

Resources