Beginning Tips for Writing AutoHotkey Scripts (Building Blocks Using Labels Containing Subroutines)

The beauty of a scripting language with a modular design is that that individual blocks which make up the application can be placed almost anywhere in the script file. This is especially true with AutoHotkey.

Cover 250 Border

In particular, when the file is initially loaded both hotstrings and hotkeys are parsed out in an initial pass and set up by AutoHotkey before the main processing of the script even begins. These blocks of code (in the case of hotstrings often composed of only one line) become independent features of the script. This modularity makes it easier to add more hotstrings and hotkeys by merely adding them to the end of the file. However, for the sake of convenience (and sanity), it’s useful to group common features together (with comments). This makes debugging and future modification of the code much easier. The next AutoHotkey building block of interest is the Label (or Subroutine).

AutoHotkey Labels (Subroutines)

While I tend to use the term Label as interchangeable with subroutine, technically the Label is the name assigned for finding the lines of code which comprise the subroutine. It can be said that the Label name is a way of pointing to the subroutine—or a pointer. When a Label, which can be any name followed by a colon (e.g. LabelName:), encloses a snippet of code with the Return command, a subroutine module is created:

MySubroutine:
  Sleep 1000
Return

(This example is taken from the online AutoHotkey documentation.)

Just as with hotstrings and hotkeys, a separate module of code is created which can appear almost anywhere in an AutoHotkey script—except in the middle of the auto-execute section or another block of code. However, Labels do not display the same degree of independence as hotstring and hotkeys. Outside of the auto-execute section of the script, Labels are only processed if they are called by another command or line of code in the same script. Otherwise, they do nothing.

Labels are usually a piece of the larger program called only when they are necessary to perform a specific action or process integral to the app. For example:

MySubroutine:
  MsgBox, The new value is %NewValue%.
Return

might be used to display a newly calculated value when called from another snippet of code. The most common (and best) way to call labels is through features built into AutoHotkey—rather than directly.

Executing Labels Directly

There are two primary ways to directly call and execute labels—the GoTo and GoSub commands. The use of either of these commands causes program execution to jump to the subroutine only returning after encountering the Return command. I can safely say that I have never used either of these commands in any of my AutoHotkey scripts. The use of GoTo and GoSub in any programming language has fallen into some disrepute and “generally makes scripts less readable and harder to maintain.” As you progress in AutoHotkey, you will find that there are so many ways to access labels through built-in features that it would be rare that you would ever need to directly access a label.

However, one important aspect of the GoTo and GoSub commands for calling subroutines is that they both will accept a variable name (e.g. Gosub %VarContainingLabelName%) while many other AutoHotkey commands do not. At times in more advanced scripts, this variable containing a Label name feature may be useful for writing routines which change the called Label depending upon the situation.

Note: While a Label is allowed to exist in a script without ever being called, if a command in the script calls a Label, that Label must exist within the script before loading. Otherwise, an error will be thrown and the script will cease loading. This error can be eliminated by merely adding the Label name followed by a colon (MyLabel:) to the script—which eliminates the error until you have time to write the appropriate code for the subroutine.

Tip: Labels are similar to Functions in that they perform tasks when called within a script and both are modular in nature—meaning they can appear as independent snippets almost anywhere in a script. However, there are distinct differences in how they are both written and called. Functions are often preferred over labels—especially when the same code is used repetitively by different parts of a script. (Functions are a topic for a future time, although you’ll find a little more discussion of the differences between the two below.)

If we are avoiding using the GoTo and GoSub commands, how do we call our labels?

Methods for Calling Labels (Subroutines)

Many of the AutoHotkey commands have methods for calling Labels built into them. If one of these calls is used in the script the Label must exist first. The first example uses the HotKey command to access a Label subroutine:

HotKey, ^!m, SayHi
Return

SayHi:
  MsgBox, Hi, Label!
Return

The HotKey command is an alternative method for setting up a hotkey combination on the fly. The differences between using the HotKey command and the regular method for setting up a hotkey combination (designated key combination followed by a set of double colons, ^!n::) are significant. First, unlike the regular double colon hotkey format, the HotKey command is not parsed out and automatically set up when the AutoHotkey script is first loaded. It must either appear in the auto-execute section at the beginning of the script for immediate use or be included in a later snippet of code which is activated by another action. The location of the HotKey command absolutely matters.

Second, the HotKey command will not allow the use of a command or group of commands in the same manner as double colon hotkey setup. A Label name pointing to a subroutine is the primary way to access snippets of code with the HotKey command.  Adding flexibility, the Label name may be a variable containing the name (e.g. %VarContainingLabelName%).

In the example above, the HotKey command is used to set up CTRL+ALT+M (^!m) as the hotkey combination for running the Label SayHi. (The Label name is entered after the HotKey command without the trailing colon.) Below (or almost anywhere else in the script) the label SayHi: is then located, opening the MsgBox with the words “Hi, Label!” Remember a Label is not a command or expression, but merely a pointer to the subroutine by the same name. That’s why a Label cannot be used with the double colon method for setting up hotkey combinations. This is the opposite of a function which can act as a command or expression.

Note: I’ve added a Return command after the HotKey command because it is running in the auto-execute section at the beginning of the script. The auto-execute section of a script will continue executing commands until it encounters a Return, a hotstring, a hotkey (regular setup), or another terminating command. Without the Return command, AutoHotkey would continue to process the Label SayHi: when the script is first loaded. (However, there may be times in the future when you will want a script to do this—running a Label on the first load.)

The HotKey command cannot be used with an AutoHotkey function in place of the Label, but the regular double-colon hotkey setup will accept a function—although not a Label:

^!n::SayHi()

SayHi()
{
  MsgBox, Hi, Function!
}

In the example above, the hotkey combination CTRL+ALT+N (^!n) is set up to run the function SayHi(). Since both the hotkey and function are modular, they can appear in the script at almost any location. The regular hotkey code can even appear after the function:

HotKey, ^!m, SayHi
Return

SayHi()
{
MsgBox, Hi, Function!
}

SayHi:
MsgBox, Hi, Label!
Return

^!n::SayHi()

This example script combines the two previous script into one. Notice that three of the snippets are in almost random order. In fact, the only code which must appear at the beginning is the Hotkey, ^!m, SayHi line which needs to run in the auto-execute section of the script. That’s because each of the other blocks is an independent module, the function (SayHi()—scheduled for more discussion in a later Blog), the Label (SayHi:), and the regular hotkey setup (^!n::SayHi()) which calls the function. (I deliberately placed the double colon hotkey setup at the end of the script to demonstrates that it doesn’t matter where it appears in the script—even if after the calling function.)

There is much more to say about the various ways to call Labels in AutoHotkey. As you develop more scripts, you will find powerful tools within AutoHotkey which make adding features so much easier. Most of these tools use Labels to implement those features contained in the Label’s subroutines. While most Labels can appear almost anywhere in a script, it’s  important to understand how to access them. Next time, I’ll discuss more ways to call and take advantage of AutoHotkey Labels.

 *          *          *

Part 1: Beginning Tips for Writing AutoHotkey Scripts (Modular Independence of HotStrings)

Part 2: Beginning Tips for Writing AutoHotkey Scripts (Modular Independence of HotKeys)

Part 4: Beginning Tips for Writing AutoHotkey Scripts (Methods for Running Label Subroutines)

 *          *          *

New to AutoHotkey? See “Introduction to AutoHotkey: A Review and Guide for Beginners.”

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 )

Facebook photo

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

Connecting to %s