Adding Folders and Files from Windows to AutoHotkey Menus

After a Little Pondering, I Found Adding Windows File Explorer Structures to an Action Menu Simple

I was wrong when I contemplated using the BoundFunc Object to insert folder and file names into an AutoHotkey action menu. At the time, I thought that the AutoHotkey Menu command did not offer enough flexibility to handle the task on its own. Those concerns included:

  1. The limited number of built-in menu variables severely constrained the information available when clicking a menu item.
  2. Duplicate folder names found in any other folder or subfolder would cause a conflict.

Both of these problems have solutions, but I was afraid that I would need to resort to some complicated gymnastics.

Sometimes, we know too much for our own good. With a toolbox full of tricks, we often devise methods which—although they work—make the coding more complex. Then, rather than rethinking the problem, we dig a deeper hole. That’s how I started out with the rewrite of the barebones QuickLinks script. Rather than stripping the question down to the basics, I started looking for solutions to problems that don’t actually exist.

AHK_user dealt with the menu name problem in “QuickLinks (Menu by folder)” by deriving menu names from the full directory path. This ensured no duplicates for any of the submenus. I surmised that I would need to do something similar.

The script loads folders and subfolders into menus and submenus.

Then, it occurred to me, “Why not just use the folder full path as the menu name?” If it worked, I would not need any Regular Expression manipulation of the folder path and name, plus, I would avoid menu name duplication. I realized that I could also drop the BoundFunc Object for passing data. It all seemed too easy.

Note: If I were an AutoHotkey newbie, then I may have started out with the following straightforward approach. But I’ve been writing code for so long that I have added some pretty powerful tricks in my toolbox and often find beginning with those tricks tempting. Sometimes, that’s appropriate. Other times, it just gets in the way.

I thought that using the full directory path and name as a menu name would likely generate an error. Who knew that colons and backslashes wouldn’t cause a problem?

I dumped my previous, more complex stabs at the code and came up with the following routine:

TopMenu := "C:\Users\" . A_UserName . "\QuickLinks"
LastMenu := TopMenu

; Loop through folders/files recursing subfolders.
Loop Files, %TopMenu%\*.*, DFR  
{
	; Skip any file that is H, R, or S (System).
	If InStr(A_LoopFileAttrib, "H") 
       or InStr(A_LoopFileAttrib, "R") 
       or InStr(A_LoopFileAttrib, "S") 
		  Continue

	; Add to Menu	
	Menu, %A_LoopFileDir%, Add, %A_LoopFileName%, Action

	; Attach submenu	
	If (A_LoopFileDir != LastMenu) 
       and (LastMenu != TopMenu)
		   AddMenu(LastMenu)

	; Save menu name
	LastMenu := A_LoopFileDir
}

AddMenu(LastMenu)

Menu, %TopMenu%, Show

Return

Action:
   Run, % A_ThisMenu . "\" . A_ThisMenuItem
Return

AddMenu(MenuName) ; Attach submenu to next level
{
	SplitPath, MenuName , DirName, OutDir
	Menu, %OutDir%, Add, %DirName%, :%MenuName%
}

(This snippet only contains 22 lines of operational code including the curly brackets.)

While I hardcoded the QuickLinks folder for this example, you can substitute the path and name of any folder from Windows File Explorer.

The script loops through all of the folders and subfolders placing each file/folder in a menu with a name (A_ThisMenu) coinciding with the path and name of the folder. The menu item name (A_ThisMenuItem) uses the file/folder name. After building each submenu, AutoHotkey attaches it to its parent menu item. Suddenly, I have embedded in the menu everything needed for opening any file (with its default program) or a Windows shortcut link using the AutoHotkey Run command.

You can modify this example to accept folder name input (the FileSelectFile command) or use the Standard Clipboard Routine to capture any folder selected in Windows File Explorer.

How the Script Works

The Loop Files command, when set in the recursive (R) mode while including all files (F) and folders (D), increments through the entire structure in alphabetical order—working from the selected top-level down. This means that the loop sequentially lists all files/folders in each directory prior to digging into the individual subdirectories. This makes submenu creation easy since all files/folders appear in a continuous list suitable for attaching to the previously built higher-level menu.

We don’t need to know when AutoHotkey reads the contents of each subfolder—only where to attach that submenu on completion. Using the folder path and name as the menu name gives us a unique key for each menu while providing the location of the included files/folders.

The script only attaches to the higher level menu after building the complete submenu. (This approach increases the speed of execution over code reconnecting the submenu after each new menu item addition.) AutoHotkey uses the change in the folder path and name to recognize the appropriate linking point. The variable LastMenu always contains the menu name of the most recently added menu item. If the new menu name A_LoopFileDir does not match LastMenu, then the script adds the old submenu to its parent using the following AddMenu(LastMenu) function:

AddMenu(MenuName) ; Attach submenu to next level
{
   SplitPath, MenuName , DirName, OutDir
   Menu, %OutDir%, Add, %DirName%, :%MenuName%
}

Note: Since the last item at the end of the loop does not see a menu name change to trigger the menu attachment, one additional AddMenu() function call runs outside the loop.

Each menu item not pointing to a subfolder calls the Action subroutine:

Action:
Run, % A_ThisMenu . "\" . A_ThisMenuItem
Return

Whenever clicking a menu item, AutoHotkey automatically opens the file using the default program or runs the file or URL found in the shortcut file (lnk). If a folder contains no files/folders, a click opens that empty folder in Windows File Explorer.

You can add a Hotkey to call up the menu or, if implementing selectable folders, run the menu-building routine. If you load folders with hundreds of files, you likely will run into problems with long menus running off the screen. If someone wanted to rebuild the QuickLinks.ahk script, this would act as a good starting point.

Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)

jack

This post was proofread by Grammarly
(Any other mistakes are all mine.)

(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)

Find my AutoHotkey books at ComputorEdge E-Books!

Find quick-start AutoHotkey classes at “Robotic Desktop Automation with AutoHotkey“!

One thought on “Adding Folders and Files from Windows to AutoHotkey Menus

  1. […] Last time, I mentioned the possibility of using the FileSelectFile command to pick the top-level folder when adding files to an AutoHotkey action menu using the barebones FileMenuLoad.ahk script. Upon further consideration, I realized that the FileSelectFolder command offered a more appropriate solution. Accidentally picking a file rather than a folder for the top-level—although workable—only introduces more complications. The FileSelectFolder command precludes the inadvertent selection of a file. […]

    Like

Leave a Reply to Using FileSelectFolder for Windows File Explorer AutoHotkey Menus | Jack's AutoHotkey Blog Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s