c++windowsdouble-clickmouse-hook

MouseProc hook and WM_LBUTTONDBLCLK


I have a hook setup for getting mouse events in a plugin I develop. I need to get the WM_LBUTTONDBLCLK, and I expect the message flow to be:

WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK

If I call the next hook when dealing with the first WM_LBUTTONDOWN, then the flow is as expected. However, if I return my own result, then the expected double click comes as a mouse down message. Any idea why this is happening? I need the message to stop after I handle it, and not have it passed to the next hook.


Solution

  • After having done a little reading over at the MSDN, I think the explanation of this behaviour lies in this remark on the WM_LBUTTONDBLCLK page:

    Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which the system generates whenever the user presses, releases, and again presses the left mouse button within the system's double-click time limit.

    If your program is returning a nonzero value when it handles WM_LBUTTONDOWN or WM_LBUTTONUP, then those messages aren't sent to the target window -- as expected. However, my inference, based on the above quote, is that since no window with the CS_DBLCLKS style is therefore receiving the messages (since the hook prevents any window from receiving the messages), the system therefore doesn't feel like it needs to generate a WM_LBUTTONDBLCLK.

    To put it another way, the system only generates a WM_LBUTTONDBLCLK if and only if (a) a window receives the previous WM_LBUTTONDOWN/WM_LBUTTONUP messages and (b) that window has the CS_DBLCLKS style. Since your hook prevents condition (a) from being satisfied, WM_LBUTTONDBLCLK is never generated and so a WM_LBUTTONDOWN message is sent instead.

    As to a workaround, I doubt there's a perfect solution. I assume the reason why you want to receive the WM_LBUTTONDBLCLK message is so your hook knows whether or not a regular WM_LBUTTONDOWN message represents the second click of a double-click, right? In that case, what you could do is read the double-click time from the registry as Faisal suggests and have your hook measure the time between WM_LBUTTONDOWN messages, however there's a large chance that you will get inaccurate results (due to the lag time between the messages being sent). Alternatively if there's some way you could instead redirect the WM_LBUTTONDOWN/WM_LBUTTONUP messages to maybe a hidden window that your hook owns (which has the CS_DBLCLKS style), the system may end up generating a WM_LBUTTONDBLCLK message and sending it to your hidden window, which you can then process in that window's WndProc (though I don't have a lot of experience with hooking so I don't know if this is possible).