|
#Requires AutoHotkey v2.0.3+ |
|
|
|
; # Goto openened folders |
|
|
|
; A better "Recent Places" |
|
|
|
#HotIf ShouldDisplayMenu() |
|
~MButton::DisplayMenu() |
|
; Ctrl + G like Listary |
|
^g::DisplayMenu() |
|
#HotIf |
|
|
|
; "Namespaced" global variables |
|
global GTOF := { |
|
WinId : 0, ; Window ID under the mouse |
|
Class : "", ; Class under the mouse |
|
Menu : Menu() |
|
} |
|
|
|
ShouldDisplayMenu() { |
|
MouseGetPos( , , &WinIdUnderMouse) |
|
GTOF.WinId := WinIdUnderMouse |
|
GTOF.Class := WinGetClass("ahk_id " . WinIdUnderMouse) |
|
return GTOF.Class ~= "#32770|ExploreWClass|CabinetWClass|ConsoleWindowClass" |
|
} |
|
|
|
DestroyMenu() { |
|
DllCall("KillTimer", "Ptr", A_ScriptHwnd, "Ptr", id := 1) |
|
if not WinExist("ahk_id " GTOF.WinId) { |
|
GTOF.Menu.Delete() |
|
} |
|
} |
|
|
|
DisplayMenu() { |
|
; Fresh menu, width adapts to path length every time |
|
GTOF.Menu := Menu() |
|
FolderMenu := GTOF.Menu |
|
; Get current paths and build menu with them |
|
for window in ComObject("Shell.Application").Windows { |
|
; Exclude special locations |
|
; Computer, Recycle Bin, Search Results, Internet Explorer pages |
|
if InStr(window.FullName, "explorer.exe") && InStr(window.LocationURL, "file://") { |
|
MenuItemName := window.Document.Folder.Self.Path |
|
; Get paths of currently opened Explorer windows |
|
FolderMenu.Add(MenuItemName, NavigateToFolder.Bind(MenuItemName)) |
|
; Same default folder icon for all |
|
; Too difficult getting the actual icons, on the off chance they're not default |
|
FolderMenu.SetIcon(MenuItemName, A_WinDir "\system32\imageres.dll", 4) ; imageres.dll,4 = Folder icon |
|
} |
|
} |
|
; If no windows are open |
|
OpenedWindowsCount := DllCall("GetMenuItemCount", "ptr", FolderMenu.Handle) |
|
if not OpenedWindowsCount { |
|
FolderMenu.Add("No folders open...", (*) => {}) |
|
FolderMenu.Disable("No folders open...") |
|
} |
|
; Add User profile / $HOME directory entry |
|
FolderMenu.Add("Home", NavigateToFolder.Bind("%USERPROFILE%")) |
|
FolderMenu.SetIcon("Home", A_WinDir "\system32\imageres.dll", 118) ; imageress.dll,118 = User folder icon |
|
|
|
; Add Desktop entry at the end of the menu |
|
FolderMenu.Add("Desktop", NavigateToFolder.Bind(A_Desktop)) |
|
FolderMenu.SetIcon("Desktop", A_WinDir "\system32\imageres.dll", 106) ; imageress.dll,106 = Desktop icon |
|
|
|
; From a separate thread destroy the menu if the target Open with dialog is gone |
|
; See thread "Script execution is stopped when menu is open" |
|
; https://www.autohotkey.com/boards/viewtopic.php?style=17&p=478539 |
|
DllCall("SetTimer", "Ptr", A_ScriptHwnd, "Ptr", id := 1, "UInt", 1000, "Ptr", CallbackCreate(DestroyMenu, "Fast")) |
|
; Present the menu |
|
FolderMenu.Show() |
|
; Destroy the menu so it doesn't remember previously opened windows |
|
FolderMenu.Delete() |
|
} |
|
|
|
NavigateToFolder(ItemName, *) { |
|
; Fetch the array element that corresponds to the selected menu item: |
|
path := ItemName |
|
if path = "" |
|
return |
|
; Activate the window so that if the user is middle-clicking |
|
; outside the dialog, subsequent clicks will also work: |
|
WinActivate "ahk_id " GTOF.WinId |
|
; It's a dialog. |
|
if GTOF.Class = "#32770" { |
|
; Lexikos solution https://stackoverflow.com/a/25718181/5266640 |
|
; {F4} is slower because it drops down the menu of past paths |
|
SendInput "!{d}{Raw}" path "`n" |
|
return |
|
} |
|
; In Explorer, switch folders. |
|
else if GTOF.Class ~= "(Cabinet|Explore)WClass" { |
|
ControlClick "ToolbarWindow323", GTOF.WinId,,,, "NA x1 y1" |
|
ControlFocus "Edit1", GTOF.WinId |
|
ControlSetText path, "Edit1", GTOF.WinId |
|
; Tekl reported the following: "If I want to change to Folder L:\folder |
|
; then the addressbar shows http://www.L:\folder.com. To solve this, |
|
; I added a {right} before {Enter}": |
|
ControlSend "{Right}{Enter}", "Edit1", GTOF.WinId |
|
return |
|
} |
|
; In a console window, navigate to that directory |
|
else if GTOF.Class = "ConsoleWindowClass" { |
|
WinActivate GTOF.WinId ; Because sometimes the mclick deactivates it. |
|
SetKeyDelay 0 ; This will be in effect only for the duration of this thread. |
|
Send "pushd " path "{Enter}" |
|
return |
|
} |
|
; Since the above didn't return, one of the following is true: |
|
; 1) It's an unsupported window type but g_AlwaysShowMenu is true. |
|
Run "explorer " path ; Might work on more systems without double quotes. |
|
} |
If you only have one folder open and you middle click > release middle click > left-click only folder > release left-click - it will save to the currently opened folder instead of switching to the selected folder... I just saved the web-page and wanted to save to downloads and thought it worked when it automatically closed the SaveAs window after selecting the downloads folder... But, then I opened folder location and it was the previous folder in SaveAs... When 2 folders are open, clicking on 1 actually switches the folder.