Variables and Expressions


Table of Contents

Introduction to Variables

Variable types: AutoHotkey has no explicitly defined variable types; all variables are stored as character strings. However, a variable containing only digits (with an optional decimal point) is automatically converted to a number when a math operation or comparison requires it. Conversely, the result of a math operation is converted back to a string when it needs to be stored in a variable.

Variable scope and declarations: With the exception of local variables in functions, all variables are global; that is, their contents may be read or altered by any part of the script. In addition, variables are not declared; they come into existence simply by using them (and each variable starts off empty/blank).

Variable names: Variable names are not case sensitive (for example, CurrentDate is the same as currentdate). Variable names may be up to 254 characters long and may consist of letters, numbers and the following punctuation: # _ @ $ ? [ ]

Due to style conventions, it is generally better to name your variables using only letters, numbers, and the underscore character (for example: CursorPosition, Total_Items, and entry_is_valid). This style allows people familiar with other computer languages to understand your scripts more easily. Also, if you use the same conventions in AutoHotkey as you use in other languages, you may find it easier to re-read your own scripts.

Although a variable name may consist entirely of digits, this is generally used only for incoming command line parameters. Such numeric names cannot be used in expressions because they would be seen as numbers rather than variables.

Since the words AND, OR, and NOT are used as operators in expressions, generally they should not be used as variable names. Using such names in an expression would prevent proper evaluation. In addition, a line such as OR = 123 would be interpreted as a continuation line rather than an assignment.

Storing values in variables: To store a string or number in a variable, there are two methods: traditional and expression. The traditional method uses the equal sign operator (=) to assign unquoted literal strings or variables enclosed in percent signs. For example:

MyNumber = 123
MyString = This is a literal string.
CopyOfVar = %Var%  ; With the = operator, percent signs are required to retrieve a variable's contents.

By contrast, the expression method uses the colon-equal operator (:=) to store numbers, quoted strings, and other types of expressions. The following examples are functionally identical to the previous ones:

MyNumber := 123
MyString := "This is a literal string."
CopyOfVar := Var  ; Unlike its counterpart in the previous section, percent signs are not used with the := operator.

The latter method is preferred by many due to its greater clarity, and because it supports an expression syntax nearly identical to that in many other languages.

You may have guessed from the above that there are two methods to erase the contents of a variable (that is, to make it blank):

MyVar =
MyVar := ""

The empty pair of quotes above should be used only with the := operator because if it were used with the = operator, it would store two literal quote-characters inside the variable.

Retrieving the contents of variables: Like the two methods of storing values, there are also two methods for retrieving them: traditional and expression. The traditional method requires that each variable name be enclosed in percent signs to retrieve its contents. For example:

CopyOfVar = %Var%
MsgBox The value in the variable named Var is %Var%.

By contrast, the expression method omits the percent signs around variable names, but encloses literal strings in quotes. Thus, the following are the expression equivalents of the previous examples:

CopyOfVar := Var
MsgBox % "The value in the variable named Var is " . Var . "."

In the MsgBox line above, a percent sign and a space is used to change the parameter from traditional to expression mode. This is necessary because the traditional method is used by default by all commands (except where otherwise documented). However, certain parameters of some commands are documented as accepting expressions, in which case the leading percent sign is permitted but not necessary. For example, all of the following are effectively identical because Sleep's first parameter is expression-capable:

Sleep MillisecondsToWait
Sleep %MillisecondsToWait%
Sleep % MillisecondsToWait

Comparing variables: Please read the expressions section below for important notes about the different kinds of comparisons, especially about when to use parentheses.

Expressions

Expressions are used to perform one or more operations upon a series of variables, literal strings, and/or literal numbers.

Variable names in an expression are not enclosed in percent signs (except for arrays and other double references). Consequently, literal strings must be enclosed in double quotes to distinguish them from variables. For example:

if (CurrentSetting > 100 or FoundColor <> "Blue")
    MsgBox The setting is too high or the wrong color is present.

In the example above, "Blue" appears in quotes because it is a literal string. To include an actual quote-character inside a literal string, specify two consecutive quotes as shown twice in this example: "She said, ""An apple a day."""

Important: An if-statement that contains an expression is differentiated from a traditional if-statement such as If FoundColor <> Blue by making the character after the word "if" an open-parenthesis. Although this is usually accomplished by enclosing the entire expression in parentheses, it can also be done with something like if (x > 0) and (y > 0). In addition, the open-parenthesis may be omitted entirely if the first item after the word "if" is a function call or an operator such as "not" or "!".

Empty strings: To specify an empty string in an expression, use an empty pair of quotes. For example, the statement if (MyVar <> "") would be true if MyVar is not blank. However, in a traditional-if, a pair of empty quotes is treated literally. For example, the statement if MyVar = "" is true only if MyVar contains an actual pair of quotes. Thus, to check if a variable is blank with a traditional-if, use = or <> with nothing on the right side as in this example: if Var =

On a related note, any invalid expression such as (x +* 3) yields an empty string.

Boolean values: When an expression is required to evaluate to true or false (such as an IF-statement), a blank or zero result is considered false and all other results are considered true. For example, the statement "if ItemCount" would be false only if ItemCount is blank or 0. Similarly, the expression "if not ItemCount" would yield the opposite result.

Operators such as NOT/AND/OR/>/=/< automatically produce a true or false value: they yield 1 for true and 0 for false. For example, in the following expression, the variable Done is assigned 1 if either of the conditions is true:

Done := A_Index > 5 or FoundIt

As hinted above, a variable can be used to hold a false value simply by making it blank or assigning 0 to it. To take advantage of this, the shorthand statement "if Done" can be used to check whether the variable Done is true or false.

The words true and false are built-in variables containing 1 and 0. They can be used to make a script more readable as in these examples:

CaseSensitive := false
ContinueSearch := true

Storing the result of an expression: To assign a result to a variable, use the := operator. For example:

NetPrice := Price * (1 - Discount/100)

Since the example above produces a floating point number (due to division), the number of decimal places stored in NetPrice is determined by SetFormat. SetFormat can also alter other characteristics of expression results. By contrast, AutoTrim has no effect on an expression's result.

Integers and floating point: Within an expression, literal numbers are considered to be floating point if they contain a decimal point; otherwise, they are integers. For most operators -- such as addition and multiplication -- if either of the inputs is a floating point number, the result will also be a floating point number.

Within expressions and non-expressions alike, integers may be written in either hexadecimal or decimal format. Hexadecimal numbers all start with the prefix 0x. For example, Sleep 0xFF is equivalent to Sleep 255.

Force an expression: An expression can be used in a parameter that does not directly support it (except an OutputVar or InputVar parameter such as those of StringLen) by preceding the expression with a percent sign and a space or tab. This technique is often used to access arrays. For example:

FileAppend, % MyArray%i%, My File.txt
MsgBox % "The variable MyVar contains " MyVar "."
Loop % Iterations + 1
WinSet, Transparent, % X + 100
Control, Choose, % CurrentSelection - 1

Operators in Expressions

Operators of equal precedence such as multiply (*) and divide (/) are evaluated in left-to-right order by default. By contrast, an operator of lower precedence such as add (+) is evaluated after a higher one such as multiply (*). For example, 3 + 2 * 2 would be evaluated as though it were 3 + (2 * 2). Parentheses may be used to override precedence as in this example: (3 + 2) * 2

Expression Operators (in descending precedence order)

%Var%

If a variable is enclosed in percent signs within an expression (e.g. %Var%), whatever that variable contains is assumed to be the name or partial name of another variable (if there is no such variable, %Var% resolves to a blank string). This is most commonly used to reference array elements such as the following example:

Var := MyArray%A_Index% + 100

Such a reference should not resolve to an environment variable, the clipboard, or any reserved/read-only variable. If it does, it is treated as an empty string.

** Power (**). Both the base and the exponent may contain a decimal point. If the exponent is negative, the result will be formatted as a floating point number even if the base and exponent are both integers. Since ** is of higher precedence than unary minus, -2**2 is evaluated like -(2**2) and so yields -4. Thus, to raise a literal negative number to a power, enclose it in parentheses such as (-2)**2. Note: A negative base combined with a fractional exponent such as (-2)**0.5 is not supported; it will yield an empty string. But both (-2)**2 and (-2)**2.0 are supported.
-
!
~
& *

Unary minus (-): Although it uses the same symbol as the subtract operator, unary minus applies to only a single item or sub-expression as shown twice in this example: -(3 / -x). On a related note, any unary plus signs (+) within an expression are ignored.

Logical-not (!): If the operand is blank or 0, the result of applying logical-not is 1, which means "true". Otherwise, the result is 0 (false). For example: !x or !(y and z).
Note: The word NOT is synonymous with ! except that ! has a higher precedence.

Bitwise-not (~): This inverts each bit of its operand. If the operand is a floating point value, it is truncated to an integer prior to the calculation. If the operand is between 0 and 4294967295 (0xffffffff), it will be treated as an unsigned 32-bit value. Otherwise, it is treated as a signed 64-bit value. For example, ~0xf0f evaluates to 0xfffff0f0 (4294963440).

Address (&) and Dereference (*) [v1.0.36.07+]: &MyVar retrieves the address of MyVar's contents in memory. Conversely, *MyVar would assume that MyVar contains a numeric memory address and retrieve the byte at that address as a number between 0 and 255 (0 is always retrieved if the address is 0; but any other invalid address must be avoided because it might crash the script). These rarely-used operators can help with DllCall structures and the manipulation of strings that contain binary zeros. ExtractInteger() is one example.

*
/
//

Multiply (*): The result is an integer if both inputs are integers; otherwise, it is a floating point number.

True divide (/): Unlike EnvDiv (/=), true division yields a floating point result even when both inputs are integers. For example, 3/2 yields 1.5 rather than 1, and 4/2 yields 2.0 rather than 2.

Floor divide (//): The double-slash operator uses high-performance integer division if the two inputs are integers. For example, 5//3 is 1 and 5//-3 is -1. If either of the inputs is in floating point format, floating point division is performed and the result is truncated to the nearest integer to the left. For example, 5//3.0 is 1.0 and 5.0//-3 is -2.0. Although the result of this floating point division is an integer, it is stored in floating point format so that anything else that uses it will see it as such. For modulo, see mod().

On a related note, the *= and /= operators are a shorthand way to multiply or divide the value in a variable by another value. For example, Var*=2 produces the same result as Var:=Var*2 (though the former performs better).

Division by zero yields a blank result (empty string).

+
-

Add (+) and subtract (-). Note: In expressions, any blank value (empty string) involved in a math operation is not assumed to be zero. Instead, it is treated as an error, which causes that part of the expression to evaluate to an empty string. For example, if the variable X is blank, the expression X+1 yields a blank value rather than 1.

The += and -= operators are a shorthand way to increment or decrement a variable. For example, Var+=2 produces the same result as Var:=Var+2 (though the former performs better). Similarly, a variable can be increased or decreased by 1 by using Var++, Var--, ++Var, or --Var.

<<
>>
Bit shift left (<<) and right (>>). Example usage: Value1 << Value2. Floating point inputs are truncated to integers prior to the calculation. Shift left (<<) is equivalent to multiplying Value1 by "2 to the Value2th power". Shift right (>>) is equivalent to dividing Value1 by "2 to the Value2th power" and truncating the remainder.
&
^
|
Bitwise-and (&), bitwise-exclusive-or (^), and bitwise-or (|). Of the three, & has the highest precedence and | has the lowest. Floating point inputs are truncated to integers prior to the calculation.
.

Concatenate (.). The period (dot) operator may be used to merge adjacent strings and variables (there should be at least one space on each side of the period). In most cases, you can also omit the period to achieve the same result (though there should be at least one space between the items to be merged).
Example (expression method): Var := "The color is " . FoundColor
Example (traditional method):  Var = The color is %FoundColor%

Sub-expressions and references such as Array%i% can also be merged with other items. For example:
Var := "The net price is " . Price * (1 - Discount/100)
Var := "The largest among X and Y is " . Max(X, Y)
Var := "The value of array element " i " is " Array%i%

A line that begins with a period is automatically merged with the line above it. See line continuation for details.

When text is being appended to the end of a variable, the traditional method of concatenation (=) performs better than the expression method (:=), especially when the strings involved are large. Here is an example of the fast method: Var = %Var%%TextToAppend%

>   <
>= <=
Greater (>), less (<), greater-or-equal (>=), and less-or-equal (<=). If either of the inputs is not a number, both are compared alphabetically (a quoted literal string such as "55" is always considered non-numeric in this context). The comparison is case sensitive only if StringCaseSense has been turned on.
= ==
<> !=
Equal (=) , case-sensitive-equal (==) , and not-equal (<> or !=). The operators != and <> are identical in function. The == operator behaves identically to = except when either of the inputs is not a number, in which case == is always case sensitive and = is always case insensitive (the method of insensitivity depends on StringCaseSense). By contrast, <> and != obey StringCaseSense. Note: A quoted literal string such as "55" is always considered non-numeric in this context.
NOT Logical-NOT. Except for its lower precedence, this is the same as the ! operator. For example, not (x = 3 or y = 3) is the same as !(x = 3 or y = 3)
AND
&&
Both of these are logical-AND. For example: x > 3 and x < 10. To enhance performance, short-circuit evaluation is applied whenever possible. Also, a line that begins with AND/OR/&&/|| is automatically merged with the line above it. See line continuation for details.
OR
||
Both of these are logical-OR. For example: x <= 3 or x >= 10. To enhance performance, short-circuit evaluation is applied whenever possible.

mod()
round()
abs()

These and other built-in math functions are described here.


Performance
: The expression assignment operator (:=) is optimized so that it performs just as quickly as the non-expression operator (=) for simple cases such as the following:

x := y  ; Same performance as x = %y%
x := 5  ; Same performance as x = 5.
x := "literal string"  ; Same performance as x = literal string.


Built-in Variables

The following variables are built into the program and can be referenced by any script. Most of them are reserved, meaning that their contents cannot be directly altered by the script.

Table of Contents

Special Characters

A_Space This variable contains a single space character. See AutoTrim for details.
A_Tab This variable contains a single tab character. See AutoTrim for details.

Script Properties

1, 2, 3, etc. These variables are automatically created whenever a script is launched with command line parameters. They can be changed and referenced just like normal variable names (for example: %1%). The variable %0% contains the number of parameters passed (0 if none). For details, see the command line parameters.
A_WorkingDir The script's current working directory, which is where files will be accessed by default. The final backslash is not included unless it is the root directory. Two examples: C:\ and C:\My Documents. Use SetWorkingDir to change the working directory.
A_ScriptDir The full path of the directory where the current script is located. For backward compatibility with AutoIt v2, the final backslash is included only for .aut scripts (even for root drives). An example for .aut scripts is C:\My Documents\
A_ScriptName The file name of the current script, without its path, e.g. MyScript.ahk.
A_ScriptFullPath The combination of the above two variables to give the complete file specification of the script, e.g. C:\My Documents\MyScript.ahk
A_LineNumber

The number of the currently executing line within the script (or one of its #Include files). This line number will match the one shown by ListLines; it can be useful for error reporting such as this example: MsgBox Could not write to log file (line number %A_LineNumber%).

Since a compiled script has merged all its #Include files into one big script, its line numbering may be different than when it is run in non-compiled mode.

A_LineFile The full path and name of the file to which A_LineNumber belongs, which will be the same as A_ScriptFullPath unless the line belongs to one of a non-compiled script's #Include files.
A_AhkVersion In versions prior to 1.0.22, this variable is blank. Otherwise, it contains the version of AutoHotkey that is running the script, such as 1.0.22. In the case of a compiled script, the version that was originally used to compile it is reported. The formatting of the version number allows a script to check whether A_AhkVersion is greater than some minimum version number with > or >= as in this example: if A_AhkVersion >= 1.0.25.07
A_AhkPath
[v1.0.41+]

For non-compiled scripts: The full path and name of the EXE file that is actually running the current script. For example: C:\Program Files\AutoHotkey\AutoHotkey.exe

For compiled scripts: The same as the above except the AutoHotkey directory is discovered via the registry entry HKEY_LOCAL_MACHINE\SOFTWARE\AutoHotkey\InstallDir. If there is no such entry, A_AhkPath is blank.

A_IsCompiled Contains 1 if the script is running as a compiled EXE and nothing if it is not.
A_ExitReason The most recent reason the script was asked to terminate. This variable is blank unless the script has an OnExit subroutine and that subroutine is currently running or has been called at least once by an exit attempt. See OnExit for details.

Date and Time

A_YYYY Current 4-digit year (e.g. 2004). Synonymous with A_Year. Note: To retrieve a formatted time or date appropriate for your locale and language, use "FormatTime, OutputVar" (time and long date) or "FormatTime, OutputVar,, LongDate" (retrieves long-format date).
A_MM Current 2-digit month (01-12). Synonymous with A_Mon.
A_DD Current 2-digit day of the month (01-31). Synonymous with A_MDay.
A_MMMM Current month's full name in the current user's language, e.g. July
A_MMM Current month's abbreviation in the current user's language, e.g. Jul
A_DDDD Current day of the week's full name in the current user's language, e.g. Sunday
A_DDD Current day of the week's 3-letter abbreviation in the current user's language, e.g. Sun
A_WDay Current 1-digit day of the week (1-7). 1 is Sunday in all locales.
A_YDay Current day of the year (1-366). The value is not zero-padded, e.g. 9 is retrieved, not 009. To retrieve a zero-padded value, use the following: FormatTime, OutputVar, , YDay0
A_YWeek Current year and week number (e.g. 200453) according to ISO 8601. To separate the year from the week, use StringLeft, Year, A_YWeek, 4 and StringRight, Week, A_YWeek, 2. Precise definition of A_YWeek: If the week containing January 1st has four or more days in the new year, it is considered week 1. Otherwise, it is the last week of the previous year, and the next week is week 1.
A_Hour Current 2-digit hour (00-23) in 24-hour time (for example, 17 is 5pm). To retrieve 12-hour time as well as an AM/PM indicator, follow this example: FormatTime, OutputVar, , h:mm:ss tt
A_Min

Current 2-digit minute (00-59).

A_Sec Current 2-digit second (00-59).
A_MSec Current 3-digit millisecond (000-999). To remove the leading zeros, follow this example: Milliseconds := A_MSec + 0
A_Now The current local time in YYYYMMDDHH24MISS format. Note: Date and time math can be performed with EnvAdd and EnvSub. Also, FormatTime can format the date and/or time according to your locale or preferences.
A_NowUTC The current Coordinated Universal Time (UTC) in YYYYMMDDHH24MISS format. UTC is essentially the same as Greenwich Mean Time (GMT).
A_TickCount

The number of milliseconds since the computer was rebooted. By storing A_TickCount in a variable, elapsed time can later be measured by subtracting that variable from the latest A_TickCount value. For example:

StartTime := A_TickCount
Sleep, 1000
ElapsedTime := A_TickCount - StartTime
MsgBox,  %ElapsedTime% milliseconds have elapsed.

If you need more precision than A_TickCount's 10ms, use QueryPerformanceCounter().

Script Settings

A_IsSuspended Contains 1 if the script is suspended and 0 otherwise.
A_BatchLines (synonymous with A_NumBatchLines) The current value as set by SetBatchLines. Examples: 200 or 10ms (depending on format).
A_TitleMatchMode The current mode set by SetTitleMatchMode: 1, 2, 3, or RegEx.
A_TitleMatchModeSpeed The current match speed (fast or slow) set by SetTitleMatchMode.
A_DetectHiddenWindows The current mode (On or Off) set by DetectHiddenWindows.
A_DetectHiddenText The current mode (On or Off) set by DetectHiddenText.
A_AutoTrim The current mode (On or Off) set by AutoTrim.
A_StringCaseSense The current mode (On, Off, or Locale) set by StringCaseSense.
A_FormatInteger The current integer format (H or D) set by SetFormat.
A_FormatFloat The current floating point number format set by SetFormat.
A_KeyDelay The current delay set by SetKeyDelay (always decimal, not hex). This delay is for the traditional SendEvent mode, not SendPlay.
A_WinDelay The current delay set by SetWinDelay (always decimal, not hex).
A_ControlDelay The current delay set by SetControlDelay (always decimal, not hex).
A_MouseDelay The current delay set by SetMouseDelay (always decimal, not hex). This delay is for the traditional SendEvent mode, not SendPlay.
A_DefaultMouseSpeed The current speed set by SetDefaultMouseSpeed (always decimal, not hex).
A_IconHidden Contains 1 if the tray icon is currently hidden or 0 otherwise. The icon can be hidden via #NoTrayIcon or the Menu command.
A_IconTip Blank unless a custom tooltip for the tray icon has been specified via Menu, Tray, Tip -- in which case it's the text of the tip.
A_IconFile Blank unless a custom tray icon has been specified via Menu, tray, icon -- in which case it's the full path and name of the icon's file.
A_IconNumber Blank if A_IconFile is blank. Otherwise, it's the number of the icon in A_IconFile (typically 1).

User Idle Time

A_TimeIdle The number of milliseconds that have elapsed since the system last received keyboard, mouse, or other input. This is useful for determining whether the user is away. This variable will be blank unless the operating system is Windows 2000, XP, or beyond. Physical input from the user as well as artificial input generated by any program or script (such as the Send or MouseMove commands) will reset this value back to zero. Since this value tends to increase by increments of 10, do not check whether it is equal to another value. Instead, check whether it is greater or less than another value. For example: IfGreater, A_TimeIdle, 600000, MsgBox, The last keyboard or mouse activity was at least 10 minutes ago.
A_TimeIdlePhysical

Same as above but ignores artificial keystrokes and/or mouse clicks whenever the corresponding hook (keyboard or mouse) is installed. If neither hook is installed, this variable is equivalent to A_TimeIdle. If only one hook is present, only that one type of artificial input will be ignored. A_TimeIdlePhysical may be more useful than A_TimeIdle for determining whether the user is truly present.

GUI Windows and Menu Bars

A_Gui The GUI window number that launched the current thread. This variable is blank unless a Gui control, menu bar item, or event such as GuiClose/GuiEscape launched the current thread.
A_GuiControl The name of the variable associated with the GUI control that launched the current thread. If that control lacks an associated variable, A_GuiControl instead contains the first 63 characters of the control's text/caption (this is most often used to avoid giving each button a variable name). A_GuiControl is blank whenever: 1) A_Gui is blank; 2) a GUI menu bar item or event such as GuiClose/GuiEscape launched the current thread; 3) the control lacks an associated variable and has no caption; or 4) The control that originally launched the current thread no longer exists (perhaps due to Gui Destroy).
A_GuiWidth
A_GuiHeight
These contain the GUI window's width and height when referenced in a GuiSize subroutine. They apply to the window's client area, which is the area excluding title bar, menu bar, and borders.
A_GuiX
A_GuiY
These contain the X and Y coordinates for GuiContextMenu and GuiDropFiles events. Coordinates are relative to the upper-left corner of the window.
A_GuiControlEvent

A_GuiEvent is a
synonym for it in v1.0.36+.

The type of event that launched the current thread. If the thread was not launched via GUI action, this variable is blank. Otherwise, it contains one of the following strings:

Normal: The event was triggered by a single left-click or via keystrokes (arrow keys, TAB key, space bar, underlined shortcut key, etc.). This value is also used for menu bar items and the special events such as GuiClose and GuiEscape.

DoubleClick: The event was triggered by a double-click. Note: The first click of the click-pair will still cause a Normal event to be received first. In other words, the subroutine will be launched twice: once for the first click and again for the second.

RightClick: Occurs only for GuiContextMenu, ListViews, and TreeViews.

Context-sensitive values: For details see GuiContextMenu, GuiDropFiles, Slider, MonthCal, ListView, and TreeView.

A_EventInfo
[v1.0.36+]

Contains additional information about the following events:

Note: Unlike variables such as A_ThisHotkey, each thread retains its own value for A_Gui, A_GuiControl, A_GuiX/Y, A_GuiControlEvent, and A_EventInfo. Therefore, if a thread is interrupted by another, upon being resumed it will still see its original/correct values in these variables.

Hotkeys, Hotstrings, and Custom Menu Items

A_ThisMenuItem The name of the most recently selected custom menu item (blank if none).
A_ThisMenu The name of the menu from which A_ThisMenuItem was selected.
A_ThisMenuItemPos A number indicating the current position of A_ThisMenuItem within A_ThisMenu. The first item in the menu is 1, the second is 2, and so on. Menu separator lines are counted. This variable is blank if A_ThisMenuItem is blank or no longer exists within A_ThisMenu. It is also blank if A_ThisMenu itself no longer exists.
A_ThisHotkey

The key name of the most recently executed hotkey or hotstring (blank if none), e.g. #z. This value will change if the current thread is interrupted by another hotkey, so be sure to copy it into another variable immediately if you need the original value for later use in a subroutine.

When a hotkey is first created -- either by the Hotkey command or a double-colon label in the script -- its key name and the ordering of its modifier symbols becomes the permanent name of that hotkey.

A_PriorHotkey Same as above except for the previous hotkey. It will be blank if none.
A_TimeSinceThisHotkey The number of milliseconds that have elapsed since A_ThisHotkey was pressed. It will be -1 whenever A_ThisHotkey is blank.
A_TimeSincePriorHotkey The number of milliseconds that have elapsed since A_PriorHotkey was pressed. It will be -1 whenever A_PriorHotkey is blank.
A_EndChar The ending character that was pressed by the user to trigger the most recent non-auto-replace hotstring. If no ending character was required (due to the * option), this variable will be blank.

Operating System and User Info

ComSpec
[v1.0.43.08+]
Contains the same string as the environment's ComSpec variable (e.g. C:\Windows\system32\cmd.exe). Often used with Run/RunWait. Note: there is no A_ prefix on this variable.
A_Temp
[v1.0.43.09+]
The full path and name of the folder designated to hold temporary files (e.g. C:\DOCUME~1\UserName\LOCALS~1\Temp). It is retrieved from one of the following locations (in order): 1) the environment variables TMP, TEMP, or USERPROFILE; 2) the Windows directory. On Windows 9x, A_WorkingDir is returned if neither TMP nor TEMP exists.
A_OSType The type of Operating System being run.  Either WIN32_WINDOWS (i.e. Windows 95/98/ME) or WIN32_NT (i.e. Windows NT4/2000/XP/2003/Vista).
A_OSVersion

One of the following strings: WIN_VISTA [requires v1.0.44.13+], WIN_2003, WIN_XP, WIN_2000, WIN_NT4, WIN_95, WIN_98, WIN_ME. For example:

if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME  ; Note: No spaces around commas.
{
    MsgBox This script requires Windows 2000/XP or later.
    ExitApp
}
A_Language The system's default language, which is one of these 4-digit codes.
A_ComputerName The network name of the computer.
A_UserName The logon name of the current user.
A_WinDir The windows directory. For example: C:\Windows
A_ProgramFiles
or ProgramFiles
The Program Files directory (e.g. C:\Program Files). In v1.0.43.08+, the A_ prefix may be omitted, which helps ease the transition to #NoEnv.
A_AppData
[v1.0.43.09+]
The full path and name of the folder containing the current user's application-specific data. For example: C:\Documents and Settings\Username\Application Data
A_AppDataCommon
[v1.0.43.09+]
The full path and name of the folder containing the all-users application-specific data.
A_Desktop The full path and name of the folder containing the current user's desktop files.
A_DesktopCommon The full path and name of the folder containing the all-users desktop files.
A_StartMenu The full path and name of the current user's Start Menu folder.
A_StartMenuCommon The full path and name of the all-users Start Menu folder.
A_Programs The full path and name of the Programs folder in the current user's Start Menu.
A_ProgramsCommon The full path and name of the Programs folder in the all-users Start Menu.
A_Startup The full path and name of the Startup folder in the current user's Start Menu.
A_StartupCommon The full path and name of the Startup folder in the all-users Start Menu.
A_MyDocuments The full path and name of the current user's "My Documents" folder. Unlike most of the similar variables, if the folder is the root of a drive, the final backslash is not included. For example, it would contain M: rather than M:\
A_IsAdmin If the current user has admin rights, this variable contains 1. Otherwise, it contains 0. Under Windows 95/98/Me, this variable always contains 1.

A_ScreenWidth
A_ScreenHeight

The width and height of the primary monitor, in pixels (e.g. 1024 and 768).

To discover the dimensions of other monitors in a multi-monitor system, use SysGet.

To instead discover the width and height of the entire desktop (even if it spans multiple monitors), use the following example (but on Windows 95/NT, both of the below variables will be set to 0):
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79

In addition, use SysGet to discover the work area of a monitor, which can be smaller than the monitor's total area because the taskbar and other registered desktop toolbars are excluded.

A_IPAddress1 through 4 The IP addresses of the first 4 network adapters in the computer.

Misc.

A_Cursor

The type of mouse cursor currently being displayed. It will be one of the following words: AppStarting, Arrow, Cross, Help, IBeam, Icon, No, Size, SizeAll, SizeNESW, SizeNS, SizeNWSE, SizeWE, UpArrow, Wait, Unknown. The acronyms used with the size-type cursors are compass directions, e.g. NESW = NorthEast+SouthWest. The hand-shaped cursors (pointing and grabbing) are classfied as Unknown.

Known limitation (in versions prior to 1.0.42.02 or on Windows 95): If this variable's contents are fetched repeatedly at a high frequency (i.e. every 500 ms or faster), it will probably disrupt the user's ability to double-click. There is no known workaround.

A_CaretX
A_CaretY

The current X and Y coordinates of the caret (text insertion point). The coordinates are relative to the active window unless CoordMode is used to make them relative to the entire screen. If there is no active window or the caret position cannot be determined, these variables are blank.

The following script allows you to move the caret around to see its current position displayed in an auto-update tooltip. Note that some windows (e.g. certain versions of MS Word) report the same caret position regardless of its actual position.

#Persistent
SetTimer, WatchCaret, 100
return
WatchCaret:
ToolTip, X%A_CaretX% Y%A_CaretY%, A_CaretX, A_CaretY - 20
return

If the contents of these variables are fetched repeatedly at a high frequency (i.e. every 500 ms or faster), the user's ability to double-click will probably be disrupted. There is no known workaround.

Clipboard The contents of the OS's clipboard, which can be read or written to. See the Clipboard section.
ClipboardAll The entire contents of the clipboard (such as formatting and text). See ClipboardAll.
ErrorLevel See ErrorLevel.
A_LastError The result from the OS's GetLastError() function. For details, see DllCall() and Run/RunWait.

Loop

A_Index This is the number of the current loop iteration (a 64-bit integer). For example, the first time the script executes the body of a loop, this variable will contain the number 1. See Loop for details.
A_LoopFileName, etc. This and other related variables are valid only inside a file-loop.
A_LoopRegName, etc. This and other related variables are valid only inside a registry-loop.
A_LoopReadLine See file-reading loop.
A_LoopField See parsing loop.

Environment Variables vs. "Normal" Variables

Environment variables are maintained by the operating system. You can see a list of them at the command prompt by typing SET then pressing Enter.

A script may create a new environment variable or change the contents of an existing one with EnvSet. However, such additions and changes are private; they are not seen by the rest of the system. One exception is when a script launches a program (even another script) via Run or RunWait: such programs inherit a copy of the parent script's environment variables, including private ones.

In v1.0.43.08+, it is recommended that all new scripts retrieve environment variables such as Path via EnvGet, OutputVar, Path. For explanation, see #NoEnv.

Variable Capacity and Memory