New Parameters for the HotstringMenu() Function Adds Flexibility and Power to Pop-up Menus
In my last blog, I started looking at adding the variadic parameter (accepts multiple inputs) and a Menu subroutine parameter to the HotstringMenu() function. While in the process of creating alternative Label subroutines, I found that changing a subroutine often called for a new menu-creating function. Rather than resorting to multiple functions, I decided to add one more parameter for tailoring the master function.

Note: This blog discusses the use of AutoHotkey object-based arrays (simple and associative) with the function’s variadic parameter. A review of my books demonstrated that most included discussions of arrays (pseudo-arrays and object-based arrays). In particular, Chapter 12.1.5 “Using Associative Arrays to Solve the Instant Hotkey Data Recall Problem” in the book Jack’s Motley Assortment of AutoHotkey Tips explains the difference between the various array types while offering a practical example of an associative array.
A Three-Parameter Function
To add more flexibility to the HotstringMenu() function discussed last time, I inserted an additional parameter (MenuType) to the function tailoring the menu before executing the SendInput subroutine:
HotstringMenuV(MenuType,Handle,MenuArray*)
This allows the changing of menu items based upon the MenuType parameter.
Note: While adding more parameters to the function does make it more flexible, it does not necessarily make it simpler. For that reason, I continue to include the original HotstringMenu() function in the master script and changed the name of the variadic form of the function to HotstringMenuV(). Some people may find the original function easier to use (as described in the blogs “AutoHotkey Hotstring Menus for Text Replacement Options” and “Hotstring Menu Techniques for Inserting Symbols and Emojis“).
When added to the new HotstringMenuV() function, the following conditions create alternative tailored menus.
Add Numeric Single-Key Shortcuts
When added to the For Each, Item in MenuArray loop, the following menu command creates a numeric single-key shortcut. Using “N” as the MenuType code, the script inserts the following menu item:
If (MenuType = "N") Menu, MyMenu, Add, % "&" Each " " Item, % Handle
The script uses the Menu command to add the next array item to the Hotstring menu. The numeric default value of the simple array key Each (or A_Index) creates the menu shortcut keys (&1, &2, &3, …) while appending the replacement text (Item) to the menu item.
Called with the following Hotstring:
:x:bn::HotstringMenuV("N","MenuShortcut","Ox" ,"Water Buffalo","Cow")
Note: Many of the code snippets in this blog use line continuation techniques to wrap lines of code for display purposes. In most cases, the wrapped lines start with a comma. AutoHotkey reads those broken lines of code as part of the previous command or function.
The new MenuShortcut subroutine automatically removes the added menu single-key shortcut characters before text replacement:
MenuShortcut: TextOut := SubStr(A_ThisMenuItem, 4) SendInput {raw}%TextOut%%A_EndChar% Return
The SubStr(A_ThisMenuItem, 4) function eliminates the first three characters of the output text which include the single-key shortcut and one space.
Add Alphabetical Single-Key Shortcuts
When added to the For Each, Item in MenuArray loop, the following menu command creates an alphabetic single-key shortcut. Using “A” as the MenuType code, the script inserts the following menu item:
If (MenuType = "A") Menu, MyMenu, Add, % "&" Chr(Each+96) " " Item, % Handle
Adding 97 to the numeric default value of Each and converting to the ASCII character value (Chr(Each+96)) creates an alphabetic menu shortcut key (&a, &b, &c, …) and appends the replacement text (Item) to the menu item.
Called with the following Hotstring:
:x:ba::HotstringMenuV("A","MenuShortcut","Ox" ,"Water Buffalo","Cow")
This alphabetical conditional uses the same MenuShortcut subroutine as the previous numeric shortcut key conditional.
Adding Simple Array Menu Items
The following two simple array function calls operate identically. The simple array definition format:
:x*?:c``::HotstringMenuV("" ,"HotstringMenuAction",["⇐ | Left arrow &1" ,"⇔ | Double arrow &2","⇒ | Right arrow &3" ,"⇑ | Up arrow &4","⇓ |Down arrow &5"]*)
Adding the asterisk to the end of the variadic parameter call forces evaluation as an array. However, the variadic format shown next in the next example works just as well without the square brackets and asterisk ([…]*):
:x*?:c``::HotstringMenuV("" ,"HotstringMenuAction","⇐ | Left arrow &1" ,"⇔ | Double arrow &2","⇒ | Right arrow &3" ,"⇑ | Up arrow &4","⇓ |Down arrow &5")
While the variadic function parameter can force a simple array definition with square brackets and the asterisk ([…]*) (as shown in the previous example), you’ll find no advantage in doing so—the variadic parameter assumes a simple array for any comma-delimited list (“text1″,var1,”text2”,var2) without using the array definition format ([“text1″,var1,”text2”,var2]*).
However, calling an established simple array by name can save space when calling the function. First, define the array (normally in the AutoExecute portion of the script):
Arrows := ["⇐ | Left arrow &1","⇔ | Double arrow &2" ,"⇒ | Right arrow &3","⇑ | Up arrow &4" ,"⇓ |Down arrow &5"]
Second, add the array name to the variadic parameter appending the asterisk (*):
:x*?:c``::HotstringMenuV("","HotstringMenuAction",Arrows*)
This produces an easier-to-read calling function and makes array editing simpler—especially if you use the array in more than one place in a script.
Using a blank MenuType code defaults to using the original Menu command:
Menu, MyMenu, add, % Item , % Handle
This Menu command, when used in conjunction with the original HotstringMenuAction subroutine, performs in the same manner as the old HotstringMenu() function discussed last time.
The original subroutine using the same criteria as the previous function follows:
HotstringMenuAction: InsertText := StrSplit(A_ThisMenuItem, "|") TextOut := StrReplace(RTrim(InsertText[1]), "&") SendInput {raw}%TextOut%%A_EndChar% Return
Adding Associative Array Menu Items
While the above variadic function calls create a simple array from the list of values or the array name included in the parameter, you can pass an associative array (key and value) directly by name or create such an array inside the calling function.
If (MenuType = "T") ; Associative array Menu, MyMenu, Add, % Each " | " Item, % Handle
I assigned the code “T” to associative arrays which use both an assigned key and value in the menu item.
To define the associative array inside the calling function, use the asterisk (*) after the array list ({…}*):
:x*?:a``::HotstringMenuV("T" ,"HotstringMenuAction",{⇐: "Left arrow &1" ,⇔: "Double arrow &5",⇒: "Right arrow &3" ,⇑: "Up arrow &2",⇓: "Down arrow &4"}*)
To call an associative array by name:
1) Define the array:
ArrowsA := {⇐: "Left arrow &1" ,⇔: "Double arrow &5",⇒: "Right arrow &3" ,⇑: "Up arrow &2",⇓: "Down arrow &4"}
2) Use the array name as the variadic parameter followed by the asterisk (*):
:x*?:c``::HotstringMenuV("T","HotstringMenuAction",ArrowsA*)
New HotstringMenuV() Function
The HotstringMenuV() function:
HotstringMenuV(MenuType,Handle,MenuArray*) { For Each, Item in MenuArray If (MenuType = "A") Menu, MyMenu, Add, % "&" Chr(Each+64) " " Item, % Handle Else If (MenuType = "N") Menu, MyMenu, Add, % "&" Each " " Item, % Handle Else If (MenuType = "T") Menu, MyMenu, Add, % Each " | " Item, % Handle Else Menu, MyMenu, add, % Item , % Handle Menu, MyMenu, Show Menu, MyMenu, DeleteAll }
If you want to add another Menu command, create a new MenuType code and plug it in as an additional Else If statement.
Label Subroutines
Control the menu output by writing additional subroutines and calling them through the function.
Original menu output subroutine:
HotstringMenuAction: InsertText := StrSplit(A_ThisMenuItem, "|") TextOut := StrReplace(RTrim(InsertText[1]), "&") SendInput {raw}%TextOut%%A_EndChar% Return
Single-key shortcut output subroutine:
MenuShortcut: TextOut := SubStr(A_ThisMenuItem, 4) SendInput {raw}%TextOut%%A_EndChar% Return
Add the HotstringMenuV() function plus the needed Label subroutines to your master Hotstring file to create flexible Hotstring menus for your AutoHotkey scripts.
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.)
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.)
This one is tough. He must be tired after writing all these because this one has some problem sentences. He also uses a term in italics “mlk.” I don’t know what it means, but in one case he has it in a phrase: “Amalickiah has a mlk-name…” Is mlk a Hebrew word and is pronounced, or is it an acronym and pronounced m-l-k (in which case the article would be “an”)?
LikeLike
I certainly may have some problem sentences, (I usually do), but I was unable to find “Amalickiah has a mlk-name…” in the text. Sounds like your browser has a delivery problem. Try rebooting and look again. Let me know.
LikeLike