{"id":93885,"date":"2016-07-15T07:00:00","date_gmt":"2016-07-15T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=93885"},"modified":"2019-03-13T11:04:22","modified_gmt":"2019-03-13T18:04:22","slug":"20160715-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20160715-00\/?p=93885","title":{"rendered":"Trying to recover from enhancement software that generates fake input incorrectly"},"content":{"rendered":"<p>A customer had a program that supported the mouse wheel, and they found that some laptops have trackpad enhancement software which supports a gesture for turning the mouse wheel. When the enhancement software recognizes the gesture, it <i>sends<\/i> a <code>WM_MOUSE&shy;WHEEL<\/code> message to the foreground window.. This causes problems for the program because there are various things that are not allowed when processing an inbound sent message. Fortunately, <a HREF=\"https:\/\/msdn.microsoft.com\/library\/windows\/desktop\/ms644941(v=vs.85).aspx\">they can detect whether they are in this situation<\/a>, but it&#8217;s not clear how they can recover from it. &#8220;We have been brainstorming and thinking that if we see this problem, we will use <code>Post&shy;Message<\/code> to put the message &#8216;back&#8217; into our queue.&#8221; <\/p>\n<p>The trackpad software is supposed to be using <code>Send&shy;Input<\/code> so that the wheel message orders correctly with the other messages in your input queue. The <code>Send&shy;Message<\/code> delivers the message immediately (or as immediately as possible), and <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/\">messages posted with the <code>Post&shy;Message<\/code> function are processed ahead of input<\/a>, both of which are wrong when you are trying to simulate input. Even your attempt to delay processing by calling <code>Post&shy;Message<\/code> won&#8217;t help because posted messages are processed ahead of input. <\/p>\n<p>Here&#8217;s a diagram which is inaccurate but may help to get the point across: <\/p>\n<table BORDER=\"0\" CELLPADDING=\"3\" STYLE=\"border-collapse: collapse\" TITLE=\"A stack of messages. At the top are inbound sent messages. There is an arrow labeled &quot;SendMessage inserts messages here&quot; at the bottom of that section. Next are inbound posted messages. There is an arrow labeled &quot;PostMessage inserts messages here&quot; at the bottom of that section. Last are inbound input messages. There is an arrow labeled &quot;SendInput inserts messages here&quot; at the bottom of that section.\">\n<tr>\n<td STYLE=\"border: 1px black;border-style: solid solid none solid\"><\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid\">Inbound sent messages<\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid solid solid\"><\/td>\n<td ROWSPAN=\"2\" VALIGN=\"center\">&larr; <code>SendMessage<\/code> inserts messages here<\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid\"><\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid\">Inbound posted messages<\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid solid solid\"><\/td>\n<td ROWSPAN=\"2\" VALIGN=\"center\">&larr; <code>PostMessage<\/code> inserts messages here<\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid\"><\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid\">Inbound input messages<\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: 1px black;border-style: none solid solid solid\"><\/td>\n<td ROWSPAN=\"2\" VALIGN=\"center\">&larr; <code>SendInput<\/code> inserts messages here<\/td>\n<\/tr>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/table>\n<p>Basically, the enhancement software already screwed you with respect to message ordering. You won&#8217;t be able to make a perfect recovery; all you can do is try to make the best of a bad situation. <\/p>\n<p>One idea is to use the <code>Reply&shy;Message<\/code> function in your message handler. The <code>Reply&shy;Message<\/code> function says, &#8220;Hey, like, act like I returned from this message for the purpose of inter-thread <code>Send&shy;Message<\/code> bookkeeping, such as unblocking the sender, but let me keep running anyway.&#8221; This may be enough to get the parts of the system that normally say &#8220;No, you can&#8217;t do that from inside a sent message&#8221; to realize &#8220;Oh, wait, the synchronous part is over. Carry on.&#8221; <\/p>\n<p>If that doesn&#8217;t work, then you can use the <code>Send&shy;Input<\/code> message to generate a wheel message back into the input queue. The wheel input will be a bit late (by the amount of time it took your window procedure to receive the message), but it&#8217;ll probably be close enough to correct that most people won&#8217;t notice. There&#8217;s most likely already a lag in the gesture recognition in the enhancement software, so a little more lag probably isn&#8217;t the end of the world. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Try to reprocess it the right way.<\/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-93885","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Try to reprocess it the right way.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/93885","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=93885"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/93885\/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=93885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=93885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=93885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}