{"id":6193,"date":"2012-11-01T07:00:00","date_gmt":"2012-11-01T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2012\/11\/01\/when-you-synthesize-input-with-sendinput-you-are-also-synthesizing-the-timestamp\/"},"modified":"2012-11-01T07:00:00","modified_gmt":"2012-11-01T07:00:00","slug":"when-you-synthesize-input-with-sendinput-you-are-also-synthesizing-the-timestamp","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20121101-00\/?p=6193","title":{"rendered":"When you synthesize input with SendInput, you are also synthesizing the timestamp"},"content":{"rendered":"<p>\nA customer was reporting a problem when they used the\n<code>Send&shy;Input<\/code> function to simulate a drag\/drop\noperation for automated testing purposes.\n<\/p>\n<blockquote CLASS=\"q\">\n<p>\nI see the mouse move from one location to another,\nand the starting and stopping locations are correct on the screen,\nbut the mouse moves instantaneously rather than waiting 500ms between\noperations.\nHere&#8217;s how I&#8217;m sending the input.\n<\/p>\n<pre>\nINPUT input[3] = { 0 };\n\/\/ Click\ninput[0].type = INPUT_MOUSE;\ninput[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;\ninput[0].mi.time = 500;\n\/\/ Drag\ninput[1].type = INPUT_MOUSE;\ninput[1].mi.dwFlags = MOUSEEVENTF_MOVE;\ninput[1].mi.dx = 100;\ninput[1].mi.dy = 100;\ninput[1].mi.time = 1000;\n\/\/ Release\ninput[2].type = INPUT_MOUSE;\ninput[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;\ninput[2].mi.time = 500;\nSendInput(3, input, sizeof(INPUT));\n<\/pre>\n<\/blockquote>\n<p>\nWell, yeah, all the events occur immediately\nbecause you submitted them all at once.\n<\/p>\n<p>\nThe <code>time<\/code> field in the\n<code>MOUSE&shy;INPUT<\/code> structure is not for\nintroducing delays in playback.\nThough I&#8217;m not sure what the customer thought\nthe <code>time<\/code> field was.\nThey say that they want a 500ms delay between operations.\nAt first, I thought that they may have misinterpreted\nit as a delay relative to the time the\n<code>Send&shy;Input<\/code> call is made,\nsince they set\n<code>input[0].mi.time<\/code> to 500 and\n<code>input[1].mi.time<\/code> to 1000.\nBut if thay were the case, then setting\n<code>input[2].mi.time<\/code> to 500\nwould end up going backward in time.\nBut looking at the big picture,\nit&#8217;s probably not worth trying to figure out what they\nwere thinking,\nsince that code will have to be scrapped anyway.\n<\/p>\n<p>\nThe <code>time<\/code> field is for letting an input source\n(typically a hardware device)\nsay,\n&#8220;Hi,\num, the mouse left button went down at 9:30 this morning.\nYes, I know it&#8217;s already 10am.\nThe PCI bus got a flat tire,\nand then the spare was also flat,\nand really there&#8217;s no point going into the details.\nSorry this message arrived late.&#8221;\nThe window manager (and anybody else who bothers to check\nthe <code>time<\/code> member of the <code>MSG<\/code> structure)\nuses this information to do things like\ndetect double-clicks.\nIf the input source later reports,\n&#8220;Hi, um, the mouse left button went up at 9:30:00.100 this morning,\nsorry for the late report,&#8221;\nthe window manager says,\n&#8220;Well, that was only 100 milliseconds after the button went down\n<i>thirty minutes ago<\/i>,\nso I guess that&#8217;s a double-click after all.\n<i>Could you try to be a bit more prompt with this information\nin the future?<\/i>&#8221;\n(Sarcasm added.)\n<\/p>\n<p>\nIn other words, the <code>time<\/code> member of the\n<code>MOUSE&shy;INPUT<\/code> structure is for backdating input\nevents.\nThey still get delivered immediately,\nbut the timestamp allows the window manager\n(and other code which looks at the timestamp)\nto make decisions about how they should respond.\n<\/p>\n<p>\nNote that post-dating the timestamp does not cause the\ninput delivery to be delayed,\nand back-dating the timestamp does not cause the input to be\ninserted into the input stream ahead of other input.\nThe input is merely delivered with a timestamp in the future\nor in the past.\n(And who knows what sort of havoc that will create\nif a program checks the timestamps and notices that they\nare either from the future or have traveled back in time.\nMaybe you&#8217;ll get\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/01\/31\/10122197.aspx\">\na call from Microsoft Research asking for\nmore information about your time machine<\/a>.)\n<\/p>\n<p>\nIf you want three input events to take place with a 500ms\ndelay between them,\nthen you need to call\n<code>Send&shy;Input<\/code> three times,\nwith a 500ms delay between the calls.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer was reporting a problem when they used the Send&shy;Input function to simulate a drag\/drop operation for automated testing purposes. I see the mouse move from one location to another, and the starting and stopping locations are correct on the screen, but the mouse moves instantaneously rather than waiting 500ms between operations. Here&#8217;s how [&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-6193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer was reporting a problem when they used the Send&shy;Input function to simulate a drag\/drop operation for automated testing purposes. I see the mouse move from one location to another, and the starting and stopping locations are correct on the screen, but the mouse moves instantaneously rather than waiting 500ms between operations. Here&#8217;s how [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6193","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=6193"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6193\/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=6193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=6193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=6193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}