Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept single or double mouse click - only execute double click code on double click

I have a situation where I am handling both single & double mouse click events on a form. In both cases something has to be loaded, however when a double click occurs, I do not wish to execute the code attached to the single click event.

Is there a way to intercept the mouse click's and check if double or single and then execute the right event appropriately?

Perhaps by intercepting the WndProc of the window or something?

like image 746
Tony The Lion Avatar asked Jan 27 '11 09:01

Tony The Lion


1 Answers

No, that's pretty much impossible unless you have a time machine. And it doesn't really even make sense once you understand how Windows distinguishes double-clicks from single-clicks.

It turns out that Raymond Chen (a developer on the Windows Shell team) explains exactly that in a blog entry titled "Logical consequences of the way Windows converts single-clicks into double-clicks".

Specifically, Windows only knows to interpret something as a double-click because a second click has occurred within the interval specified by the GetDoubleClickTime function. Because it would require clairvoyance (as Raymond so eloquently puts it) to determine ahead of time if something is going to be a single or double click, the window manager goes ahead and sends a WM_LBUTTONDOWN message as soon as the first click is received. The WM_LBUTTONDBLCLK message is only sent later, after the second click is confirmed to actually represent a double-click. The upshot is that your application will always receive two WM_LBUTTONDOWN messages for each WM_LBUTTONDBLCLK message that is received.

Now, the .NET Framework designers understood how this process works and designed the events that are raised accordingly. Of course, they can't do anything about a single click always occurring before a double-click, but they were able to suppress the second click message if it is determined that the user intended that to be part of a double-click event. As the documentation for the Control.MouseClick event (which roughly corresponds to the WM_LBUTTONDOWN message) tells us:

Two single clicks that occur close enough in time, as determined by the mouse settings of the user's operating system, will generate a MouseDoubleClick event instead of the second MouseClick event.

Raymond's blog article that I linked to above does, however, propose a possible workaround for apps and developers who insist on a design where the double-click action is unrelated to the single-click action (although neither of us recommend that you actually do this):

Now suppose you're a program that nevertheless wants to continue with the dubious design of having the double-click action be unrelated to the single-click action. What do you do?

Well, one thing you could do is to do nothing on receipt of the WM_LBUTTONDOWN message aside from set a timer to fire in GetDoubleClickTime() milliseconds. [Corrected 10am.] If you get a WM_LBUTTONDBLCLK message within that time, then it was a double-click after all. If you don't, then it must have been a single-click, so you can do your single-click action (although a bit late).

like image 200
Cody Gray Avatar answered Oct 29 '22 10:10

Cody Gray