Modules [v2.1-alpha.11+]

A module is basically a script within the script. Each module has its own:

Splitting the components of a script into modules can make the components easier to reuse and maintain.

By default, all lines of code and global variables (including functions and classes) are added to an implicitly-defined module named "__Main". The script can start a new module with #Module or load one from file with #Import.

An #Import declaration can be used to add a module or some of its functions, classes and variables into the current module's global namespace. These need not be explicitly marked as exports, but doing so with an Export declaration permits them to be imported by a wildcard import.

All modules implicitly import from the built-in "AHK" module, which contains all built-in classes, variables and functions. A declaration or assignment within a module can reuse the name of a built-in class or function, in which case that class or function is not accessible except through the AHK module (e.g. #Import AHK, AHK.MsgBox()). However, built-in (A_) variables do not require a declaration or explicit import to allow assignment, and their names cannot be reused. A_Args is the exception (it is a normal variable defined in __Main).

A module name is added to a module's global namespace only when imported, and conflicts can be resolved by giving the imported module an alias within the destination module.

#Include is able to include a file once per module.

#Warn can enable or disable warnings within the current module without affecting other modules. For details, see the #Warn remarks.

#HotIf affects only the current module. #HotIf and HotIf expressions are module-scoped, as they may contain references to module-level variables. For instance, the effect of #HotIf myToggle depends on what value myToggle has in the current module.

KS Module

The built-in KS module exports Keysharp-specific classes, functions and variables. These are not available to a script until they are imported, which keeps the global namespace the same as AutoHotkey's.

#Import "Ks" { Image, A_DirSeparator }

Capture := Image.FromDesktop()
MsgBox A_DirSeparator

New methods or properties added to an existing built-in class, such as Array or Buffer, are available without importing KS.

The full set of exports is listed below.

Classes

ExportDescription
ClrLoads .NET assemblies and calls into them from a script.
HashMapAn unordered hash table, faster than Map where ordering is not needed.
HighlightOutlines a region of the screen with a colored, click-through border.
ImageCaptures, loads, manipulates and saves images.
JsonConverts between JSON text and Keysharp objects.
NamedArgsCarries the named arguments of one call, for building or inspecting them at run time.
OverlayDraws a click-through, always-on-top surface over the screen.
RealThreadRuns a script on a real operating-system thread.
StringBufferA mutable text buffer for building large strings efficiently.
WinEventCalls a function when windows are created, activated, moved or closed.

Functions

ExportDescription
AESEncrypts or decrypts data using AES.
ATan2Returns the arc tangent of y/x, using the signs of both values to determine the quadrant.
Base64DecodeDecodes Base64 text into a Buffer.
Base64EncodeEncodes binary data as Base64 text.
ClipCursorConfines the mouse cursor to a region of the screen, or releases it.
CollectRuns a garbage collection.
CopyImageToClipboardPlaces an image on the clipboard.
CoshReturns the hyperbolic cosine.
CRC32Returns the CRC32 checksum of a value.
FileCreateTempCreates a uniquely named temporary file.
FileDirNameReturns the directory portion of a path.
FileFullPathExpands a path to its absolute form.
FormatCsFormats a string using .NET composite formatting.
GetKeyboardLayoutReturns the keyboard layout of a window or thread.
GetKeyInfoReturns the characters a key produces under a keyboard layout.
IsClipboardEmptyReturns 1 if the clipboard holds no data.
JoinConcatenates values with a separator.
LockRunRuns a program while holding a named lock, preventing concurrent runs.
MailSends an email message over SMTP.
MD5Returns the MD5 digest of a value.
MonitorFromPointReturns the monitor containing a screen point.
MonitorGetScaleReturns the DPI scale factor of a monitor.
NormalizeEolConverts line endings in a string to a single form.
OutputDebugLineWrites a line to the system debug output.
ParseScriptParses source code and returns its syntax tree.
RandomSeedSeeds the pseudo-random number generator.
RegExMatchCsMatches a .NET regular expression.
RegExReplaceCsReplaces text using a .NET regular expression.
RequestCapabilitiesRequests optional platform capabilities the script needs.
RunScriptCompiles and runs source code, returning a process object.
SecureRandomReturns a cryptographically secure random number.
SHA1Returns the SHA-1 digest of a value.
SHA256Returns the SHA-256 digest of a value.
SHA384Returns the SHA-384 digest of a value.
SHA512Returns the SHA-512 digest of a value.
ShowDebugShows or hides the debug output window.
SinhReturns the hyperbolic sine.
TanhReturns the hyperbolic tangent.
WinFromPointReturns the window at a screen point.
WinMaximizeAllMaximizes all windows.

Variables

The KS module's built-in variables cover thread identity, millisecond timestamps, screen metrics, hotstring defaults and directive state. They are listed with descriptions under KS Module Variables.

AHK Module

The built-in AHK module contains every built-in class, function and variable. Each module implicitly imports it, so these names are available without any declaration and the module rarely has to be named.

Importing it explicitly is useful when a script defines its own function or class using the name of a built-in one. The built-in remains reachable through the module, which lets a script wrap a built-in rather than replace it, as in the example below.

#Import AHK
AHK.MsgBox("Shown by the built-in MsgBox.")

Because the AHK module forwards the built-in API rather than declaring its own, its exports are documented throughout this reference and not listed here. Built-in (A_) variables are the exception to shadowing: their names cannot be reused, so they never need to be reached through the module.

Execution

The body of each module is executed at program startup, by the auto-execute thread. Execution begins with the module which was defined or loaded last. If the module has no imports, the second-last module is executed next, and so on, until all modules have executed.

[v2.1-alpha.21+]: If a module has not begun execution by the time one of its variables or constants is referenced, the module is executed immediately. The #Import directive itself has no effect on the order. For example:

#module A
MsgBox "A executing"  ; Shown second.
global ANSWER := 42

#module B
#import A {ANSWER}
MsgBox "B executing"  ; Shown first.
MsgBox ANSWER         ; Shown third.

[v2.1-alpha.20] and earlier: Each module executes its imported modules before its own body, excluding modules which have already begun execution. This doesn't work well when modules have circular dependencies.

Search Path [v2.1-alpha.20+]

The module search path is a list of directories which the #Import statement looks in to find module files. The directory of the file which contains the #Import directive is always searched first. The AhkImportPath environment variable can contain a semicolon-delimited list of additional directories to search. If it is not defined, the default list is as follows:

%A_ScriptDir%;%A_MyDocuments%\AutoHotkey;%A_AhkPath%\..

Built-in variables may be used in the value of AhkImportPath by enclosing them in percent signs. Any percent signs which are not part of a valid variable reference are interpreted literally. References to environment variables are not resolved by AutoHotkey, as they are typically resolved before the process starts. List items can be absolute paths or relative to the directory containing the script (A_ScriptDir). The list is resolved only once, so A_LineFile always refers to the main script.

Directories are searched in the order they are listed. Within each directory, files are considered in this order:

For example, #Import M may load the file with exact name M, M\__Init.ahk or M.ahk. #Import "M" is the same except that the name M is not added to the current module.

Examples

Each module has its own global variables (MyVar and ShowVar).

import Other as Other  ; This works with v2.1-alpha.19 and v2.1-alpha.20.
;#Import Other         ; This requires v2.1-alpha.20+.
;import Other {}       ; This would make Other accessible only in v2.1-alpha.20+.
MyVar := 1
      ShowVar()  ; Our MyVar is 1.
Other.ShowVar()  ; Other MyVar is still 2.
MsgBox "Within main, Other.MyVar = " (Other.MyVar ?? "inaccessible")  ; MyVar is accessible in v2.1-alpha.19+.
ShowVar() => MsgBox("Main MyVar = " MyVar)

#Module Other
MyVar := 2
export ShowVar() => MsgBox("Other MyVar = " MyVar)

Use an alias to resolve a conflict. Each module has its own Calculate, which takes precedence over any wildcard import.

import {Calculate as CalculateX} from X
import * from Y

MyVar := 1
MsgBox Calculate()
MsgBox CalculateX()
MsgBox Check(3)
MsgBox "X = " (X ?? "not imported")
MsgBox "Y = " (Y ?? "not imported")

Calculate() => 1

#Module X
export Calculate() => 2

#Module Y
export Calculate() => 3
export Check(n) => n = Calculate()

Access shadowed built-in functions.

#import AHK

MsgBox "Hello, world!",, "T2"

; Add the Info icon by default.
MsgBox(Text?, Title?, Options:="") {
    return AHK.MsgBox(Text?, Title?, "Iconi " Options)
}

#Module Other
MsgBox "Other still has the original MsgBox.",, "T2"