AutoHotkey Tip of the Week: Add Dynamic Submenus to Static Menus Using Menu, DeleteAll

How to Add an Updating Dynamic Submenu to a Static AutoHotkey MenuUnderstanding the Difference Between Menu, DeleteAll Command and Menu, Delete Command

When I first wrote the HotstringMenu.ahk script, I planned it as a substitution for ambiguous or multiple option Hotstring text replacements. After typing one of the activation strings, a menu of alternative replacements pops-up. Since the Hotstring menus include many varied item lists, it made sense to create each only when needed. However, when I decided to combine a number of these menus into a group under one main menu, preloading the numerous static submenus seemed more practical. That left me with one problem. Some menus, such as current time and date insertion, need updating each time they pop up.

HotstringTimeDateMenu
The TimeDate submenu updates each time the top-level menu displays.

Once created, AutoHotkey menus sit idle as static tools waiting for the Menu, Show command—at least until deleted. While each subroutine called by a clicked menu item can produce variable results, the contents of the menu itself remain fixed. (Menu items do not accept variables as item names.) That means scripts which use the MenuItemName variable as dynamic output won’t update—unless the script deletes the menu items, then recreates them. If used as a submenu, the DateMenus.ahk script for inserting various current time and/or date formats into documents needs such an active menu.

Library Benefits

An AutoHotkey forum user alerted me to the problem when asking about adding their own dynamic date menu to another Hotstring menu app. I replied with a short answer and added the technique to my own HotstringSubMenuTimeDate.ahk script. If you want to add the same series of time and/or date formats to any menu (static or dynamic) as a submenu and would like it to always update to current times and dates regardless of when it opens, I offer the following approach.

Adding Dynamic Time/Date Submenu to Any Static Menu

Use the following three steps to add this TimeDate submenu to any parent menu:

  1. At the appropriate place in the script, create the TimeDate submenu using a dummy entry and attach it to the parent menu.
  2. Include the subroutines and functions shown below in your script for creating the TimeDate submenu on-the-fly.
  3. Add the appropriate commands and function calls to the main menu’s Menu, …, Show subroutine for updating the TimeDate submenu each time AutoHotkey displays the main menu. These commands first delete the submenu (Menu, TimeDate, DeleteAll), then rebuild the TimeDate submenu using the current datestamp.

Note: By calling Menu, TimeDate, DeleteAll rather than Menu, TimeDate, Delete, AutoHotkey leaves the parent menu item in place allowing the recreating of the TimeDate submenu without the need to reattach it to the main menu. The Menu, TimeDate, Delete command removes both the submenu and its parent menu item.

Adding a Dynamic TimeDate Submenu to the QuickLinks.ahk Script

For demonstration purposes, I’ve added the new submenu to my QuickLinks.ahk script. While this approach attaches a dynamic TimeDate submenu to QuickLinks, you can use the same technique for any other menu. See the QuickLinksTimeDateSubMenu.ahk script.

QuickLinks TimeDate Submenu
Take the three steps discussed to attach a dynamic TimeDate submenu to the QuickLinks.ahk app.

Step One: Setting Up and Linking the Dynamic Submenu

This procedure for adding dynamic menus first requires the creation of the submenu and attaching it to a menu item at the parent level. Initially, it doesn’t matter which menu items we include in the submenu because AutoHotkey will never use them. The first time the script issues the Menu, Show command, AutoHotkey builds the correct submenu replacing the initial dummy menu item(s). We must add at least one menu item to the submenu to facilitate linking to the higher-level menu item:

Menu, TimeDate, Add, Time/Date, QuickLinksHandler  ; Dummy menu item
Menu, QuickLinks, Add, Insert Time/Date, :TimeDate
Menu, QuickLinks, Icon, Insert Time/Date
                , %A_Windir%\system32\SHELL32.dll, 266,

Note: Although you can call any subroutine in the dummy menu item, in order to avoid errors, you must use a Label subroutine that exists in the same script (i.e. QuickLinksHandler). The function of the subroutine doesn’t matter since the script never executes it.

The second Menu, …, Add command establishes the link between the parent menu (QuickLinks) and the submenu (TimeDate).

The third (optional) Menu, …, Icon command adds an icon to the top-level menu item.

*          *          *

CoverImage200
A Multitude of AutoHotkey Tips and Tricks

Three chapters of the e-book Digging Deeper Into AutoHotkey discuss the beginnings of the QuickLinks.ahk script and how it works. Plus, Chapter Thirty of AutoHotkey Applications explains how to add icons to AutoHotkey menus. You can find even more features for the QuickLinks.ahk script demonstrated in Chapter 4.1.4 “Automatically Add Windows Shortcuts to the QuickLinks App”, Chapter 4.1.5 “Spice Up AutoHotkey Menus with Icons”, Chapter 4.1.6 “Finding Windows Icons for AutoHotkey Menus”, Chapter 4.1.7 “Add Secret Windows Tools (God Mode) to QuickLinks Menu”, and Chapter 4.1.8 “Using Unique Icons for Specific Windows Shortcuts” of the book Jack’s Motley Assortment of AutoHotkey Tips. In addition, I plan to implement the new Switch/Case command and other improved techniques in blogs in the coming weeks.

*          *          *

In the QuickLinks.ahk script, I inserted the TimeDate submenu after the main menu generating loops, but prior to the fixed QuickLinks tools menu items.

Step Two: Add to the Script (or #Include) Subroutines and Functions for Building the Submenu

Add the needed functions and subroutine to the script—preferably toward the end of the file to prevent any inadvertent interference. The following two functions (DateFormats(Date) and TextMenuDate(TextOptions,Menu,Action)) format and create the TimeDate submenu which calls the DateAction subroutine:

DateFormats(Date)
{
  FormatTime, OutputVar , %Date%, h:mm tt ;12 hour clock
  List := OutputVar
  FormatTime, OutputVar , %Date%, HH:mm ;24 hour clock
  List := List . "|" . OutputVar
  FormatTime, OutputVar , %Date%, ShortDate ; 11/5/2015
  List := List . "|" . OutputVar
  FormatTime, OutputVar , %Date%, MMM. d, yyyy
  List := List . "|" . OutputVar
  FormatTime, OutputVar , %Date%, MMMM d, yyyy
  List := List . "|" . OutputVar
  FormatTime, OutputVar , %Date%, LongDate
  List := List . "|" . OutputVar
  FormatTime, OutputVar, %Date%, h:mm tt, dddd, MMMM d, yyyy
  List := List . "|" . OutputVar
  FormatTime, OutputVar, %Date%, dddd MMMM d, yyyy hh:mm:ss tt
  List := List . "|" . OutputVar
  Return List
}

This snippet creates a List of time and date formats for parsing by the following TextMenuDate() function:

TextMenuDate(TextOptions,Menu,Action)
{
  StringSplit, MenuItems, TextOptions , |
  Loop %MenuItems0%
  {
    Item := MenuItems%A_Index%
    Menu, %Menu%, add, %Item%, %Action%
  }
}

When selected from the TimeDate submenu, DateAction inserts the date/time into the active document:

DateAction:
  SendInput %A_ThisMenuItem%{Raw}%A_EndChar%
Return

As an alternative, you can save these two functions and the subroutine in a separate file and use the #Include directive to embedded the code on loading.

Step Three: Add Calls for Menu Updating Commands and Functions to Script’s Menu, …, Show Subroutine

In the final step, add the code which updates the TimeDate submenu to the subroutine or Hotkey code which displays the menu (Menu, QuickLinks, Show):

XButton1::
#z::
!,::
  Menu, TimeDate, DeleteAll
  List := DateFormats(A_Now)
  TextMenuDate(List,"TimeDate","DateAction")
  Menu, QuickLinks, Show
Return

Remember, when using the DeleteAll subcommand rather than Delete, AutoHotkey leaves the parent menu item in place while deleting all of the submenu items. This makes it easy to replace the submenu without affecting anything else in the menu system.

Note: Menu, TimeDate, Delete also deletes the submenu items, but it removes the parent entry as well.

For another example of adding this dynamic TimeDate submenu to a parent menu see the HotstringSubMenuTimeDate.ahk script.

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.)

Leave a 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