{"id":37553,"date":"2004-10-15T07:00:00","date_gmt":"2004-10-15T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/10\/15\/logical-consequences-of-the-way-windows-converts-single-clicks-into-double-clicks\/"},"modified":"2004-10-15T07:00:00","modified_gmt":"2004-10-15T07:00:00","slug":"logical-consequences-of-the-way-windows-converts-single-clicks-into-double-clicks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20041015-00\/?p=37553","title":{"rendered":"Logical consequences of the way Windows converts single-clicks into double-clicks"},"content":{"rendered":"<p><P>\nFirst, I&#8217;m going to refer you to\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/userinput\/mouseinput\/aboutmouseinput.asp\">\nthe MSDN documentation on mouse clicks<\/A>,\nsince that&#8217;s the starting point.\nI&#8217;m going to assume that you know the mechanics of how\nsingle-clicks are converted to double-clicks.\n<\/P>\n<P>\nOkay, now that you&#8217;ve read it, let&#8217;s talk about some logical\nconsequences of that article and what it means for the way\nyou design your user interface.\n<\/P>\n<P>\nFirst, some people design their double-click action to be\nsomething unrelated to the single-click action.\nThey want to know if they can suppress the initial\nWM_LBUTTONDOWN of the double-click sequence.\n<\/P>\n<P>\nOf course, you realize that that would require clairevoyance.\nWhen the mouse button goes down for the first time, the\nwindow manager doesn&#8217;t know whether another click will come\nor not.  (Heck, often the user doesn&#8217;t know either!)\nSo it spits out a WM_LBUTTONDOWN and waits for more.\n<\/P>\n<P>\nNow suppose you&#8217;re a program that nevertheless wants to\ncontinue with the dubious design of having the double-click\naction be unrelated to the single-click action.  What do you do?\n<\/P>\n<P>\nWell, one thing you could do is to do nothing on receipt\nof the WM_LBUTTONDOWN message aside from set a timer to fire\nin\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/userinput\/mouseinput\/mouseinputreference\/mouseinputfunctions\/getdoubleclicktime.asp\">\n<CODE>GetDoubleClickTime()<\/CODE><\/A> milliseconds.\n[Corrected 10am.]\nIf you get a WM_LBUTTONDBLCLK message within that time,\nthen it was a double-click after all.  If you don&#8217;t, then\nit must have been a single-click, so you can do your single-click\naction (although a bit late).\n<\/P>\n<P>\nThis &#8220;wait a tick&#8221; technique is also necessary if you don&#8217;t\nhave a double-click action, but the second click causes trouble\nin conjunction with the first click.  Why is this necessary?\nBecause many users double-click everything.\nHere are some examples of where the &#8220;delayed action to avoid\nthe second click&#8221; can be seen:\n<\/P>\n<UL>\n<LI>\nThe context menu that appears for taskbar notification\nicons.  If the context menu appeared immediately upon the first click,\nthen the second click would dismiss the context menu, leaving the\nuser confused.  &#8220;I clicked and something happened and then it went\naway.&#8221;  (Users don&#8217;t say &#8220;I double-clicked&#8221;; they just say that they\nclicked. Double-click is the only thing they know how to do, so they\njust call it &#8220;click&#8221;. For the same reason you don&#8217;t say &#8220;I drove my\nblue car&#8221; if you have only one car.)\n<LI>\nIf Explorer is in one-click mode, it waits to see if there is a second\nclick, and if so, it ignores it.  Otherwise, when people double-click,\nthey launch two copies of the program.\nFurthermore, if you suppress the second click but don&#8217;t wait a tick,\nthen the program they launched gets stuck <STRONG>behind<\/STRONG>\nthe Explorer window, since the user clicked on Explorer after launching\nthe program.\n<LI>\nThe XP style Start button ignores the second click.\nOtherwise, when people double-click the Start button, the first\nclick would open the Start menu and the second click would dismiss it!\n(This is sometimes known as &#8220;debouncing&#8221;.)\n<\/UL>\n<P>\n<\/P>\n<P>\nLet&#8217;s demonstrate how you might implement click delay.\nStart with\n<A href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/07\/23\/54576.aspx\">\nthe scratch program<\/A> and add the following:\n<\/P>\n<PRE>\nvoid CALLBACK DelayedSingleClick(HWND hwnd, UINT,\n                                 UINT_PTR id, DWORD)\n{\n    KillTimer(hwnd, id);\n    MessageBeep(MB_OK);\n}<\/p>\n<p>void OnLButtonDown(HWND hwnd, BOOL fDoubleClick,\n                   int x, int y, UINT keyFlags)\n{\n    if (fDoubleClick) {\n        KillTimer(hwnd, 1);\n        MessageBeep(MB_ICONASTERISK);\n    } else {\n        SetTimer(hwnd, 1, GetDoubleClickTime(),\n                 DelayedSingleClick);\n    }\n}<\/p>\n<p>    HANDLE_MSG(hwnd, WM_LBUTTONDOWN, OnLButtonDown);\n    HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK, OnLButtonDown);\n<\/PRE>\n<P>\nAlso, since we&#8217;re messing with double clicks, we should turn them on:\n<\/P>\n<PRE>\n    wc.style = <FONT COLOR=\"blue\">CS_DBLCLKS<\/FONT>;\n<\/PRE>\n<P>\nWhen you run this program, click and double-click in the client\narea.  Notice that the program doesn&#8217;t react to the single click\nuntil after your double-click timeout has elapsed, because it&#8217;s\nwaiting to see if you are going to continue to click a second time\n(and therefore double-click instead of single-click).\n<\/P>\n<P>\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/10\/18\/243925.aspx\">\nNext time<\/A>, we&#8217;ll look at clicks beyond two.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>First, I&#8217;m going to refer you to the MSDN documentation on mouse clicks, since that&#8217;s the starting point. I&#8217;m going to assume that you know the mechanics of how single-clicks are converted to double-clicks. Okay, now that you&#8217;ve read it, let&#8217;s talk about some logical consequences of that article and what it means for the [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-37553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>First, I&#8217;m going to refer you to the MSDN documentation on mouse clicks, since that&#8217;s the starting point. I&#8217;m going to assume that you know the mechanics of how single-clicks are converted to double-clicks. Okay, now that you&#8217;ve read it, let&#8217;s talk about some logical consequences of that article and what it means for the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37553","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=37553"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37553\/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=37553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=37553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=37553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}