You are here

Developers: Code Snippets

4 posts / 0 new
Last post
wraithdu
Offline
Last seen: 11 years 1 month ago
Developer
Joined: 2007-06-27 20:22
Developers: Code Snippets

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
Chad Ross
Chad Ross's picture
Offline
Last seen: 2 years 10 months ago
Developer
Joined: 2007-06-29 22:40
Very Nice

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 Smile

"If knowledge can create problems, is it not through ignorance that we can solve them." -Isaac Asimov

wraithdu
Offline
Last seen: 11 years 1 month ago
Developer
Joined: 2007-06-27 20:22
Not sure yet. I'm waiting

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.

wraithdu
Offline
Last seen: 11 years 1 month ago
Developer
Joined: 2007-06-27 20:22
New code posted above. This

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.

Log in or register to post comments