Here's my sample AHK low level mouse hook. The comments should be pretty self-explanatory. This is the hook I'm hoping to implement in eXpresso.
#Persistent
#NoEnv
SetBatchLines -1
ListLines off
pMouseHook := RegisterCallback("MouseHookProc", "", 3) ; LowLevelMouseProc
hMouseHook := DllCall("SetWindowsHookEx", "int", 14, "uint", pMouseHook, "uint", DllCall("GetModuleHandle", "uint", 0), "uint", 0) ; set the WH_MOUSE_LL hook
DblClick := DllCall("GetDoubleClickTime") ; gets system dbl click time
DllCall("SetDoubleClickTime", "uint", 30) ; set a very low system dbl click time
; this will allow us to programmatically send our own dbl clicks without interference from the system
; effectively disabling human dbl clicks
; window classes for dbl click subroutine
; for this example we're handling dbl clicks on the Desktop and Explorer windows
aWinClass := "Progman,CabinetWClass,ExploreWClass"
fromEnter := False ; init variable
OnExit, ExitSub ; unregister the hook on exit
Return
; catch the Enter button as well
$Enter::
Critical
fromEnter := True ; cannot use A_ThisHotKey
SetTimer, DoubleClick, -10 ; run timed sub only once
Return
MouseHookProc(nCode, wParam, lParam)
{
Critical ; prevent this thread from being interrupted
Global DblClick, ClickTime, hMouseHook, MouseX, MouseY, fromEnter
; only process messages withe nCode >= 0
; incoming callback params are UINTs, so this is the test for >= 0
If (nCode activeControl))
Goto EndDblClickSub
; check for supported controls
IfInString, activeControl, SysListView32
{
; we got a list view, use an optimized method to find the selection
; find out if anything is selected
ControlGet, selItems, List, Selected, %activeControl%, ahk_id %HWndActiveWin%
If (selItems "")
{
; something is selected, get the result
Loop, Parse, selItems, `n
{
; rows are delimited by `n, columns by A_Tab
; we only want the first column which has the file name
Loop, Parse, A_LoopField, %A_Tab%
{
MsgBox %A_LoopField%
Break ; only interested in first column
}
}
Return ; suppress the click / enter
}
}
; else use generic Ctrl+c copy processing
newClip := ""
oldClip := ClipboardAll ; save old clipboard
Clipboard := "" ; empty it
Send ^c
ClipWait 0.15 ; wait 150 ms
If !ErrorLevel
newClip := Clipboard
If (newClip "")
{
Loop, Parse, newClip, `n, `r ; parse the clipboard contents
{
MsgBox %A_LoopField%
}
}
Clipboard := oldClip ; restore clipboard contents
; done processing click / enter
Return ; break the loop and suppress the input
}
}
EndDblClickSub:
; if no matches, send the click or Enter through
If fromEnter
Send {Enter} ; send the Enter key
Else
{
Click ; click primary mouse button
ClickTime :=0 ; prevent hook from seeing dbl click
Click ; trigger the system dbl click
}
Return
ExitSub:
DllCall("UnhookWindowsHookEx", "uint", hMouseHook) ; unregister the hook
DllCall("SetDoubleClickTime", "uint", DblClick) ; reset default dbl click time
ExitApp
Thanks for posting this wraithdu. What kind of increase in accuracy have you noted with this approach? I'll definitely be looking at how I can utilize this in some of my scripts.
Again, Thanks
"If knowledge can create problems, is it not through ignorance that we can solve them." -Isaac Asimov
Not sure yet. I'm waiting for the source from Oliver when he's done with it. It may or may not be better than the hotkey method that I think Cafe currently uses. The only way to tell will be when someone who is having problems with the hotkey method actually tests this method. I have some other ideas to get away from the Ctrl+C (copy) that Cafe currently uses to get file paths in certain controls, that I hope will be more accurate. But I'll have to wait and see how the implementation goes in Cafe to see if it will be a viable option.
New code posted above. This will be closer to what I hope to implement in eXpresso. Note that in Win7 an Explorer window is NO LONGER a 'SysListView32' control, it is a 'DirectUIHWND' control, so we are back to using the Ctrl+c copy technique right now. On my system 150ms to process Ctrl+s seems pretty good. In eXpresso this time will be configurable. I will look into working with this new control and see if it can be directly accessed (like a SysListView32) from AHK.
Also interesting...
I use XYplorer as my at home file explorer. It is a Delphi (I think) program and does not use standard windows controls (SysListView32, etc). In older versions Ctrl+c worked to copy a file path from the list view window. This no longer works in current versions. If a file is selected Ctrl+c yields blank, and if nothing is selected XYplorer pops an error message!
I don't see any way around this at this point, so eXpresso is not likely to work in conjunction with current versions of XYplorer.