Using the Right Images Make Your AutoHotkey Menus Both Prettier and More Useful
It’s easy enough to put together a plain vanilla AutoHotkey pop-up menu without any icons. The sample QuickLinks script creates a menu from favorites Windows shortcuts in the QuickLinks folder. However, a stripped down menu looks pretty boring and makes individual items harder to find.

Adding icons to your menus makes it easy to pick out particular options and tells you something about what it does. The AutoHotkey Menu command allows the insertion of icons into a menu, but not automatically.

In Chapter Twenty-one of the book Digging Deeper Into AutoHotkey, I discuss using the QuickLinks.ahk script for easy access to your favorite apps, folders, and Web pages. In Chapter Thirty of AutoHotkey Applications, I explain a basic method for adding icons to the same QuickLinks menus, but in this blog, I offer a couple of other AutoHotkey commands to improve and automate the process.
Where to Find Icons
The online AutoHotkey documentation offers instruction for inserting icons into AutoHotkey menus (both pop-up and System tray) using the Menu command. That’s the easy part. Locating and calling the most useful icons for your menu proves a little more complicated.
When inserting icons into AutoHotkey menu, the “following types of files are supported: ICO, CUR, ANI, EXE, DLL, CPL, SCR, and other types that contain icon resources.” While you can create your own icon files (ICO), you may find more than enough images freely available on your computer. In fact, most EXE program files and certain DLL files contain a plethora of icons immediately accessible.

You can create and save your own individual ICO files (icon file with the .ico extension) using your favorite paint programs and image software such as the free IrfanView, but individual image files require the presence of each at the time of menu creation. Both EXE and DLL files contain ready-made icons (often with multiple versions) ready for immediate use without any extra work. Plus, wouldn’t it be better to automatically load the usual program icons without searching for each?
In the QuickLinks.ahk script, our menu items target Windows shortcuts with the file extension .lnk (link files) or .url (Internet link file). For the most part, Windows shortcuts do not embed icons but draw them from other files. That means we must dig inside the shortcut to find the alternate location for an appropriate menu image. To do that we use two AutoHotkey commands which reveal the inner workings of Windows shortcuts: the FileGetShortcut and FileGetAttrib commands.
Two Types of Windows Shortcuts
In the second level of the QuickLink.ahk script, AutoHotkey creates the submenus by accessing the Windows shortcuts found in the top-level folders. To slightly confuse matters, you may find that each folder contains different types of shortcuts. Windows uses two shortcut types: one for linking to programs, folders, or Web sites and one for Web sites only.
The primary shortcut file uses the link extension (.lnk) and points directly to the target file or location. If linked to a program, a double-click of the shortcut launches that software. If linked to a folder (directory), the shortcut opens that folder in Windows Explorer—(called File Explorer in Windows 10). If the target path contains the URL of a Web page, then it opens that page using the default browser. All three of these options work with any shortcut (.lnk) file. However, Windows added a complication.
If you manually create a Windows shortcut (right-click New⇒Shortcut) entering a Web location (URL) as the target, Windows changes the extension to .url (Internet shortcut) rather than using the standard .lnk. The shortcut continues to operate properly, however, AutoHotkey must handle an Internet shortcut differently, plus the AutoHotkey FileGetShortcut command does not work on .url files. That means we need to be on the lookout for .url shortcuts. You can easily deal with this perturbation within the Loop by setting a trap for .url shortcuts immediately after the creation of the menu item (Menu, %MainMenu%, Add, %NewName%, MenuHandler):
If (A_LoopFileExt = "url") { Menu, %MainMenu%, Icon, %NewName%, %A_Windir%\system32\SHELL32.dll, 14, }
With this line of code placed within the secondary QuickLinks.ahk loop, AutoHotkey checks for the .url extension. If found, the Menu command inserts an icon which may represent the Web. I found this global icon, , as the 14th image in the system file SHELL32.dll (pictured above).
Note: Refer to the previous blog titled “Automatically Add Windows Shortcuts to the QuickLinks App (AutoHotkey Tip)” for an understanding of the two loops (primary and secondary) in the QuickLinks.ahk script.
Whenever AutoHotkey encounters an Internet shortcut, the above code automatically assigns the fourteenth icon in the SHELL32.dll file to that menu item. Fortunately, I can use this one icon for every Web page link. If I want to use a variety of icons for different Web pages, then I deal with that later in the process.
While this code works for all .url Internet shortcuts, it does not identify the .lnk files which might target URLs. A special condition discussed later in this blog resolves this situation.
Inserting Program Icons into AutoHotkey Menus
Ideally, when one of the Windows shortcuts targets a program or app, we want AutoHotkey to automatically insert the associated icon into the menu. To do this, we extract the target path and filename from the shortcut. For that, we use the FileGetShortcut command:
FileGetShortcut, C:\Users\%A_UserName%\QuickLinks\%MainMenu%\%NewName%.lnk , OutTarget, OutDir, OutArgs, OutDescription , OutIcon, OutIconNum, OutRunState
When used on any .lnk shortcut, the variable OutTarget usually contains the path and name of the target program. This same command program (normally with the extension .exe) contains the icons available for the QuickLinks menu. To add the first icon embedded in the program file to your menu simply call it from the target program file:
IfInString, OutTarget, exe, Menu, %MainMenu%, Icon, %NewName%, %OutTarget%
By identifying any command files (.exe) with the IfInString command, we can automatically add the default program icon to the menu. This one line solves the problem of adding icons to all the Windows shortcuts which launch EXE programs. However, it leaves untouched any shortcuts which open folders, contain Web targets within a .lnk file, or uses an extension other than .exe for launching scripts—such as an AutoHotkey script (.ahk).
Alternative Icons for Other Scripts and Apps
I wanted to distinguish between AutoHotkey scripts (.ahk) and compiled apps (.exe). For that, I decided to use the second icon found in the AutoHotkeyU64.exe file. I added the following line of code:
IfInString, OutTarget, ahk, Menu, %MainMenu%, Icon, %NewName% , C:\Program Files\AutoHotkey\AutoHotkeyU64.exe, 2
When finding “ahk” in OutTarget, this line of code pulls in the second icon (2) found in the main AutoHotkey program file (C:\Program Files\AutoHotkey\AutoHotkeyU64.exe).
You can use this same technique to distinguish any special shortcuts in your AutoHotkey menus.
Web Page Targets in Standard Windows Shortcuts (.lnk)
Although we fixed the Internet shortcut (.url) with previous code, that does nothing for Web links targeted in standard shortcuts (.lnk). (Note: If you use the FileCreateShortcut command, (discussed in a previous blog) to create a Web shortcut, the extension remains .lnk rather than converting to .url—as would occur with the manual creation of Windows shortcuts targeting URLs.) We use the substring “http” to identify those Web pages targeted in standard Windows shortcuts:
IfInString, OutDir, http, Menu, %MainMenu%, Icon, %NewName%
, %A_Windir%\system32\SHELL32.dll, 14,
This adds that same global icon to any remaining Web page shortcuts.
Note: Since the OutTarget variable returns blank for Web links, use the OutDir variable to identify Web pages.
Identifying Shortcuts for Opening Windows Folders (Directories)
When a Windows shortcut opens a folder (directory), the Properties window for the shortcut identifies the Target type as File folder. However, the FileGetShortcut command does not easily identify that type of shortcut. We could go through some data manipulation to determine whether the shortcut targets a folder, but using the FileGetAttrib command makes it easy:
FileGetAttrib, FileAttrib , %OutTarget%
The folder attribute (D) appears in the FileAttrib variable string for all folders (directories). Therefore, we can add the folder icon (4) to the menu item from the system file imageres.dll:
IfInString, FileAttrib, D, Menu, %MainMenu%, Icon, %NewName% , %A_Windir%\system32\imageres.dll, 4,
Adding Special Icons
When I originally discussed adding icons to the QuickLinks.ahk script, I used a single function, AddIcon(), which includes a list of Menu commands for inserting icons into menus. I found continuing to use the function within the primary loop especially important since each main menu item represents a folder containing various other targeted shortcuts.
I could have used the same folder icon (as discussed above) for each of the main menu items, but, when viewed at the top level, the redundant folder image seemed boring. Since the top-level menu items use folders, the shortcut dependent techniques I’ve illustrated for the second level won’t work. However, using a function dependent upon the main menu names makes viable a set of statements which fill in the possibilities. Plus, whenever you notice that a missing icon, adding statements to that same function works when used in the second level loop. Add the function to the script twice, once after the creation of a new menu item inside the primary loop, and again inside the secondary—usually after all other Menu, …, Icon commands:
AddIcon(MainMenu,NewName)
This cleanup function deals with the exceptions while adding unique icons to the top level menu:
AddIcon(menuitem,submenu) { IfInString, submenu, Tools Menu, %menuitem%, Icon, %submenu%, %A_Windir%\system32\SHELL32.dll, 36, IfInString, submenu, web Menu, %menuitem%, Icon, %submenu%, %A_Windir%\system32\SHELL32.dll, 14, IfInString, submenu, Text Menu, %menuitem%, Icon, %submenu%, %A_Windir%\system32\SHELL32.dll, 2, IfInString, submenu, Photos Menu, %menuitem%, Icon, %submenu%, %A_Windir%\system32\SHELL32.dll, 140, IfInString, submenu, E-Book Menu, %menuitem%, Icon, %submenu%, Books.ico IfInString, submenu, EPUB Menu, %menuitem%, Icon, %submenu%, Books.ico IfInString, submenu, Dropbox Menu, %menuitem%, Icon, %submenu% , C:\Users\%A_UserName%\AppData\Roaming\Dropbox\bin\Dropbox.exe IfInString, submenu, Graphics Menu, %menuitem%, Icon, %submenu%, %A_Windir%\system32\SHELL32.dll, 142, IfInString, submenu, Fav Menu, %menuitem%, Icon, %submenu%, %A_Windir%\system32\SHELL32.dll, 44, IfInString, submenu, Amazon Menu, %menuitem%, Icon, %submenu%, Amazon.ico IfInString, submenu, Cheeseburger Menu, %menuitem%, Icon, %submenu%, CheeseBurger.ico }
Placing the function last in the loop allows you to overwrite specific generic icons (Web page, folders, etc.) when another image does a better job of discerning the menu option. Notice that some of the icons use graphics files (.ico) while others draw from other files (e.g. SHELL32.dll).
Tip: If you would like to use the embedded icon from a particular Web site, you can generally find it at http://www.website.com/favicon.ico. (e.g. amazon.com/favicon.ico). Just add /favicon.ico to the end of the domain. Some sites may use a different technique which changes the name of the .ico file. I’ve found that opening the source code page for the Web site and searching for “ico” has helped me find the specific graphics. Save the image to your working directory and use it in your QuickLinks menu.
[…] Spice Up AutoHotkey Menus with Icons (AutoHotkey Tip) […]
LikeLike
Many thanks for an excellent article. It took me a while to add all the tweaks so icons were displayed correctly but I got there in the end.
I found, as the result of much trial and error [mostly error 🙂 ], that the ‘IfInString’ order was very important. Mine ended up using the following so AHK scripts and compiled exes displayed correctly:
IfInString, OutTarget, ahk, Menu, %MainMenu%, Icon, %NewName%
, C:\Program Files\AutoHotkey\AutoHotkeyU64.exe, 2
IfInString, OutTarget, exe, Menu, %MainMenu%, Icon, %NewName%, %OutTarget%
IfInString, OutTarget, pdf, Menu, %MainMenu%, Icon, %NewName%
, C:\Program Files (x86)\Foxit Software\Foxit Reader\FoxitReader.exe, 2
PS – Has the link for the HelpHandler changed? As is, the following line just displays a ‘loading’ graphic, not a web page:
Run, http://webserver.computoredge.com/online.mvc?issue=3103&article=vista&src=qcklnks
Eventually it times out with “The server at webserver.computoredge.com is taking too long to respond.”.
LikeLike
Your right Rick. The order of the IfInString statements does matter. Whichever one appears last in the script takes precedence.
As for the QuickLinks Help action, the correct subroutine should be:
HelpHandler:
Run, http://www.computoredge.com/AutoHotkey/AutoHotkey_Quicklinks_Menu_App.html
Return
LikeLike