{"id":33453,"date":"2005-11-04T09:58:33","date_gmt":"2005-11-04T09:58:33","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/11\/04\/why-is-there-a-special-postquitmessage-function\/"},"modified":"2005-11-04T09:58:33","modified_gmt":"2005-11-04T09:58:33","slug":"why-is-there-a-special-postquitmessage-function","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20051104-33\/?p=33453","title":{"rendered":"Why is there a special PostQuitMessage function?"},"content":{"rendered":"<p>Why is there a special PostQuitMessage function? Because it&#8217;s not really a posted message.<\/p>\n<p> Commenter A. Skrobov asked, &#8220;<a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/02\/22\/378018.aspx#378042\">What&#8217;s the difference<\/a> between <code> <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/windowing\/messagesandmessagequeues\/messagesandmessagequeuesreference\/messagesandmessagequeuesfunctions\/postquitmessage.asp\"> PostQuitMessage<\/a><\/code> and <code> <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/windowing\/messagesandmessagequeues\/messagesandmessagequeuesreference\/messagesandmessagequeuesfunctions\/postthreadmessage.asp\"> PostThreadMessage<\/a>(GetCurrentThreadId, WM_QUIT)<\/code>?&#8221; <\/p>\n<p> They are not equivalent, though they may look that way at first glance. The differences are subtle but significant. <\/p>\n<p> Like the <code>WM_PAINT<\/code>, <code>WM_MOUSEMOVE<\/code>, and <code>WM_TIMER<\/code> messages, the <code>WM_QUIT<\/code> message is not a &#8220;real&#8221; posted message. Rather, it is one of those messages that the system generates <strong>as if<\/strong> it were posted, even though it wasn&#8217;t. And like the other messages, the <code>WM_QUIT<\/code> message is a &#8220;low priority&#8221; message, generated only when the message queue is otherwise empty. <\/p>\n<p> When a thread calls <code>PostQuitMessage<\/code>, a flag in the queue state is set that says, &#8220;If somebody asks for a message and there are no posted messages, then manufacture a <code>WM_QUIT<\/code> message.&#8221; This is just like the other &#8220;virtually posted&#8221; messages. <code>WM_PAINT<\/code> messages are generated on demand if there are any invalid regions, <a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/10\/01\/55108.aspx\"> <code>WM_MOUSEMOVE<\/code> messages are generated on demand if the mouse has moved since the last time you checked<\/a>, and <code>WM_TIMER<\/code> messages are generated on demand if there are any due timers. And since the message is &#8220;virtually posted&#8221;, multiple calls coalesce, in the same way that multiple paint messages, multiple mouse motions, and multiple timer messages also coalesce. <\/p>\n<p> Why is <code>WM_QUIT<\/code> handled like a low-priority message? <\/p>\n<p> Because the system tries not to inject a <code>WM_QUIT<\/code> message at a &#8220;bad time&#8221;; instead it waits for things to &#8220;settle down&#8221; before generating the <code>WM_QUIT<\/code> message, thereby reducing the chances that the program might be in the middle of a multi-step procedure triggered by a sequence of posted messages. <\/p>\n<p> If you <code>PeekMessage(..., PM_NOREMOVE)<\/code> a <code>WM_QUIT<\/code> message, this returns a <code>WM_QUIT<\/code> message but does not clear the flag. The <code>WM_QUIT<\/code> message virtually &#8220;stays in the queue&#8221;. <\/p>\n<p> As another special behavior, the generated <code>WM_QUIT<\/code> message bypasses the message filters passed to the <code>GetMessage<\/code> and <code>PeekMessage<\/code> functions. If the internal &#8220;quit message pending&#8221; flag is set, then you will get a <code>WM_QUIT<\/code> message once the queue goes quiet, regardless of what filter you pass. <\/p>\n<p> By comparison, <code>PostThreadMessage<\/code> just places the message in the thread queue (for real, not virtually), and therefore it does not get any of the special treatment that a real <code>PostQuitMessage<\/code> triggers. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Why is there a special PostQuitMessage function? Because it&#8217;s not really a posted message. Commenter A. Skrobov asked, &#8220;What&#8217;s the difference between PostQuitMessage and PostThreadMessage(GetCurrentThreadId, WM_QUIT)?&#8221; They are not equivalent, though they may look that way at first glance. The differences are subtle but significant. Like the WM_PAINT, WM_MOUSEMOVE, and WM_TIMER messages, the WM_QUIT message [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-33453","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Why is there a special PostQuitMessage function? Because it&#8217;s not really a posted message. Commenter A. Skrobov asked, &#8220;What&#8217;s the difference between PostQuitMessage and PostThreadMessage(GetCurrentThreadId, WM_QUIT)?&#8221; They are not equivalent, though they may look that way at first glance. The differences are subtle but significant. Like the WM_PAINT, WM_MOUSEMOVE, and WM_TIMER messages, the WM_QUIT message [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/33453","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=33453"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/33453\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=33453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=33453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=33453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}