AutoHotkey - send hotkeys to nested folders

Viewed 106

Using Autohotkey, I can send "ctrl+" to Windows File Explorer, to auto adjust column width. Manually, it's ctrl+ (the + in the numpad).

This code below works, but only for first level folders, not if I open a folder within a folder. Is there a way to send "ctrl+" again for each subfolders I might open?

Gui, +LastFound
DllCall("RegisterShellHookWindow", UInt, WinExist())
MsgNum := DllCall("RegisterWindowMessage", Str, "SHELLHOOK")
OnMessage(MsgNum, "ShellMessage")
Return

ShellMessage(wParam, lParam) {
 wTitle = ahk_id %lParam%
 WinGet, pname, ProcessName, %wTitle%
 If (wParam != 1 || pname != "Explorer.exe")
  Return
 WinActivate, %wTitle%
 Send ^{NumpadAdd}   ;ctrl+ (numpad)
}
1 Answers

Seems like a pretty questionable approach.
I would rather see about somehow setting this to be the default behavior, or automating this with COM instead of sending a hotkey.
Anyway, for the hotkey approach, this seems to do the trick:

;No need to create a gui, A_ScriptHwnd is used for this
DllCall("RegisterShellHookWindow", UInt, A_ScriptHwnd)
MsgNum := DllCall("RegisterWindowMessage", Str, "SHELLHOOK")
OnMessage(MsgNum, "ShellMessage")
Return

ShellMessage(wParam, lParam) 
{
    static _time := 0
    if (wParam = 6 && A_TickCount - _time > 100 && WinActive("A") = lParam)
    {
        _time := A_TickCount
        WinGet, pname, ProcessName, % "ahk_id " lParam
        if (pname = "explorer.exe")
        {
            ControlFocus, DirectUIHWND2, % "ahk_id " lParam
            SendInput, ^{NumpadAdd}
        }
    }
}

So, first ditched the legacy way of getting a hwnd for the current script, and used A_ScriptHwnd (docs).
Also, ditched legacy syntax overall.

Then switched over to the HSHELL_REDRAW (docs) event to check for window title changes.
And the timing stuff is to filter out duplicate shell messages. When the title changes, we actually receive like 10+ of those messages at once. Only need to run the hotkey once.
So a simple 100ms cooldown does the trick.
A_TickCount (docs) is used for this.

Also made the checking order smarter.
No need to get the process name if we didn't even receive the correct shell message.

And finally before sending the hotkey, activate the correct control so the hotkey will work. This part is likely going to be wrong for you if you're on some older or future Windows version.
Also switched over to SendInput (docs) due to it being the recommended faster and more reliable send mode.

Related