AutoHotkey’s GroupAdd Command and Ahk_Group Create Multiple Context-Sensitive Hotkeys While Streamlining Code—Plus a Quick GroupAdd Script for Easy Window Handling!
Unlike AutoHotkey Hotstrings, there are numerous ways to manipulate Hotkeys—both while the script is loading (as in #Directives, discussed last time) or with various commands after the script is up and running. The most flexible of the interactive instructions is the Hotkey command which allows changes on the fly. The Hotkey command deserves much more attention (and will get it starting next time), but for now there are a couple more tricks demonstrating ways to make better use of the #IfWinActive directive in our example for blocking dangerous Windows shortcuts.
* * *
New to AutoHotkey? See “Introduction to AutoHotkey: A Review and Guide for Beginners.”
* * *
Note: It may seem that I’m spending an inordinate amount of time discussing techniques for blocking other Windows shortcuts. My purpose here is not to advocate for any particular application, but demonstrate the flexibility available in the AutoHotkey built-in Hotkey system. This easy Hotkey system (along with Hotstrings) is what distinguishes AutoHotkey from AutoIt. For many people, these simple Hotkey and Hotstring capabilities may be all they’ll ever need—without getting involved with much more complex coding. I use shortcut blocking merely as a method for understanding and comparing the various ways to work with Hotkeys. Any other AutoHotkey action or app could easily replace the blocking non-action shown in these examples.
The code for blocking unwanted shortcuts in various Web browsers can get a little lengthy:
#IfWinActive ahk_class Chrome_WidgetWin_1 ^W::MsgBox Oops! You pressed CTRL+W !F4::MsgBox Oops! You pressed ALT+F4 ^F4::MsgBox Oops! You pressed CTRL+F4 #IfWinActive ahk_class MozillaWindowClass ^W::MsgBox Oops! You pressed CTRL+W !F4::MsgBox Oops! You pressed ALT+F4 ^F4::MsgBox Oops! You pressed CTRL+F4 #IfWinActive ahk_class ApplicationFrameWindow ^W::MsgBox Oops! You pressed CTRL+W !F4::MsgBox Oops! You pressed ALT+F4 ^F4::MsgBox Oops! You pressed CTRL+F4 #IfWinActive
If left unblocked by AutoHotkey Hotkeys, the three unsafe Windows shortcut key combinations (CTRL+W, ALT+F4, and CTRL+F4)—which can inadvertently close Web editing windows—could lead to the loss of important work. In this case, the Microsoft Edge Web browser is added to the shortcut blocking list by attaching the parameter ahk_class ApplicationFrameWindow to the #IfWinActive directive along with the same three repeated Hotkeys.
If we continue adding to this approach, as more programs are targeted for blocking (Internet Explorer, Safari, etc.), the code gets longer and longer as each set of blocked Hotkeys is included with a new #IfWinActive class (e.g. ahk_class ApplicationFrameWindow for the Microsoft Edge Web browser). Let’s look at a simple method for creating groups of context-sensitive Hotkeys using the GroupAdd command which only requires one additional line of code for each new program type.
Creating Hotkey Groups with the GroupAdd Command
One of the parameters available for the #IfWinActive directive is ahk_group (#IfWinActive ahk_group MyGroup). By creating and recalling a group of windows, the code needed for blocking repeated shortcuts is sharply reduced. The GroupAdd command creates a group of windows, then recalls that group with the ahk_group parameter.
Tip: The first part of this blog only discusses one limited use of GroupAdd when blocking Windows shortcuts. When working with similar types of windows, there are many other useful ways to implement window groups in your scripts. The ahk_group parameter works with window commands which use a window title (the WinTitle parameter). “The commands WinMinimize, WinMaximize, WinRestore, WinHide, WinShow, WinClose, and WinKill will act on all the group’s windows. By contrast, the other window commands such as WinActivate and IfWinExist will operate only on the topmost window of the group.” At the end of this blog, I offer a simple script using GroupAdd to select individual windows for easy group manipulation.
Since GroupAdd is a command (not a directive, as discussed in my last blog), it must run in either the auto-execute section at the beginning of the script or within a function or another command routine after the script loads. That means the group does not exist when the #IfWinActive directive is first loaded, but that group must be created before the included Hotkey action will work. For example, the #IfWinActive snippet is defined and loaded in the first phase of AutoHotkey AHK file processing—per the discussion last time:
#IfWinActive ahk_group MyGroup ^!#g::MsgBox Group works! #IfWinActive
In this case, the Hotkey combination CTRL+ALT+WIN+G (^!#g) will display the message “Group works!” whenever an active program window is included in the group MyGroup. However, until the GroupAdd command defines that group, nothing happens. Commonly, a group of windows is defined in the auto-execute section of the script—although it can be created or expanded at any time after the script is loaded:
GroupAdd, MyGroup, ahk_class Notepad GroupAdd, MyGroup, ahk_class Notepad++
This GroupAdd code creates a group called MyGroup which includes all Notepad and Notepad++ windows. Whenever either type of editing window is active, pressing CTRL+ALT+WIN+G (^!#g) pops up the Hotkey message found within the phase-one loaded #IfWinActive directive. (If the window group does not exist, running the GroupAdd command creates it automatically.)
Since GroupAdd is a command, we can insert more classes of windows after the script is loaded. For example, adding another GroupAdd command to any Hotkey or Label subroutine extends the coverage of the #IfWinActive directive:
GroupAdd, MyGroup, ahk_class WordPadClass
Running the above single-line GroupAdd command in a separate Hotkey or subroutine adds Wordpad to the group of windows (MyGroup) affected by the #IfWinActive directive context-sensitive Hotkey combinations.
Note: While it is easy to add more windows to a group, I don’t see a way to either remove window classes or delete the group once the script is loaded. It seems to be a one-way command requiring script editing and/or reloading to reduce its reach.
Shorter Code for Blocking Shortcuts
By defining an AutoHotkey group of Web browser windows where we find the unwanted shortcuts, we reduce the #IfWinActive directive code to:
#IfWinActive ahk_group BrowserGroup ^W::MsgBox Oops! You pressed CTRL+W !F4::MsgBox Oops! You pressed ALT+F4 ^F4::MsgBox Oops! You pressed CTRL+F4 #IfWinActive
This snippet crops two-thirds of the code out of the original script found at the top of this blog. Next, we must create the group by the same name (BrowserGroup) in the auto-execute section of the script:
GroupAdd, BrowserGroup, ahk_class Chrome_WidgetWin_1 GroupAdd, BrowserGroup, ahk_class MozillaWindowClass GroupAdd, BrowserGroup, ahk_class ApplicationFrameWindow
Each GroupAdd command line inserts another class of window into the group BrowserGroup. This accounts for Google Chrome (Chrome_WidgetWin_1), Mozilla Firefox (MozillaWindowClass), and Microsoft Edge (ApplicationFrameWindow). But what if we want to include the old Microsoft Internet Explorer browser?
Load an Internet Explorer window, then obtain the ahk_class (i.e. IEFrame) using Window Spy—as explained in this previous blog. Next, merely add one more GroupAdd line of code to the script and reload:
GroupAdd, BrowserGroup, ahk_class Chrome_WidgetWin_1 GroupAdd, BrowserGroup, ahk_class MozillaWindowClass GroupAdd, BrowserGroup, ahk_class ApplicationFrameWindow GroupAdd, BrowserGroup, ahk_class IEFrame
More active Windows program types can be added to any window group by editing the script or creating a Hotkey to do it on the fly:
^!k:: WinGetClass, Class, A GroupAdd, BrowserGroup, ahk_class %Class% Return
How is Works
When the Hotkey combination CTRL+ALT+K is pressed, the WinGetClass command retrieves the ahk_class of the active window and stores it to the variable Class. Next, that ahk_class parameter is added to the window group. (Placing percent signs % around the new variable Class inserts the saved window ahk_class value into the GroupAdd command.) Now, the three dangerous shortcuts are also blocked in the newly added window class.
This new shortcut protection is only valid for this session. Unlike the commands in the auto-execute section, this window class is temporarily added to the group and lost whenever the script is reloaded.
This type of Hotkey can be handy for grouping new windows as you open them, then using the GroupActivate, GroupDeactivate, and GroupClose (or other windows commands) to view and control them.
A Simple Script for Picking and Controlling a Group of Windows
Maybe one of the best ways to use the GroupAdd command is in AutoHotkey scripts to quickly collect windows for easy access during a working session. After loading such a script, running windows can be added to the working group one at a time. Then, Hotkey commands can be used to minimize the group, restore the group, or cycle through windows in the group one at a time. These group features quickly find key running processes hidden behind other windows and speed up app selection without digging through the entire Windows ALT+TAB list or picking from the Taskbar. The following script does just that:
^!k:: WinGet, WinID, ID, A GroupAdd, WinGroup, ahk_id %WinID% MsgBox, Window %WinID% added to group ,`rCTRL+[ Restore Group ,`rCTRL+] Minimize Group ,`rCTRL+BackSlash Cycle Group ,`rCTRL+BackSpace Reset Group. Return
#IfWinExist, ahk_group WinGroup ^[::WinRestore, ahk_group WinGroup ^]::WinMinimize, ahk_group WinGroup ^\::GroupActivate, WinGroup RControl & BackSpace::Reload #IfWinExist
This script adds active program windows to the group (WinGroup) one at a time. When the script is first loaded, the window group (WinGroup) does not exist. It’s created only when the first window is added. To add a window to the work group activate the target window (open the program or select the window), then simultaneously press the CTRL+ALT+K (^!k) Hotkey combination.
AutoHotkey grabs the window ID (WinGet, WinID, ID, A) which is unique for each loaded window. Calling that ID adds the selected window to the group (GroupAdd, WinGroup, ahk_id %WinID%). A confirmation message is displayed which also lists the now active Hotkey combinations for the group of windows and what they do. (The MsgBox command uses AutoHotkey line continuation to wrap the single command line for display purposes.)
The Hotkey CTRL+Left Square Bracket (^[) uses the WinRestore command to bring the entire group of windows to the forefront. The CTRL+Right Square Bracket (^]) combination uses the WinMinimize command to reduce the entire group of windows to the Taskbar. The Hotkey CTRL+BackSlash (^\) uses the GroupActivate command to cycle through each window in the group one at a time.
To reset the window group, RIGHT CONTROL+BACKSPACE (RControl & BackSpace) reloads the script—effectively deleting the group.
Note: This last Hotkey combination (RControl & BackSpace) uses the special key names and the ampersand (&) to create the activating key combination. The same Hotkey could be defined with >^BackSpace. The right arrow (>) tells AutoHotkey to use the right side CTRL modifier key—in this case the right control key (>^) and BACKSPACE without the need for the ampersand (&).
2 thoughts on “AutoHotkey GroupAdd Command Reduces Script Code (Beginning Hotkeys Part 4)”
Hey, that’s a good idea that I never thought of, adding windows to your group with a hotkey and minimizing, restoring all at once. Windows management is one thing AHK sure excels in!
Good work on your explanations.
Hi Jack. Thanks for your great blog! Until I saw “A Simple Script for Picking and Controlling a Group of Windows” I had never used the GroupAdd command. Your cool example prompted me to start experimenting and I added a few features that might interest others. For what it’s worth…
; Ignore certain classes of windows
; Progman = Desktop; DV2ControlHost = Start Menu; Shell_TrayWnd = Taskbar
WinGetClass, WinClass, A
if WinClass in Progman,DV2ControlHost,Shell_TrayWnd
; Get the Titles and IDs of all windows already in myWinGroup (if any)
Loop % ID_list
WinID := ID_list%A_Index%
WinGetTitle, WinTitle, ahk_id %WinID%
WinGroupTitles = %WinGroupTitles%`n%WinTitle%|ID:%WinID%
; Get the Active Window ID and determine if it had been previously added to myWinGroup
WinGet, WinID, ID, A
WinGet, ActiveWindowInGroupID, ID, % "ahk_id " WinID " ahk_group myWinGroup"
if ActiveWindowInGroupID ; myWinGroup previously existed and active window was found in the group
msg1 = Window was already in the group:%WinGroupTitles%
GroupAdd, myWinGroup, ahk_id %WinID%
if WinGroupTitles= ; myWinGroup did not previously exist
msg1 = New window group created.
msg1 = Window added to:%WinGroupTitles% ; myWinGroup previously existed, but active window was NOT found in the group
Alt + [ : Restore the Group
Alt + ] : Minimize the Group
Alt + \ : Cycle Group Members
Alt + Esc : Empty the Group
; Display myWinGroup information via a Tooltip (for 2.5 seconds).
SetTimer, CloseToolTip, 2500
#IfWinExist, ahk_group myWinGroup
![::WinRestore, ahk_group myWinGroup
!]::WinMinimize, ahk_group myWinGroup
Alt & Esc::EmptyGroup()
ToolTip, Window Group emptied.
SetTimer, RemoveToolTip, Off