It depends on how you define a "hotkey". You can not use RegisterHotkey with VK_LBUTTON or VK_RBUTTON but you can hook the mouse if you want. There are a couple of hooks you might find interesting, first it's the regular low-level mouse hook and there is also a hook called journal recording. The latter is normally used to record macros but you'll get information about every mouse movement using it.
Darn, can't we trap double clicks for SetWindowsHookEx? I am trying the ff. code but WM_LBUTTONDBLCLK is not being trapped...
Code:
Private Const WM_LBUTTONDBLCLK = &H203
Private Const WM_RBUTTONDBLCLK = &H206
Private Const HC_ACTION = 0&
Public Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim MouseData As MOUSEHOOKSTRUCT
If nCode >= HC_ACTION Then
Select Case wParam
Case WM_LBUTTONDBLCLK
ClickCounterDbLeft = ClickCounterDbLeft + 1
If RightDoubleClick = True Then
MsgBox "trapped!"
RightDoubleClick = False
End If
Case WM_RBUTTONDBLCLK
RightDoubleClick = True
End Select
End If
LowLevelMouseProc = CallNextHookEx(m_Hook, nCode, wParam, lParam)
End Function
Regards,
™
As a gesture of gratitude please consider rating helpful posts. c",)
That's correct. The only messages you will recieve is WM_[L|R]BUTTON[DOWN|UP], WM_MOUSEMOVE, and WM_MOUSEWHEEL. It will never send any WM_LBUTTONDBLCLICK and there is a good reason for that. Since this will be a system wide hook you will recieve the messages before they are sent to the message queue for the actual window the mouse is over. A double click event is only raised for a window that has the CS_DBLCLK style. Not all windows have this style (for example a regular command button doesn't have this style and it never gets a dblclick message). Since you recieve the message first the OS have not yet converted the second WM_LBUTTONDOWN message to a WM_LBUTTONDBLCLICK message (since it might not even do that).
You have to implement this yourself by checking the time elapsed between two WM_LBUTTONDOWN messages and also messure the amount the mouse have moved between these messages. If they are within the correct metrics then a double click has occured. You can get the metrics by calling GetSystemMetrics with the SM_CXDOUBLECLK and SM_CYDOUBLECLK indexes (for the amount a mouse pointer can move). You get the double click time (in milliseconds) with a simple call to the GetDoubleClickTime function.
I am trying to capture the ff. combination but I could find the right logic for now, can anyone point me where I am doing wrong?
LEFT DOUBLE CLICK
RIGHT SINGLE CLICK
LEFT DOUBLE CLICK
Code:
Public Function LowLevelMouseProc(ByVal nCode As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Dim MouseData As MOUSEHOOKSTRUCT
' Display the screen resolution -- i.e., the width and height of the screen.
If nCode = HC_ACTION Then
If bolFirstCriteriaMet = False Then
Debug.Print "first"
Select Case wParam
Case WM_LBUTTONDOWN
If bolLeftClicked = True Then
CopyMemory MouseData, ByVal lParam, Len(MouseData)
If ((MouseData.pt.x - lngPreviousX) <= lngDoubleClickX) And ((MouseData.pt.y - lngPreviousY) <= lngDoubleClickY) And ((GetTickCount - time1) <= GetDoubleClickTime) Then
bolFirstCriteriaMet = True
Debug.Print "double first"
End If
bolLeftClicked = False
Else
time1 = GetTickCount
CopyMemory MouseData, ByVal lParam, Len(MouseData)
lngPreviousX = MouseData.pt.x
lngPreviousY = MouseData.pt.y
bolLeftClicked = True
End If
Case WM_LBUTTONUP
If bolLeftClicked = False Then
ResetCriteria wParam
End If
Case WM_MOUSEMOVE
Case Else
ResetCriteria wParam
End Select
ElseIf bolSecondCriteriaMet = False Then
Debug.Print "second"
Select Case wParam
Case WM_RBUTTONDOWN
bolSecondCriteriaMet = True
Debug.Print "right"
Case WM_LBUTTONUP, WM_MOUSEMOVE
Case Else
ResetCriteria wParam
End Select
ElseIf bolThirdCriteriaMet = False Then
Debug.Print "third"
Select Case wParam
Case WM_LBUTTONDOWN
If bolLeftClicked = True Then
CopyMemory MouseData, ByVal lParam, Len(MouseData)
If ((MouseData.pt.x - lngPreviousX) <= lngDoubleClickX) And ((MouseData.pt.y - lngPreviousY) <= lngDoubleClickY) And ((GetTickCount - time1) <= GetDoubleClickTime) Then
bolThirdCriteriaMet = True
Debug.Print "Hotkey Successful", Time
ResetCriteria wParam
Else
ResetCriteria wParam
End If
Else
time1 = GetTickCount
CopyMemory MouseData, ByVal lParam, Len(MouseData)
lngPreviousX = MouseData.pt.x
lngPreviousY = MouseData.pt.y
bolLeftClicked = True
End If
Case WM_RBUTTONUP, WM_LBUTTONUP, WM_MOUSEMOVE
Case Else
ResetCriteria wParam
End Select
End If
End If
LowLevelMouseProc = CallNextHookEx(m_Hook, nCode, wParam, lParam)
End Function
Private Sub ResetCriteria(ByVal lParam As Long)
Debug.Print lParam
bolFirstCriteriaMet = False
bolSecondCriteriaMet = False
bolThirdCriteriaMet = False
bolLeftClicked = False
End Sub
Last edited by dee-u; Nov 5th, 2008 at 11:07 AM.
Regards,
™
As a gesture of gratitude please consider rating helpful posts. c",)
It crashed for me as well, I had to change line #144 to this:
Code:
Debug.Print "Hotkey Successful", VBA.Time$
However there seems to be something wrong with how you calculate the double click. I sometimes need to tripple click, right click, double click for it to work. This usually happens when I pressed the mouse once and then move it slightly to do the first double click.
As soon as I move my mouse over the form it ends (hook crashed I suppose?).
The one above (MouseHookTest.zip ) seems to work OK for me though.
Oooppsss, I removed MouseHookTest.zip thinking it is the faulty one without double checking your reply, have you tried the workaround of Joacim? It is working fine here without the crashes...
Regards,
™
As a gesture of gratitude please consider rating helpful posts. c",)
It crashed for me as well, I had to change line #144 to this:
Code:
Debug.Print "Hotkey Successful", VBA.Time$
However there seems to be something wrong with how you calculate the double click. I sometimes need to tripple click, right click, double click for it to work. This usually happens when I pressed the mouse once and then move it slightly to do the first double click.
I guess you are right, I am working it out, thanks for the input...
Regards,
™
As a gesture of gratitude please consider rating helpful posts. c",)
Oooppsss, I removed MouseHookTest.zip thinking it is the faulty one without double checking your reply, have you tried the workaround of Joacim? It is working fine here without the crashes...
OK that seemed to do the trick, no more crashing.
As far as the mouse clicking hot-key goes it doesn't seem to be reliable, when I first start its OK but then it fails and keeps failing.
EDIT
I sometimes need to tripple click
Ya a couple times when it seemd to stop working then all of a sudden it fired and I'm not sure what clicks I was sending. I think the best way to test it would be to make another program that just simulates mouse clicking.
Last edited by Edgemeal; Nov 5th, 2008 at 12:08 PM.
The following seems to do the trick though I need you guys to help me out in testing it further. I utilized a timer to restart after a period of milliseconds...
Seems OK here, I got tired of clicking the mouse so I made a simple mouse click sim to send the hot clicks every 5 seconds and it passed over 50 times in a row before I stopped it.
FWIW I was just using 60ms intervals between mouse clicks......
I only tested it by hand for about 15 minutes and probably sent the hot key around 20 times and it worked just like it is supposed to. I tried the simulator method using 60ms pauses between clicks and it never failed on that either.
So now I'd say the only real test left would be to actually put it to use in a program thats running 24/7 and periodically send the hotkey over a weeks time, if it doesn't fail I'd say its golden.
I only tested it by hand for about 15 minutes and probably sent the hot key around 20 times and it worked just like it is supposed to. I tried the simulator method using 60ms pauses between clicks and it never failed on that either.
So now I'd say the only real test left would be to actually put it to use in a program thats running 24/7 and periodically send the hotkey over a weeks time, if it doesn't fail I'd say its golden.
I don't have a machine that runs 24/7 to test it but for now I can tell that it works though I am still a little worried with performance on using timers for calculating the elapsed time...
Regards,
™
As a gesture of gratitude please consider rating helpful posts. c",)