Thread messages are eaten by modal loops

Date:April 26, 2005 / year-entry #105
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20050426-18/?p=35783
Comments:    3
Summary:Thread messages (as generated by the PostThreadMessage function) do not go anywhere when passed to the DispatchMessage function. This is obvious if you think about it, because there is no window handle associated with a thread message. DispatchMessage has no idea what to do with a message with no associated window. It has no choice...

Thread messages (as generated by the PostThreadMessage function) do not go anywhere when passed to the DispatchMessage function. This is obvious if you think about it, because there is no window handle associated with a thread message. DispatchMessage has no idea what to do with a message with no associated window. It has no choice but to throw the message away.

This has dire consequences for threads which enter modal loops, which any thread with a window almost certainly will do at one time or another. Recall that the traditional modal loop looks like this:

while (GetMessage(&msg, NULL, 0, 0)) {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}

If a thread message is returned by the GetMessage function, it will just fall through the TranslateMessage and DispatchMessage without any action being taken. Lost forever.

Thread messages are generally to be avoided on threads that create windows, for this very reason. Of course, if you're going to create a window, why not use PostMessage instead, passing that window as the target of the posted message? Since there is now a window handle, the DispatchMessage function knows to give the message to your window procedure. Result: Message not lost.


Comments (3)
  1. Why not add an API to set a per-thread message callback for any thread-only messages? Then DispatchMessage could just call this.

  2. Adrian says:

    This seems related to why the timed message box back in the Modality series of articles didn’t work reliably. See http://blogs.msdn.com/oldnewthing/archive/2005/03/04/385100.aspx

    That article showed how to post a WM_QUIT message to break a modal loop, and then to remove the re-posted WM_QUIT message to keep the application from exiting. Unfortunately for me, it failed to remove the re-posted WM_QUIT because it was occluded by thread messages that were posted to the queue immediately after the modal loop exited.

    They mystery remains as to who would post such a message (and why). The sample application certainly wasn’t doing it. Since it happens reliably on two vanilla Windows XP boxes here at work, I suspect LANdesk Remote Control agent, as that is the only non-standard program running (and the only one I can’t uninstall thanks to our strict IT department).

  3. Fran├žois says:

    The documentation for PostThreadMessage hints that we should install a thread-specific hook to solve this problem.

    Why not simply always do this ? Even if I am in control of the thread’s implementation, sometimes ‘magic’ modal loops will appear (say I call into this library that uses COM under the covers).

    So maybe the rule is : whenever you PostThreadMessage, you MUST install a hook on the target thread to handle the thread messages ?

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index