PostMessage does not trigger Message Handler - c++

I have a VC++ code that uses PostMessage to trigger a function call. Although the function gets called eventually, I see that the function does not get called right after PostMessage is executed. It does not even get called after the function containing the PostMessage command completes execution. I noticed that a few more functions got called before the desired function was called.
I would like to know what determines when exactly the callback for a message gets called.
The message is a WM_USER message.

The Windows event-driven model in a nutshell (with many important details simplified away):
There is a "message pump," which is a loop that, on each iteration, pulls a message out of a queue and "dispatches" it by calling the "window procedure" associated with the specific window, passing it the details from the message.
If you're using a framework, it's likely that the message pump and the window procedure are provided for you and that the provided window procedure calls your handler functions in response to the messages it receives.
When a message is posted, it's added to the queue, and nothing else happens to it until the message pump gets to it. There may be messages ahead of it in the queue, and/or a bunch of other code may run before execution returns to the message pump.
When a message is sent, the message is not added to the queue. Instead, the sending code will call the window procedure directly. (Caveat: this is an oversimplification. Things are more complicated when sending a message to another thread.)
So if other functions are being called before the one you expect from your posted message, here are some possibilities:
Other messages were already in the queue when you posted your message.
Other messages are being sent rather than posted, so they're handled immediately, and only when they're done and the message pump eventually runs again will your posted message be handled.
The message pump decided that other messages, which were posted after yours, are more important and therefore should be handled first. (This is not actually common. Certain types of messages, like WM_PAINT, are very low priority and are only generated when there's nothing in the queue, but I can't think of a case where a message takes priority over one that's already in the queue.)
You're posting your message during initialization before the message pump even starts. For example, if you create a window, post a message to it, and then start the message pump, it's possible that there will be a series of messages in the queue related to the window creation ahead of your posted message.

Not all messages are equal. PostMessage doesn't simply add it to a queue data structure; the OS will do a lot of manipulation and prioritizing. Different messages get different priorities, and some messages like WM_PAINT, cannot be sent like this at all.
So there's no way to generalize "when will PostMessage invoke the message handler?" It depends on which message you're sending, how busy the target message queue is, and how the target message loop behaves.
I don't think there is any concise list of how messages are prioritized.

Related

PostMessage: Messages not received

I'm looking for some feedback on an issue that I can workaround, but want to understand better. I have some multithreaded code where a worker thread uses the Win32 API PostMessage function to post a message to the main UI thread in order to update a TreeView. Some of the posted messages sometimes fail to ever appear via the UI thread's message pump, despite my logging showing that the PostMessage returned successfully.
I've already found numerous explanations of how this could happen if I'd done something funky in my message pump, due to the presence of a modal message pump in certain circumstances, but I'm not doing anything funky.
I think (but would like confirmed) that my problem is due to calling PostMessage too early in the UI thread's lifetime. My WinMain calls CreateWindowEx to create its main window, and the WM_CREATE handler for that window indirectly launches the background threads that will, fairly quickly, call PostMessage using the main windows's HWND, possibly even before the WM_CREATE handler finishes, very likely before WinMain's message pump is started.
Is it possible/likely that some messages in this situation would be lost, even though PostMessage returned success? In testing, I've determined that adding a small delay (Sleep(50)) in the worker thread before it calls PostMessage is enough to prevent any message loss. However, I'm not convinced that this is solving the underlying problem so would like to know if I need to keep digging.
EDIT:
There's only one message loop in all my code and it's not doing anything unusual beyond calling the usual TranslateAccelerator etc:
// Enter the message loop
while (GetMessage (&msg, NULL, 0, 0)) {
if (!TranslateMDISysAccel(hwndClient, &msg) && !TranslateAccelerator (hwndFrame, hAccel, &msg)) {
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
I've already found numerous explanations of how this could happen if I'd done something funky in my message pump, due to the presence of a modal message pump in certain circumstances, but I'm not doing anything funky.
Modal loops don't throw away window messages, unless they are coded wrong and don't pass unknown messages to TranslateMessage()/DispatchMessage() like they should.
I think (but would like confirmed) that my problem is due to calling PostMessage too early in the UI thread's lifetime.
If that were the case, PostMessage() would simply fail, but you have already ruled that out. As soon as a thread calls any user32.dll function, the message queue is created and can begin receiving messages, even if the queue is not polled right away.
Is it possible/likely that some messages in this situation would be lost, even though PostMessage returned success?
No. Something else is going on. Either your message loop is filtering messages incorrectly, or a malformed modal loop is discarding messages, or you are simply posting to the wrong HWND. Hard to say as you did not show any of your code.
In testing, I've determined that adding a small delay (Sleep(50)) in the worker thread before it calls PostMessage is enough to prevent any message loss.
What is your main thread normally doing during those 50ms? Sounds like something in your UI code is receiving and discarding your posted messages during that time.
On the other hand, how do the threads know which HWND to post to? Is your WM_CREATE handler passing its hwnd parameter to the threads, or are the threads relying on the HWND returned by CreateWindowEx()? In the latter case, PostMessage() should fail if called before CreateWindowEx() exits. Unless your receiving HWND variable is initially uninitialized and contains a random non-null value that PostMessage() interprets as a valid HWND elsewhere on the system.

WinProc() vs main message loop

I noticed that some messages in WinAPI can be retrieved only in the "main message loop" with PeekMessage() (like WM_QUIT), others can only be retrieved in the user defined winProc() function (like WM_CLOSE and WM_SIZE), and some messages like WM_MOUSEMOVE are retrieved with both.
What's the difference? How do I know where the WM message is going to be sent to?
Messages that were posted with a NULL window handle can only be retrieved in the message loop. Necessarily so, DispatchMessage() can't do its job. This is quite rare.
But yes, WM_QUIT, note how PostQuitMessage() does not take a window handle. That's rather inevitable, when you call PostQuitMessage() you (usually) don't have any window left so only a NULL window handle is sensible. Of course its real intention is to make GetMessage() return FALSE and thus terminate the message loop.
The only other case I can think of are messages generated with PostThreadMessage(). Note how this is a pretty dangerous function, it should never be used to post messages to a thread that ever displays any window. Such messages fall in the bit-bucket when another message loop pumps. Like the one that allows the user to move/resize a window. Or the one that keeps MessageBox() modal. It is only useful in process and thread interop marshaling.
So just ignore this, it is a corner-case.

What does WindProc do for me?

I have a multiple dialog MFC client app that i am working on. This client can receive a lot of messaging (>10Hz) to the main dialog, which often performs some small function, then forwards that message onto the another dialog for processing.
In my specific case, the main dialog receives messages relating to a vehicle location, updates a couple fields on that GUI, then passes it on vi a PostMessage to a window that displays all the vehicle information.
So basically, my question is this: what is the difference b/w posting the message, or just calling the dialog.update (which is a function i created)?
Well, since we don't know what your dialog.update() does, how are we to know what the difference is?
If you are doing another PostMessage, I'm not sure what the point of that is. Your program has to wait for another iteration of the message loop to retrieve your newly posted message and possibly another message could be received before that one is posted. Instead of PostMessage, you could use SendMessage which will send the message straight to the WndProc without having to iterate the message loop for another message.
I am thinking that if you are multi-threaded, then sending or posting messages will be a little more thread safe since Windows should switch contexts automatically. If you are single threaded, then it probably shouldn't matter.
I believe your application is multithreaded, and one of the thread is receivng the data, and is different than GUI thread. You should use PostMessage only from other thread to this dialog, and not SendMessage or direct call.
If you are receiving too many messages, you should buffer them - either by count (say 5000), or by some timeout. You may keep the messages into vector, list or any other collection you like. Later, when sending, post the address of this collection as WPARAM (or LPARAM) to the dialog. Dialog will get it, in a single bunch and would process it. This approach may not be correct as I am not aware about other design perspetives of your application.
You would need to trial-and-error approach, see where you get the actual performance and stability benefits.

Run windows GUI application in synchronized mode?

I am debugging GUI app on windows and I want to find out who is the sender of some message. On linux, I can run app in synchronized mode and find the sender in call stack. Is there any equivalent mode in windows?
AFAIK there's no built-in ability to do this.
But let's first investigate the problem. You want to know who's the sender of the message. You should know however that windows message processing can be classified by the following criterias:
Posted vs Sent messages (PostMessage vs SendMessage).
Messages sent to the window belonging to another thread vs sender thread.
Messages posted to a thread (not bound to a specific window, hence not processed by the window procedure).
You may trace directly the sender only when the message is sent (not posted) to a window, whereas the call to the SendMessage (or similar) was issued in the thread to which the window belongs. In such you will see the sender in the call stack.
In case the message was sent from another thread - you will not see it in the call stack. Simply because the call stack shows the call chain that belongs to the current thread only. When a message is sent from another thread the system performs the following:
Suspends the caller thread.
Puts this message to the queue of the thread that owns the window.
When that thread calls GetMessage (or similar) - the message is dispatched to the window.
Finally the OS resumes the caller thread. The SendMessage returns with the result that was returned by the window procedure.
In such a case you may try to identify the caller indirectly. Interrupt your program with the breakpoint, and try to search for suspended threads, which are blocked in a call to SendMessage or similar.
Finally, messages that are posted are impossible to trace by the above method. You may try to put a conditional breakpoint on a call to PostMessage, but if the caller belongs to another problem - this will be more complex.
valdo is correct. Calls to SendMessage call your applications wndproc directly. Calls to PostMessage posts the message to the message que and your application then recives the message via the message pump (the loop, getmessage, translatemessage, dispatchmessage). So , like he said, if the messages were sent via a SendMessage then the callee of the function will show in the call stack. If it was sent via PostMessage , it will not.

How to hook for particular windows message without subclassing?

Is there a way to hook for a particular windows message without subclassing the window.
There is WH_GETMESSAGE but that seems create performance issues.
Any other solutions apart from these which doesn't deteriorate performance?
AFAIK there's no better solution than what you mentioned. And, of course, subclassing the window is better than hooking all the messages of the thread.
Let's think which path the message passes up until it's handled by the window:
The message is either posted or sent to the window, either by explicit call to PostMessage/SendMessage or implicitly by the OS.
Posted messages only: eventually the thread pops this message from the message queue (by calling GetMessage or similar), and then calls DispatchMessage.
The OS invokes the window's procedure by calling CallWindowProc (or similar).
The CallWindowProc identifies the window procedore associated with the window (via GetClassLong/GetWindowLong)
The above procedure is called.
Subclassing - means replacing the window procedure for the target window. This seems to be the best variant.
Installing hook with WH_GETMESSAGE flag will monitor all the messages posted to the message queue. This is bad because of the following:
Performance reasons.
You'll get notified only for windows created in the specific thread
You'll get notified only for posted messages (sent messages will not be seen)
A "posted" message doesn't necessarily means "delivered". That is, it may be filtered by the message loop (thrown away without calling DispatchMessage).
You can't see what the actual window does and returns for that message.
So that subclassing seems much better.
One more solution - in case your specific message is posted (rather than sent) you may override the message loop, and for every retrieved message you may do some pre/post-processing