{"id":42343,"date":"2003-10-01T12:42:00","date_gmt":"2003-10-01T12:42:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2003\/10\/01\/why-do-i-get-spurious-wm_mousemove-messages\/"},"modified":"2003-10-01T12:42:00","modified_gmt":"2003-10-01T12:42:00","slug":"why-do-i-get-spurious-wm_mousemove-messages","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20031001-00\/?p=42343","title":{"rendered":"Why do I get spurious WM_MOUSEMOVE messages?"},"content":{"rendered":"\n<p>         In order to understand this properly, it helps to know where <code>WM_MOUSEMOVE<\/code> messages         come from.      <\/p>\n<p>         When the hardware mouse reports an interrupt, indicating that the physical mouse has         moved, Windows determines which thread should receive the mouse move message and sets         a flag on that thread&#8217;s input queue that says, &#8220;The mouse moved, in case anybody cares.&#8221;         (Other stuff happens, too, which we will ignore here for now. In particular, if a         mouse button event arrives, a lot of bookkeeping happens to preserve the virtual input         state.)      <\/p>\n<p>         When that thread calls a message retrieval function like <code>GetMessage<\/code>,         and the &#8220;The mouse moved&#8221; flag is set, Windows inspects the mouse position and does         the work that is commonly considered to be part of mouse movement: Determining the         window that should receive the message, changing the cursor, and determining what         type of message to generate (usually <code>WM_MOUSEMOVE<\/code> or perhaps <code>WM_NCMOUSEMOVE<\/code>).      <\/p>\n<p>         If you understand this, then you already see the answer to the question, &#8220;Why does         my program not receive all mouse messages if the mouse is moving too fast?&#8221;      <\/p>\n<p>         If your program is slow to call <code>GetMessage<\/code>, then multiple mouse interrupts         may arrive before your program calls <code>GetMessage<\/code> to pick them up. Since         all that happens when the mouse interrupt occurs is that a flag is set, if two interrupts         happen in succession without a message retrieval function being called, then the second         interrupt will merely set a flag that is already set, which has no effect. The net         effect is that the first interrupt acts as if it has been &#8220;lost&#8221; since nobody bothered         to pick it up.      <\/p>\n<p>         You should also see the answer to the question, &#8220;How fast does Windows deliver mouse         movement messages?&#8221;      <\/p>\n<p>         The answer is, &#8220;As fast as you want.&#8221; If you call <code>GetMessage<\/code> frequently,         then you get mouse messages frequently; if you call <code>GetMessage<\/code> rarely,         then you get mouse messages rarely.      <\/p>\n<p>         Okay, so back to the original question, &#8220;Why do I get spurious WM_MOUSEMOVE messages?&#8221;      <\/p>\n<p>         Notice that the delivery of a mouse message includes lots of work that is typically         thought of as being part of mouse movement. Often, Windows wants to do that follow-on         work even though the mouse hasn&#8217;t actually moved. The most obvious example is when         a window is shown, hidden or moved. When that happens, the mouse cursor may be over         a window different from the window it was over previously (or in the case of a move,         it may be over a different part of the same window). Windows needs to recalculate         the mouse cursor (for example, the old window may have wanted an arrow but the new         window wants a pointy finger), so it <i>artificially sets the &#8220;The mouse moved, in         case anybody cares&#8221; flag<\/i>. This causes all the follow-on work to happen, a side-effect         of which is the generation of a spurious <code>WM_MOUSEMOVE<\/code> message.      <\/p>\n<p>     So if your program wants to detect whether the mouse has moved, you need to add a     check in your <code>WM_MOUSEMOVE<\/code> that the mouse position is different from     the position reported by the previous <code>WM_MOUSEMOVE<\/code> message.  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In order to understand this properly, it helps to know where WM_MOUSEMOVE messages come from. When the hardware mouse reports an interrupt, indicating that the physical mouse has moved, Windows determines which thread should receive the mouse move message and sets a flag on that thread&#8217;s input queue that says, &#8220;The mouse moved, in case [&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-42343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>In order to understand this properly, it helps to know where WM_MOUSEMOVE messages come from. When the hardware mouse reports an interrupt, indicating that the physical mouse has moved, Windows determines which thread should receive the mouse move message and sets a flag on that thread&#8217;s input queue that says, &#8220;The mouse moved, in case [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/42343","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=42343"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/42343\/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=42343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=42343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=42343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}