└── docs ├── 404.htm ├── AHKL_DBGPClients.htm ├── ChangeLog.htm ├── Compat.htm ├── Concepts.htm ├── FAQ.htm ├── Functions.htm ├── HotkeyFeatures.htm ├── Hotkeys.htm ├── Hotstrings.htm ├── KeyList.htm ├── Language.htm ├── ObjList.htm ├── Objects.htm ├── Program.htm ├── Scripts.htm ├── Tutorial.htm ├── Variables.htm ├── howto ├── Install.htm ├── ManageWindows.htm ├── RunExamples.htm ├── RunPrograms.htm ├── SendKeys.htm └── WriteHotkeys.htm ├── index.htm ├── lib ├── A_Clipboard.htm ├── A_HotkeyModifierTimeout.htm ├── A_MaxHotkeysPerInterval.htm ├── A_MenuMaskKey.htm ├── Any.htm ├── Array.htm ├── Block.htm ├── BlockInput.htm ├── Break.htm ├── Buffer.htm ├── CallbackCreate.htm ├── CaretGetPos.htm ├── Catch.htm ├── Chr.htm ├── Class.htm ├── Click.htm ├── ClipWait.htm ├── ClipboardAll.htm ├── ComCall.htm ├── ComObjActive.htm ├── ComObjArray.htm ├── ComObjConnect.htm ├── ComObjFlags.htm ├── ComObjFromPtr.htm ├── ComObjGet.htm ├── ComObjQuery.htm ├── ComObjType.htm ├── ComObjValue.htm ├── ComObject.htm ├── ComValue.htm ├── Continue.htm ├── Control.htm ├── ControlAddItem.htm ├── ControlChooseIndex.htm ├── ControlChooseString.htm ├── ControlClick.htm ├── ControlDeleteItem.htm ├── ControlFindItem.htm ├── ControlFocus.htm ├── ControlGetChecked.htm ├── ControlGetChoice.htm ├── ControlGetClassNN.htm ├── ControlGetEnabled.htm ├── ControlGetFocus.htm ├── ControlGetHwnd.htm ├── ControlGetIndex.htm ├── ControlGetItems.htm ├── ControlGetPos.htm ├── ControlGetStyle.htm ├── ControlGetText.htm ├── ControlGetVisible.htm ├── ControlHide.htm ├── ControlHideDropDown.htm ├── ControlMove.htm ├── ControlSend.htm ├── ControlSetChecked.htm ├── ControlSetEnabled.htm ├── ControlSetStyle.htm ├── ControlSetText.htm ├── ControlShow.htm ├── ControlShowDropDown.htm ├── CoordMode.htm ├── Critical.htm ├── DateAdd.htm ├── DateDiff.htm ├── DetectHiddenText.htm ├── DetectHiddenWindows.htm ├── DirCopy.htm ├── DirCreate.htm ├── DirDelete.htm ├── DirExist.htm ├── DirMove.htm ├── DirSelect.htm ├── DllCall.htm ├── Download.htm ├── Drive.htm ├── DriveEject.htm ├── DriveGetCapacity.htm ├── DriveGetFileSystem.htm ├── DriveGetLabel.htm ├── DriveGetList.htm ├── DriveGetSerial.htm ├── DriveGetSpaceFree.htm ├── DriveGetStatus.htm ├── DriveGetStatusCD.htm ├── DriveGetType.htm ├── DriveLock.htm ├── DriveSetLabel.htm ├── DriveUnlock.htm ├── Edit.htm ├── EditGetCurrentCol.htm ├── EditGetCurrentLine.htm ├── EditGetLine.htm ├── EditGetLineCount.htm ├── EditGetSelectedText.htm ├── EditPaste.htm ├── Else.htm ├── Enumerator.htm ├── EnvGet.htm ├── EnvSet.htm ├── Error.htm ├── Exit.htm ├── ExitApp.htm ├── File.htm ├── FileAppend.htm ├── FileCopy.htm ├── FileCreateShortcut.htm ├── FileDelete.htm ├── FileEncoding.htm ├── FileExist.htm ├── FileGetAttrib.htm ├── FileGetShortcut.htm ├── FileGetSize.htm ├── FileGetTime.htm ├── FileGetVersion.htm ├── FileInstall.htm ├── FileMove.htm ├── FileOpen.htm ├── FileRead.htm ├── FileRecycle.htm ├── FileRecycleEmpty.htm ├── FileSelect.htm ├── FileSetAttrib.htm ├── FileSetTime.htm ├── Finally.htm ├── Float.htm ├── For.htm ├── Format.htm ├── FormatTime.htm ├── Func.htm ├── GetKeyName.htm ├── GetKeySC.htm ├── GetKeyState.htm ├── GetKeyVK.htm ├── GetMethod.htm ├── Goto.htm ├── GroupActivate.htm ├── GroupAdd.htm ├── GroupClose.htm ├── GroupDeactivate.htm ├── Gui.htm ├── GuiControl.htm ├── GuiControls.htm ├── GuiCtrlFromHwnd.htm ├── GuiFromHwnd.htm ├── GuiOnCommand.htm ├── GuiOnEvent.htm ├── GuiOnNotify.htm ├── HasBase.htm ├── HasMethod.htm ├── HasProp.htm ├── HotIf.htm ├── Hotkey.htm ├── Hotstring.htm ├── If.htm ├── ImageSearch.htm ├── InStr.htm ├── IniDelete.htm ├── IniRead.htm ├── IniWrite.htm ├── InputBox.htm ├── InputHook.htm ├── InstallKeybdHook.htm ├── InstallMouseHook.htm ├── Integer.htm ├── Is.htm ├── IsLabel.htm ├── IsObject.htm ├── IsSet.htm ├── KeyHistory.htm ├── KeyWait.htm ├── ListHotkeys.htm ├── ListLines.htm ├── ListVars.htm ├── ListView.htm ├── ListViewGetContent.htm ├── LoadPicture.htm ├── Loop.htm ├── LoopFiles.htm ├── LoopParse.htm ├── LoopRead.htm ├── LoopReg.htm ├── Map.htm ├── Math.htm ├── Menu.htm ├── MenuFromHandle.htm ├── MenuSelect.htm ├── Monitor.htm ├── MonitorGet.htm ├── MonitorGetCount.htm ├── MonitorGetName.htm ├── MonitorGetPrimary.htm ├── MonitorGetWorkArea.htm ├── MouseClick.htm ├── MouseClickDrag.htm ├── MouseGetPos.htm ├── MouseMove.htm ├── MsgBox.htm ├── NumGet.htm ├── NumPut.htm ├── Number.htm ├── ObjAddRef.htm ├── ObjBindMethod.htm ├── Object.htm ├── OnClipboardChange.htm ├── OnError.htm ├── OnExit.htm ├── OnMessage.htm ├── Ord.htm ├── OutputDebug.htm ├── Pause.htm ├── Persistent.htm ├── PixelGetColor.htm ├── PixelSearch.htm ├── PostMessage.htm ├── Process.htm ├── ProcessClose.htm ├── ProcessExist.htm ├── ProcessGetName.htm ├── ProcessGetParent.htm ├── ProcessSetPriority.htm ├── ProcessWait.htm ├── ProcessWaitClose.htm ├── Random.htm ├── RegCreateKey.htm ├── RegDelete.htm ├── RegDeleteKey.htm ├── RegExMatch.htm ├── RegExReplace.htm ├── RegRead.htm ├── RegWrite.htm ├── Reload.htm ├── Return.htm ├── Run.htm ├── RunAs.htm ├── Send.htm ├── SendLevel.htm ├── SendMessage.htm ├── SendMode.htm ├── SetControlDelay.htm ├── SetDefaultMouseSpeed.htm ├── SetKeyDelay.htm ├── SetMouseDelay.htm ├── SetNumScrollCapsLockState.htm ├── SetRegView.htm ├── SetStoreCapsLockMode.htm ├── SetTimer.htm ├── SetTitleMatchMode.htm ├── SetWinDelay.htm ├── SetWorkingDir.htm ├── Shutdown.htm ├── Sleep.htm ├── Sort.htm ├── Sound.htm ├── SoundBeep.htm ├── SoundGetInterface.htm ├── SoundGetMute.htm ├── SoundGetName.htm ├── SoundGetVolume.htm ├── SoundPlay.htm ├── SoundSetMute.htm ├── SoundSetVolume.htm ├── SplitPath.htm ├── StatusBarGetText.htm ├── StatusBarWait.htm ├── StrCompare.htm ├── StrGet.htm ├── StrLen.htm ├── StrLower.htm ├── StrPtr.htm ├── StrPut.htm ├── StrReplace.htm ├── StrSplit.htm ├── String.htm ├── SubStr.htm ├── Suspend.htm ├── Switch.htm ├── SysGet.htm ├── SysGetIPAddresses.htm ├── Thread.htm ├── Throw.htm ├── ToolTip.htm ├── TraySetIcon.htm ├── TrayTip.htm ├── TreeView.htm ├── Trim.htm ├── Try.htm ├── Type.htm ├── Until.htm ├── VarSetStrCapacity.htm ├── VerCompare.htm ├── While.htm ├── Win.htm ├── WinActivate.htm ├── WinActivateBottom.htm ├── WinActive.htm ├── WinClose.htm ├── WinExist.htm ├── WinGetClass.htm ├── WinGetClientPos.htm ├── WinGetControls.htm ├── WinGetControlsHwnd.htm ├── WinGetCount.htm ├── WinGetID.htm ├── WinGetIDLast.htm ├── WinGetList.htm ├── WinGetMinMax.htm ├── WinGetPID.htm ├── WinGetPos.htm ├── WinGetProcessName.htm ├── WinGetProcessPath.htm ├── WinGetStyle.htm ├── WinGetText.htm ├── WinGetTitle.htm ├── WinGetTransColor.htm ├── WinGetTransparent.htm ├── WinHide.htm ├── WinKill.htm ├── WinMaximize.htm ├── WinMinimize.htm ├── WinMinimizeAll.htm ├── WinMove.htm ├── WinMoveBottom.htm ├── WinMoveTop.htm ├── WinRedraw.htm ├── WinRestore.htm ├── WinSetAlwaysOnTop.htm ├── WinSetEnabled.htm ├── WinSetRegion.htm ├── WinSetStyle.htm ├── WinSetTitle.htm ├── WinSetTransColor.htm ├── WinSetTransparent.htm ├── WinShow.htm ├── WinWait.htm ├── WinWaitActive.htm ├── WinWaitClose.htm ├── _ClipboardTimeout.htm ├── _DllLoad.htm ├── _ErrorStdOut.htm ├── _HotIf.htm ├── _HotIfTimeout.htm ├── _Hotstring.htm ├── _Include.htm ├── _InputLevel.htm ├── _MaxThreads.htm ├── _MaxThreadsBuffer.htm ├── _MaxThreadsPerHotkey.htm ├── _NoTrayIcon.htm ├── _Requires.htm ├── _SingleInstance.htm ├── _SuspendExempt.htm ├── _UseHook.htm ├── _Warn.htm ├── _WinActivateForce.htm └── index.htm ├── license.htm ├── misc ├── Acknowledgements.htm ├── Ahk2ExeDirectives.htm ├── CLSID-List.htm ├── Colors.htm ├── DPIScaling.htm ├── Editors.htm ├── EscapeChar.htm ├── FontsStandard.htm ├── Functor.htm ├── ImageHandles.htm ├── Labels.htm ├── Languages.htm ├── LongPaths.htm ├── Macros.htm ├── Override.htm ├── Performance.htm ├── RegEx-QuickRef.htm ├── RegExCallout.htm ├── Remap.htm ├── RemapController.htm ├── SendMessage.htm ├── SendMessageList.htm ├── Styles.htm ├── Threads.htm ├── WinTitle.htm ├── Winamp.htm └── remove-userchoice.reg ├── scripts ├── ContextSensitiveHelp.ahk ├── ControllerMouse.ahk ├── ControllerTest.ahk ├── EasyWindowDrag.ahk ├── EasyWindowDrag_(KDE).ahk ├── EncodeHTML.ahk ├── FavoriteFolders.ahk ├── KeyboardOnScreen.ahk ├── MinimizeToTrayMenu.ahk ├── MsgBoxButtonNames.ahk ├── Numpad000.ahk ├── NumpadMouse.ahk ├── Seek_(SearchTheStartMenu).ahk ├── TooltipMouseMenu.ahk ├── UpDownCustomIncrements.ahk ├── VolumeOSD.ahk ├── WinLIRC.ahk ├── WindowShading.ahk └── index.htm ├── search.htm ├── settings.htm ├── static ├── ahk16.png ├── ahk16_pause.png ├── ahk16_pause_suspend.png ├── ahk16_suspend.png ├── ahk_logo.png ├── ahk_logo.svg ├── ahk_logo_no_text.png ├── ahkfile16.png ├── content.css ├── content.js ├── ctrl_button.png ├── ctrl_check.png ├── ctrl_combo.png ├── ctrl_datetime.png ├── ctrl_ddl.png ├── ctrl_edit.png ├── ctrl_group.png ├── ctrl_hotkey.png ├── ctrl_link.png ├── ctrl_list.png ├── ctrl_listview.png ├── ctrl_menu.png ├── ctrl_monthcal.png ├── ctrl_progress.png ├── ctrl_radio.png ├── ctrl_slider.png ├── ctrl_status.png ├── ctrl_tab.png ├── ctrl_text.png ├── ctrl_treeview.png ├── ctrl_updown.png ├── dark.css ├── dlg_file.png ├── dlg_folder.png ├── dlg_input.png ├── dlg_message.png ├── dlg_tooltip.png ├── dlg_traytip.png ├── fonts │ ├── icons.eot │ ├── icons.svg │ ├── icons.ttf │ └── icons.woff ├── highlighter │ ├── dark.css │ ├── highlighter.css │ ├── highlighter.js │ └── light.css ├── sound_levels.png ├── source │ ├── build_search.ahk │ ├── check_data.ahk │ ├── data_deprecate.js │ ├── data_index.js │ ├── data_search.js │ ├── data_toc.js │ └── data_translate.js └── theme.css ├── v1-changes.htm └── v2-changes.htm /docs/404.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

404 - File not found

15 |

Looks like the document you're looking for doesn't exist.

16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/AHKL_DBGPClients.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debugging Clients | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Debugging Clients

14 | 15 |

Additional debugging features are supported via DBGp, a common debugger protocol for languages and debugger UI communication. See Interactive Debugging for more details. Some UIs or "clients" known to be compatible with AutoHotkey are listed on this page:

16 | 24 | 25 |

SciTE4AutoHotkey

26 |

SciTE4AutoHotkey is a free, SciTE-based AutoHotkey script editor. In addition to DBGp support, it provides syntax highlighting, calltips/parameter info and auto-complete for AutoHotkey, and other useful editing features and scripting tools.

27 |

Debugging features include:

28 | 37 |

https://www.autohotkey.com/scite4ahk/

38 | 39 |

Visual Studio Code

40 |

The vscode-autohotkey-debug extension enables Visual Studio Code to act as a debugger client for AutoHotkey. The extension has support for all basic debugging features as well as some more advanced features, such as breakpoint directives (as comments) and conditional breakpoints.

41 | 42 |

XDebugClient

43 |

XDebugClient is a simple open-source front-end DBGp client based on the .NET Framework 2.0. XDebugClient was originally designed for PHP with Xdebug, but a custom build compatible with AutoHotkey is available below.

44 |

Changes:

45 | 51 |

Download: Binary; Source Code (also see SharpDevelop, Dockpanel Suite and Advanced TreeView.)

52 |

Usage:

53 | 60 |

Features:

61 | 68 |

Issues:

69 | 73 | 74 |

Notepad++ DBGp Plugin

75 |

A DBGp client is available as a plugin for Notepad++ 32-bit. It is designed for PHP, but also works with AutoHotkey. The plugin has not been updated since 2012, and is not available for Notepad++ 64-bit.

76 |

Download: See DBGp plugin for Notepad++.

77 |

Usage:

78 | 89 |

Features:

90 | 100 |

Issues:

101 | 106 | 107 |

Script-based Clients

108 |

A script-based DBGp library and example clients are available from GitHub.

113 |

GitHub: Lexikos / dbgp

114 |

The DebugVars script provides a graphical user interface for inspecting and changing the contents of variables and objects in any running script (except compiled scripts). It also serves as a demonstration of the dbgp.ahk library.

115 |

GitHub: Lexikos / DebugVars

116 | 117 |

Command-line Client

118 |

A command-line client is available from xdebug.org, however this is not suitable for most users as it requires a decent understanding of DBGp (the protocol).

119 | 120 |

Others

121 |

A number of other DBGp clients are available, but have not been tested with AutoHotkey. For a list, see Xdebug: Documentation.

122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/ChangeLog.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Changes & New Features | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Changes & New Features

14 |

Changes from v1.1 to v2.0 covers the differences between v1.1 and v2.0.

15 |

For full technical details of changes, refer to GitHub.

16 | 17 |

2.0.19 - January 25, 2025

18 |

Fixed memory out-of-bounds access during RegEx compilation.

19 |

Fixed externally-released modifiers to not be "restored" post-Send.

20 |

Fixed modal dialog boxes suppressing InputHook events.

21 |

Fixed key-up erroneously being suppressed after key-repeat presses it down in some cases.

22 |

Fixed Critical Error when loading large icons with no alpha channel.

23 |

Fixed MouseGetPos to make Control blank and not throw if ClassNN cannot be determined.

24 |

Fixed FileSelect to validate Options.

25 |

Fixed unexpected Catch/Else/Finally/Until not being flagged as an error in some cases.

26 |

Fixed Try/Catch/Else/Finally not executing Finally if Else returns.

27 |

Fixed execution of if-else-if-else-if containing fat arrow functions.

28 | 29 |

2.0.18 - July 6, 2024

30 |

Fixed A_Clipboard silently exiting when GetClipboardData returns NULL.

31 |

Fixed a.b[c] := d to invoke the getter for a.b if there is no setter.

32 | 33 |

2.0.17 - June 5, 2024

34 |

Implemented an optimization to the WinText parameter by Descolada. [PR #335]

35 |

Changed UnsetError message to suggest a global declaration instead of appending "(same name as a global)" after the variable name.

36 |

Changed VarUnset warning message for consistency with UnsetError.

37 |

Fixed the increment/decrement operators to throw UnsetError if the var is unset, not TypeError.

38 |

Fixed OwnProps to assign the property name safely in cases where a property deletes itself.

39 |

Fixed breakpoints to work in arrow functions under a control flow statement without a block.

40 |

Fixed debugger to break at the line of the call when stepping out of a function. (This behaviour was added in Revision 31 and broken by v1.1.30.00.)

41 |

Stepping out of a function which was called as a new thread now breaks at the line which was interrupted, instead of waiting until the next line is reached.

42 |

Fixed debugger to not delete temporary breakpoints which are ignored while evaluating DBGp property_get or context_get.

43 | 44 |

2.0.16 - May 30, 2024

45 |

Fixed load-time errors sent to stdout showing incorrect file/line number in some cases.

46 |

Fixed ExitApp on load-time error/warning dialogs to use exit code 2.

47 |

Fixed locating WindowSpy.ahk in Current User (non-admin) installs.

48 |

Fixed DBGp property_get paging items incorrectly (again).

49 |

Fixed StrPut failing if Length/Buffer is specified and MultiByteToWideChar doesn't support the WC_NO_BEST_FIT_CHARS flag for the target codepage.

50 |

Fixed Download to attempt anonymous authentication if the server requests client authentication.

51 | 52 |

2.0.15 - May 16, 2024

53 |

Fixed DBGp property_get failing to retrieve properties due to incorrect paging (since v2.0.14).

54 |

Fixed DBGp property evaluation causing Try without Catch to fail (since v2.0.14).

55 |

Fixed <base> debugger pseudo-property leaking a reference (since v2.0.14).

56 | 57 |

2.0.14 - May 6, 2024

58 |

Fixed the error dialog to handle letter key shortcuts even when text is focused.

59 |

Fixed MonthCal W-n (number of month) width values to not be affected by DPI scaling.

60 |

Fixed Click to not return an integer.

61 |

Fixed detection of key::try { as an error.

62 |

Fixed :B0*O:XY::Z to produce XYZ rather than XZ (suppressing Y).

63 |

Fixed Send to leave any prior {modifier Down} in effect even if the key happens to be physically held down.

64 |

Improved the reliability of the script taking focus when a menu popup is shown.

65 | 66 |

Debugger improvements:

67 |

Fixed stdout/stderr packets sent during the processing of another command to not corrupt the pending response.

68 |

Fixed property_get -n <exception>.message and similar.

69 |

Fixed corrupted results from property_get when a property returns a temporary object with a string, such as x.y.z where y => {z:"a"}.

70 |

Fixed crashes when an asynchronous command is received during the processing of another command.

71 |

Fixed exceptions not being deleted after they are suppressed via property_set.

72 |

Fixed property_get -c 0 -d 0 to allow global variables, as already allowed by -d 1.

73 |

Fixed property_get paging enumerated items incorrectly.

74 | 75 |

Improved property_get to support property getters with one parameter (previously only the implicit __Item property supported this).

76 |

Improved property_get to support properties of primitive values. The value must still be contained by a variable or returned from a property.

77 |

Improved property_get to allow calling functions with <=1 parameter.

78 |

Improved property_get to support float keys/parameters.

79 | 80 |

Changed debugger to suppress exceptions during property evaluation.

81 |

Changed debugger to ignore errors thrown by __Enum (treat as no items).

82 |

Changed the <enum> pseudo-property to require __Enum. This prevents the object itself from being called as an enumerator.

83 |

Small code size optimizations in the debugger.

84 | 85 |

2.0.13 - April 20, 2024

86 |

Changed Hotkey function to throw ValueError if Options contains an invalid option.

87 |

Fixed InputHook to respect the +S option for Backspace when acting as undo.

88 |

Fixed debugger to safely handle property deletion during enumeration.

89 |

Fixed OLE clipboard content (e.g. error dialog text) being lost on exit.

90 |

Fixed detection of invalid suffix on a hotkey, such as Hotkey "a pu".

91 |

Fixed DllCall AStr* arg type to copy back only if address changes.

92 |

Fixed #Include to correctly "close" any built-in variable it reads (no known impact on real-world scripts).

93 |

Fixed WinTitles with two different ahk_id values to yield no match.

94 | 95 |

2.0.12 - March 23, 2024

96 |

Fixed Gui GetPos/GetClientPos when Gui has an owner window or +DPIScale.

97 |

Fixed Until preventing subfolder recursion in file loops.

98 |

Fixed DllCall to throw when arg type is UStr.

99 |

Fixed a memory leak occurring for each regex callout.

100 |

Fixed Send erroneously releasing a modifier due to a race condition. For example, ~LAlt::Send "{Blind}x" intermittently released LAlt if some other keyboard hook was installed more recently than the script's own hook.

101 |

Fixed icon loader to prefer higher bit-depth when multiple bitmaps of the same size are present.

102 |

Fixed SendInput failing to release LCtrl if it had already released RAlt and the layout does not have AltGr.

103 |

Fixed key-up hotkeys not firing if the key repeats after modifiers change. For example, F1::Send "{Ctrl down}" should allow F1 up:: to execute when the key is released even though Ctrl is down, but was not allowing it after key-repeat occurs.

104 |

Fixed an error message to refer to #HotIf rather than #IfWin. [PR #327]

105 |

Fixed OwnProps erroneously skipping properties with optional parameters.

106 |

Fixed inconsistent behaviour of cloned dynamic properties.

107 | 111 |

Fixed SysGetIPAddresses causing a Critical Error when the network subsystem is non-functional; e.g. in Windows safe mode.

112 |

Changed ControlGetFocus to return 0 when focus can't be determined, such as when a console window is active.

113 | 114 |

2.0.11 - December 23, 2023

115 |

Added a workaround for the first shown menu not accepting keyboard input on Windows 10.

116 |

Fixed the Add method (Gui) to support the ShortDate option for DateTime controls.

117 |

Fixed a reference counting error with multi-level function nesting.

118 |

Fixed #include <x> causing a load-time crash if used inside a function.

119 |

Fixed ListView.Opt("NoSort").

120 |

Fixed a memory leak occurring when an object with no own properties is cloned.

121 |

Fixed #include and FileInstall (non-compiled) to compare file names ordinally, not linguistically.

122 | 123 |

2.0.10 - September 24, 2023

124 |

Fixed crashing when a named function hotkey is used after #HotIf.

125 |

Fixed numeric literals ending with a dot to not cause line continuation.

126 |

Fixed pre-increment/decrement to work with chained array indexing.

127 |

Fixed OnNotify/OnCommand applying styles only applicable to OnEvent.

128 |

Fixed FileExist/DirExist leaking handles when emptydir\* is used.

129 |

Fixed DirExist leaking handles when only files match.

130 | 131 |

2.0.9 - September 17, 2023

132 |

Fixed stacking of hotstrings with the X option.

133 |

Fixed debugger not listing local vars if the function is at the bottom of the stack.

134 |

Fixed Gui threads to show on the debugger's call stack.

135 |

Fixed some combinations of &/ByRef causing stack overflow in ExitApp.

136 | 137 |

2.0.8 - September 11, 2023

138 |

Fixed ByRef parameters erroneously assigning the default value to the caller's VarRef if unset.

139 |

Fixed some issues affecting suppressed Alt/Ctrl/Shift/Win hotkeys, such as:

140 | 145 |

Fixed some issues affecting continuation sections:

146 | 150 |

Optimized the automatic escaping of quote marks and backtick in continuation sections.

151 |

Fixed breakpoint_list (debugger) returning duplicates on lines containing fat arrow functions.

152 |

Fixed +BackgroundDefault failing to override the Gui's BackColor property.

153 | 154 |

2.0.7 - September 2, 2023

155 |

Fixed MouseClickDrag to allow X1 and Y1 to be omitted.

156 |

Fixed mouse AltTab hotkeys not suppressing execution of a prefix hotkey, such as 1:: for 1 & WheelDown::AltTab. (Broken by v2.0.4)

157 |

Fixed hook hotkeys not recognizing modifiers which are pressed down by SendInput.

158 |

Fixed A_AhkPath to not be reliant on the case/format of the command line used to launch the process.

159 |

Fixed heap corruption during window searches involving groups. (Broken by v2.0.6)

160 |

Launcher

161 |

Fixed #Requires not being detected if followed by a comment other than ; prefer xxx. (Broken by v2.0.6)

162 |

Fixed syntax detection misinterpreting multi-line auto-replace hotstrings.

163 |

Window Spy

164 |

Changed font to Segoe UI size 9, consistent with Dash.

165 | 166 |

2.0.6 - August 30, 2023

167 |

Fixed some ambiguity with COM calls, such as x.y acting as x.y().

168 |

Fixed breakpoint on control flow statement being "hit" when a fat arrow function on the line below it returns.

169 |

Fixed Default : to not merge with the line below it. This prevented Default : from being used at the end of a Switch block, and caused any subsequent line to take the line number of the Default.

170 |

Optimized ProcessGetPath, ProcessSetPriority and ProcessClose to not scan through all processes when given a valid PID, even if access to the process is denied.

171 |

Fixed inability of LWin::Alt to be used to activate some Alt key combos.

172 |

Fixed TypeError thrown by x is y to say "Class" rather than "Object".

173 |

Fixed WinTitle to support criteria longer than 1023 characters.

174 |

Fixed issues when &ref is used on different aliases of the same variable.

175 |

Fixed optional parameter default expressions (other than simple literal values) preventing the use of assume-global/assume-static.

176 | 177 |

2.0.5 - August 12, 2023

178 |

Fixed a memory leak caused by incorrect reference counting when an object is enumerated via COM. [PR# 325]

179 |

Fixed internal calls to __Enum to not call __Call.

180 |

Fixed error messages referring to parameter #65535.

181 |

Fixed incorrect IEnumVARIANT return count.

182 |

Fixed Download throwing OSError(0) when error should be non-zero.

183 |

Fixed LV.Add/Insert/Modify crashing when passed the minimum number of parameters.

184 |

Fixed stack traces to exclude calls to __new for Error subclasses.

185 | 186 |

2.0.4 - July 3, 2023

187 |

Changed the Reload button on error/warning dialogs to explicitly close the dialog, even if the current script instance isn't terminated.

188 |

Removed an optimization for return var which caused the variable to appear blank when accessed within a finally block.

189 |

Fixed Default (Switch) to allow space before the colon.

190 |

Fixed Array.Prototype.RemoveAt to return the removed value when Length is "explicitly omitted" with unset or var?.

191 |

Fixed crashing when a ComObject is passed to a for-loop with only the second variable specified.

192 |

Changes merged from v1.1.37.00 and v1.1.37.01:

193 |

Changed COM method and property calls to pass large integers as VT_I8, not VT_R8 (floating-point), so the original type and precision is retained. Integers in the 32-bit range are still passed as VT_I4.

194 |

Added support for multi-variable enumerators (for-loops) with IDispatch-wrapped AutoHotkey objects. Both the script invoking the object and the object itself must be running a supported AutoHotkey version.

195 |

Fixed omitted parameters to receive their default values rather than the "optional argument marker" when an AutoHotkey method is called via IDispatch (COM). The reverse translation was already done when calling COM methods in previous versions.

196 |

Fixed VerCompare(a, ">" b) and reduced code size marginally.

197 |

Fixed AltTab-related load-time errors to be consistent with other errors.

198 |

Fixed errors thrown by a ComObject wrapper not being propagated correctly if it is called via an object/COM.

199 |

Fixed the Hotkey GUI control to allow setting the symbols ^, ! and + as hotkeys.

200 |

Fixed the Hotkey control to include modifiers when its value is set to a symbol.

201 |

Fixed potential misbehaviour of InputHook.KeyOpt() with single chars.

202 | 206 |

Fixed a bug with custom combos where a set of hotkeys like a & b::, a:: and a up:: would fail to suppress the release of a if a:: alone is disabled with #HotIf.

207 |

Fixed a bug where a key-down event is correctly suppressed by a hotkey, but sending an additional key-down with SendLevel > 0 would prevent the subsequent key-up from being suppressed, even if the sent event is ignored due to #InputLevel.

208 |

Fixed a & b up:: not suppressing b if a & b:: is present but disabled by #HotIf.

209 |

Fixed an issue with hotkeys not firing due to a race condition. If a modifier hotkey such as ~*RWin:: called Send or GetKeyState too soon, the OS could report that RWin isn't down, so the hook's modifier state would be "corrected" and hotkeys would wrongly fire or fail to fire. This was likely to occur only if another keyboard hook was installed more recently than the script's own hook, since in that case the OS would not update key state until the other hook's thread has resumed and returned.

210 |

Fixed hotstrings to use the Last Found Window set by #HotIf.

211 |

Fixed an issue where any attempt to reinstall the keyboard or mouse hook would fail if the OS had automatically uninstalled the hook. It is still necessary to meet certain conditions before any such attempt can be made.

212 |

Optimized allocation of cached COM property names for built-in IDispatch.

213 |

Refactored code to support a build configuration for AutoHotkey as a DLL.

214 | 215 |

2.0.3 - June 19, 2023

216 |

Fixed Hotkey("a", "b") to use the original function of "b", not "a". [PR #318]

217 |

Fixed FileSetAttribute crash when used in a File Reading Loop. [PR #323]

218 |

Fixed duplicate Gui control name errors to correctly abort the thread.

219 |

Fixed DateTime/MonthCal Range option not applying minimum value.

220 |

Fixed s[x] => x and other single-line properties starting with "s".

221 |

Fixed a bug with deleting a breakpoint on a static line containing =>.

222 |

Fixed Button control not becoming default when clicked.

223 |

Fixed PixelSearch to unset X when pixel is not found.

224 |

Fixed hotstring with escape sequence causing next line to be skipped.

225 |

Fixed WinTitle ignoring character 1 when "ahk_" is at character 2.

226 |

Fixed remapping to utilize right-hand modifier already being down. For example, +x::+y will no longer release RShift to press LShift.

227 |

Changed error message for a == b && c() and similar cases to avoid alluding to legacy =.

228 |

Improved error message for some cases of unintended line continuation.

229 |

Fixed reserved words to be permitted as method names, as documented.

230 |

Fixed duplicate OnMessage calls for some keyboard messages.

231 |

Fixed inter-referenced closures being deleted prematurely.

232 |

Fixed SetFont to permit leading spaces in the Options parameter.

233 |

Fixed sending of {ASC nnnn}.

234 |

Fixed a.base := a to throw an error.

235 |

Fixed x.y := unset causing crashes or undefined behaviour.

236 |

Fixed GuiControl.Move() to be relative to the GUI's client area even when the GUI is not its parent.

237 |

Fixed Menu Add overwriting items which were appended by Menu Insert.

238 | Launcher 239 |

Run Dash instead of showing the old Welcome page in the documentation, when run without parameters.

240 |

Fixed version selection GUI raising an error if Enter is pressed without selecting a version. [PR UX/#4]

241 |

Suppress errors when checking whether an absent version can be downloaded.

242 |

Fixed absent version download prompt to not show the UAC shield if UAC is disabled.

243 |

Fixed issues with #Requires interpretation.

244 | 249 | Installation 250 |

Fixed the default installation directory for command-line use.

251 |

Renamed the Start menu shortcut from "AutoHotkey" to "AutoHotkey Dash".

252 |

Fixed EnableUIAccess when running as SYSTEM.

253 |

Fixed EnableUIAccess to verify the private key when selecting a certificate.

254 | Dash 255 |

Fixed Launch Config GUI to update the "Run as administrator" and "Run with UI access" options.

256 |

Fixed Up/Down key handling in the Launch Config GUI.

257 | 258 |

2.0.2 - January 2, 2023

259 |

Fixed Short DllCall arg type and undefined behaviour for invalid types.

260 |

Fixed (non-string) file version number for AutoHotkey binaries.

261 |

Fixed parameter type errors to show the correct parameter number.

262 | 263 |

2.0.1 - January 1, 2023

264 |

Fixed Func.IsOptional(1) returning 0 in some cases where it shouldn't.

265 |

Fixed Gui event handler functions to not drop the Gui parameter when the Gui is its own event sink.

266 |

Fixed COM errors to not show "(null)" when no description is available.

267 |

Fixed ToolTips intermittently appearing at the wrong position.

268 |

Fixed __Enum(unset) to permit a second variable for Array, Match and Gui.

269 |

Fixed #include <> error messages to show "Script library" rather than "Function library".

270 |

Fixed new threads being unable to prevent a message check with Critical.

271 |

Optimized conversion of DllCall type names.

272 |

Made some trivial but effective code size optimizations.

273 | 274 |

Pre-Release

275 |

For a history of changes prior to the v2.0.0 release, refer to the following (but note some changes were superseded):

276 | 281 | 282 | -------------------------------------------------------------------------------- /docs/Compat.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Binary Compatibility | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Binary Compatibility

14 | 15 |

This document contains some topics which are sometimes important when dealing with external libraries or sending messages to a control or window.

16 | 17 | 27 | 28 |

Unicode vs ANSI

29 |

Note: This section builds on topics covered in other parts of the documentation: Strings, String Encoding.

30 |

Within a string (text value), the numeric character code and size (in bytes) of each character depends on the encoding of the string. These details are typically important for scripts which do any of the following:

31 | 37 |

AutoHotkey v2 natively uses Unicode (UTF-16), but some external libraries or window messages might require ANSI strings.

38 |

ANSI: Each character is one byte (8 bits). Character codes above 127 depend on your system's language settings (or the codepage chosen when the text was encoded, such as when it is written to a file).

39 |

Unicode: Each character is two bytes (16 bits). Character codes are as defined by the UTF-16 format.

40 |

Semantic note: Technically, some Unicode characters are represented by two 16-bit code units, collectively known as a "surrogate pair." Similarly, some ANSI code pages (commonly known as Double Byte Character Sets) contain some double-byte characters. However, for practical reasons these are almost always treated as two individual units (referred to as "characters" for simplicity).

41 | 42 |

Buffer

43 |

When allocating a Buffer, take care to calculate the correct number of bytes for whichever encoding is required. For example:

44 |
ansi_buf  := Buffer(capacity_in_chars)
 45 | utf16_buf := Buffer(capacity_in_chars * 2)
46 |

If an ANSI or UTF-8 string will be written into the buffer with StrPut, do not use StrLen to determine the buffer size, as the ANSI or UTF-8 length may differ from the native (UTF-16) length. Instead, use StrPut to calculate the required buffer size. For example:

47 |
required_bytes := StrPut(source_string, "cp0")
 48 | ansi_buf := Buffer(required_bytes)
 49 | StrPut(source_string, ansi_buf)
50 | 51 |

DllCall

52 |

When the "Str" type is used, it means a string in the native format of the current build. Since some functions may require or return strings in a particular format, the following string types are available:

53 | 54 | 55 | 56 | 57 | 58 |
 Char SizeC / Win32 TypesEncoding
WStr16-bitwchar_t*, WCHAR*, LPWSTR, LPCWSTRUTF-16
AStr8-bitchar*, CHAR*, LPSTR, LPCSTRANSI (the system default ANSI code page)
Str--TCHAR*, LPTSTR, LPCTSTREquivalent to WStr in AutoHotkey v2.
59 |

If "Str" or "WStr" is used for a parameter, the address of the string is passed to the function. For "AStr", a temporary ANSI copy of the string is created and its address is passed instead. As a general rule, "AStr" should not be used for an output parameter since the buffer is only large enough to hold the input string.

60 |

Note: "AStr" and "WStr" are equally valid for parameters and the function's return value.

61 |

In general, if a script calls a function via DllCall which accepts a string as a parameter, one or more of the following approaches must be taken:

62 |
    63 |
  1. If both Unicode (W) and ANSI (A) versions of the function are available, omit the W or A suffix and use the "Str" type for input parameters or the return value. For example, the DeleteFile function is exported from kernel32.dll as DeleteFileA and DeleteFileW. Since DeleteFile itself doesn't really exist, DllCall automatically tries DeleteFileW: 64 |
    DllCall("DeleteFile", "Ptr", StrPtr(filename))
     65 | DllCall("DeleteFile", "Str", filename)
    66 |

    In both cases, the address of the original unmodified string is passed to the function.

    67 |

    In some cases this approach may backfire, as DllCall adds the W suffix only if no function could be found with the original name. For example, shell32.dll exports ExtractIconExW, ExtractIconExA and ExtractIconEx with no suffix, with the last two being equivalent. In that case, omitting the W suffix causes the ANSI version to be called.

  2. 68 |
  3. If the function accepts a specific type of string as input, the script may use the appropriate string type: 69 |
    DllCall("DeleteFileA", "AStr", filename)
     70 | DllCall("DeleteFileW", "WStr", filename)
  4. 71 |
  5. If the function has a string parameter used for output, the script must allocate a buffer as described above and pass it to the function. If the parameter accepts input, the script must also convert the input string to the appropriate format; StrPut can be used for this.
  6. 72 |
73 | 74 |

NumPut / NumGet

75 |

When NumPut or NumGet are used with strings, the offset and type must be correct for the given type of string. The following may be used as a guide:

76 |
;  8-bit/ANSI   strings:  size_of_char=1  type_of_char="UChar"
 77 | ; 16-bit/UTF-16 strings:  size_of_char=2  type_of_char="UShort"
 78 | nth_char := NumGet(buffer_or_address, (n-1)*size_of_char, type_of_char)
 79 | NumPut(type_of_char, nth_char, buffer_or_address, (n-1)*size_of_char)
80 |

For the first character, n should have the value 1.

81 | 82 |

Pointer Size

83 |

Pointers are 4 bytes in 32-bit builds and 8 bytes in 64-bit builds. Scripts using structures or DllCalls may need to account for this to run correctly on both platforms. Specific areas which are affected include:

84 | 89 |

For size and offset calculations, use A_PtrSize. For DllCall, NumPut and NumGet, use the Ptr type where appropriate.

90 |

Remember that the offset of a field is usually the total size of all fields preceding it. Also note that handles (including types like HWND and HBITMAP) are essentially pointer-types.

91 |
/*
 92 |   typedef struct _PROCESS_INFORMATION {
 93 |     HANDLE hProcess;    // Ptr
 94 |     HANDLE hThread;
 95 |     DWORD  dwProcessId; // UInt (4 bytes)
 96 |     DWORD  dwThreadId;
 97 |   } PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
 98 | */
 99 | pi := Buffer(A_PtrSize*2 + 8) ; Ptr + Ptr + UInt + UInt
100 | DllCall("CreateProcess", <omitted for brevity>, "Ptr", &pi, <omitted>)
101 | hProcess    := NumGet(pi, 0)         ; Defaults to "Ptr".
102 | hThread     := NumGet(pi, A_PtrSize) ;
103 | dwProcessId := NumGet(pi, A_PtrSize*2,     "UInt")
104 | dwProcessId := NumGet(pi, A_PtrSize*2 + 4, "UInt")
105 | 
106 | 107 | 108 |














109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/Concepts.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Concepts and Conventions | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Concepts and Conventions

13 |

This document covers some general concepts and conventions used by AutoHotkey, with focus on explanation rather than code. The reader is not assumed to have any prior knowledge of scripting or programming, but should be prepared to learn new terminology.

14 |

For more specific details about syntax, see Scripting Language.

15 | 16 |

Table of Contents

17 | 48 | 54 | 55 |

Values

56 |

A value is simply a piece of information within a program. For example, the name of a key to send or a program to run, the number of times a hotkey has been pressed, the title of a window to activate, or whatever else has some meaning within the program or script.

57 |

AutoHotkey supports these types of values:

58 | 63 |

The Type function can be used to determine the type of a value.

64 |

Some other related concepts:

65 | 69 | 70 |

Strings

71 |

A string is simply text. Each string is actually a sequence or string of characters, but can be treated as a single entity. The length of a string is the number of characters in the sequence, while the position of a character in the string is merely that character's sequential number. By convention in AutoHotkey, the first character is at position 1.

72 |

Numeric strings: A string of digits (or any other supported number format) is automatically interpreted as a number when a math operation or comparison requires it.

73 |

How literal text should be written within the script depends on the context. For instance, in an expression, strings must be enclosed in quotation marks. In directives (excluding #HotIf) and auto-replace hotstrings, quotation marks are not needed.

74 |

For a more detailed explanation of how strings work, see String Encoding.

75 | 76 |

Numbers

77 |

AutoHotkey supports these number formats:

78 | 83 |

Hexadecimal numbers must use the 0x or 0X prefix, except where noted in the documentation. This prefix must be written after the + or - sign, if present, and before any leading zeroes. For example, 0x001 is valid, but 000x1 is not.

84 |

Numbers written with a decimal point are always considered to be floating-point, even if the fractional part is zero. For example, 42 and 42.0 are usually interchangeable, but not always. Scientific notation is also recognized (e.g. 1.0e4 and -2.1E-4), but always produces a floating-point number even if no decimal point is present.

85 |

The decimal separator is always a dot, even if the user's regional settings specify a comma.

86 |

When a number is converted to a string, it is formatted as decimal. Floating-point numbers are formatted with full precision (but discarding redundant trailing zeroes), which may in some cases reveal their inaccuracy. Use the Format function to produce a numeric string in a different format. Floating-point numbers can also be formatted by using the Round function.

87 |

For details about the range and accuracy of numeric values, see Pure Numbers.

88 | 89 |

Boolean

90 |

A boolean value can be either true or false. Boolean values are used to represent anything that has exactly two possible states, such as the truth of an expression. For example, the expression (x <= y) is true when x has lesser or equal value to y. A boolean value could also represent yes or no, on or off, down or up (such as for GetKeyState) and so on.

91 |

AutoHotkey does not have a specific boolean type, so it uses the integer value 0 to represent false and 1 to represent true. When a value is required to be either true or false, a blank or zero value is considered false and all other values are considered true. (Objects are always considered true.)

92 |

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

93 | 94 |

Nothing

95 |

AutoHotkey does not have a value which uniquely represents nothing, null, nil or undefined, as seen in other languages.

96 |

Instead of producing a "null" or "undefined" value, any attempt to read a variable, property, array element or map item which has no value causes an UnsetError to be thrown. This allows errors to be identified more easily than if a null value was implicitly allowed to propagate through the code. See also: Uninitialized Variables.

97 |

A function's optional parameters can be omitted when the function is called, in which case the function may change its behaviour or use a default value. Parameters are usually omitted by literally omitting them from the code, but can also be omitted explicitly or conditionally by using the unset keyword. This special signal can only be propagated explicitly, with the maybe operator (var?). An unset parameter automatically receives its default value (if any) before the function executes.

98 |

Mainly for historical reasons, an empty string is sometimes used wherever a null or undefined value would be used in other languages, such as for functions which have no explicit return value.

99 |

If a variable or parameter is said to be "empty" or "blank", that usually means an empty string (a string of zero length). This is not the same as omitting a parameter, although it may have the same effect in some cases.

100 | 101 |

Objects

102 |

The object is AutoHotkey's composite or abstract data type. An object can be composed of any number of properties (which can be retrieved or set) and methods (which can be called). The name and effect of each property or method depends on the specific object or type of object.

103 |

Objects have the following attributes:

104 | 111 |

Note: All objects which derive from Object have additional shared behaviour, properties and methods.

112 |

Some ways that objects are used include:

113 | 119 |

The proper use of objects (and in particular, classes) can result in code which is modular and reusable. Modular code is usually easier to test, understand and maintain. For instance, one can improve or modify one section of code without having to know the details of other sections, and without having to make corresponding changes to those sections. Reusable code saves time, by avoiding the need to write and test code for the same or similar tasks over and over.

120 | 121 |

Object Protocol

122 |

This section builds on these concepts which are covered in later sections: variables, functions

123 |

Objects work through the principle of message passing. You don't know where an object's code or variables actually reside, so you must pass a message to the object, like "give me foo" or "go do bar", and rely on the object to respond to the message. Objects in AutoHotkey support the following basic messages:

124 | 129 |

A property is simply some aspect of the object that can be set and/or retrieved. For example, Array has a Length property which corresponds to the number of elements in the array. If you define a property, it can have whatever meaning you want. Generally a property acts like a variable, but its value might be calculated on demand and not actually stored anywhere.

130 |

Each message contains the following, usually written where the property or method is called:

131 | 135 |

For example:

136 |
137 | myObj.methodName(arg1)
138 | value := myObj.propertyName[arg1]
139 | 
140 |

An object may also have a default property, which is invoked when square brackets are used without a property name. For example:

141 |
value := myObj[arg1]
142 |

Generally, Set has the same meaning as an assignment, so it uses the same operator:

143 |
144 | myObj.name := value
145 | myObj.name[arg1, arg2, ..., argN] := value
146 | myObj[arg1, arg2, ..., argN] := value
147 | 
148 | 149 |

Variables

150 |

A variable allows you to use a name as a placeholder for a value. Which value that is could change repeatedly during the time your script is running. For example, a hotkey could use a variable press_count to count the number of times it is pressed, and send a different key whenever press_count is a multiple of 3 (every third press). Even a variable which is only assigned a value once can be useful. For example, a WebBrowserTitle variable could be used to make your code easier to update when and if you were to change your preferred web browser, or if the title or window class changes due to a software update.

151 |

In AutoHotkey, variables are created simply by using them. Each variable is not permanently restricted to a single data type, but can instead hold a value of any type: string, number or object. Attempting to read a variable which has not been assigned a value is considered an error, so it is important to initialize variables.

152 |

A variable has three main aspects:

153 | 158 |

Certain restrictions apply to variable names - see Names for details. In short, it is safest to stick to names consisting of ASCII letters (which are case-insensitive), digits and underscore, and to avoid using names that start with a digit.

159 |

A variable name has scope, which defines where in the code that name can be used to refer to that particular variable; in other words, where the variable is visible. If a variable is not visible within a given scope, the same name can refer to a different variable. Both variables might exist at the same time, but only one is visible to each part of the script. Global variables are visible in the "global scope" (that is, outside of functions), and can be read by functions by default, but must be declared if they are to be assigned a value inside a function. Local variables are visible only inside the function which created them.

160 |

A variable can be thought of as a container or storage location for a value, so you'll often find the documentation refers to a variable's value as the contents of the variable. For a variable x := 42, we can also say that the variable x has the number 42 as its value, or that the value of x is 42.

161 |

It is important to note that a variable and its value are not the same thing. For instance, we might say "myArray is an array", but what we really mean is that myArray is a variable containing a reference to an array. We're taking a shortcut by using the name of the variable to refer to its value, but "myArray" is really just the name of the variable; the array object doesn't know that it has a name, and could be referred to by many different variables (and therefore many names).

162 | 163 |

Uninitialized Variables

164 |

To initialize a variable is to assign it a starting value. A variable which has not yet been assigned a value is uninitialized (or unset for short). Attempting to read an uninitialized variable is considered an error. This helps to detect errors such as mispelled names and forgotten assignments.

165 |

IsSet can be used to determine whether a variable has been initialized, such as to initialize a global or static variable on first use.

166 |

A variable can be un-set by combining a direct assignment (:=) with the unset keyword or the maybe (var?) operator. For example: Var := unset, Var1 := (Var2?).

167 |

The or-maybe operator (??) can be used to provide a default value when a variable lacks a value. For example, MyVar ?? "Default" is equivalent to IsSet(MyVar) ? MyVar : "Default".

168 | 169 |

Built-in Variables

170 |

A number of useful variables are built into the program and can be referenced by any script. Except where noted, these variables are read-only; that is, their contents cannot be directly altered by the script. By convention, most of these variables start with the prefix A_, so it is best to avoid using this prefix for your own variables.

171 |

Some variables such as A_KeyDelay and A_TitleMatchMode represent settings that control the script's behavior, and retain separate values for each thread. This allows subroutines launched by new threads (such as for hotkeys, menus, timers and such) to change settings without affecting other threads.

172 |

Some special variables are not updated periodically, but rather their value is retrieved or calculated whenever the script references the variable. For example, A_Clipboard retrieves the current contents of the clipboard as text, and A_TimeSinceThisHotkey calculates the number of milliseconds that have elapsed since the hotkey was pressed.

173 |

Related: list of built-in variables.

174 | 175 |

Environment Variables

176 |

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.

177 |

A script may create a new environment variable or change the contents of an existing one with EnvSet. Such additions and changes are not seen by the rest of the system. However, any programs or scripts which the script launches by calling Run or RunWait usually inherit a copy of the parent script's environment variables.

178 |

To retrieve an environment variable, use EnvGet. For example:

179 |
Path := EnvGet("PATH")
180 | 181 |

Variable References (VarRef)

182 |

Within an expression, each variable reference is automatically resolved to its contents, unless it is the target of an assignment or the reference operator (&). In other words, calling myFunction(myVar) would pass the value of myVar to myFunction, not the variable itself. The function would then have its own local variable (the parameter) with the same value as myVar, but would not be able to assign a new value to myVar. In short, the parameter is passed by value.

183 |

The reference operator (&) allows a variable to be handled like a value. &myVar produces a VarRef, which can be used like any other value: assigned to another variable or property, inserted into an array, passed to or returned from a function, etc. A VarRef can be used to assign to the original target variable or retrieve its value by dereferencing it.

184 |

For convenience, a function parameter can be declared ByRef by prefixing the parameter name with ampersand (&). This requires the caller to pass a VarRef, and allows the function itself to "dereference" the VarRef by just referring to the parameter (without percent signs).

185 |
class VarRef extends Any
186 |

The VarRef class currently has no predefined methods or properties, but value is VarRef can be used to test if a value is a VarRef.

187 |

When a VarRef is used as a parameter of a COM method, the object itself is not passed. Instead, its value is copied into a temporary VARIANT, which is passed using the variant type VT_BYREF|VT_VARIANT. When the method returns, the new value is assigned to the VarRef.

188 | 189 |

Caching

190 |

Although a variable is typically thought of as holding a single value, and that value having a distinct type (string, number or object), AutoHotkey automatically converts between numbers and strings in cases like "Value is " myNumber and MsgBox myNumber. As these conversions can happen very frequently, whenever a variable containing a number is converted to a string, the result is cached in the variable.

191 |

Currently, AutoHotkey v2 caches a pure number only when assigning a pure number to a variable, not when reading it. This preserves the ability to differentiate between strings and pure numbers (such as with the Type function, or when passing values to COM objects).

192 | 193 | 194 | 198 | 199 |

Functions

200 |

A function is the basic means by which a script does something.

201 |

Functions can have many different purposes. Some functions might do no more than perform a simple calculation, while others have immediately visible effects, such as moving a window. One of AutoHotkey's strengths is the ease with which scripts can automate other programs and perform many other common tasks by simply calling a few functions. See the function list for examples.

202 |

Throughout this documentation, some common words are used in ways that might not be obvious to someone without prior experience. Below are several such words/phrases which are used frequently in relation to functions:

203 |
204 |
Call a function
205 |

Calling a function causes the program to invoke, execute or evaluate it. In other words, a function call temporarily transfers control from the script to the function. When the function has completed its purpose, it returns control to the script. In other words, any code following the function call does not execute until after the function completes.

206 |

However, sometimes a function completes before its effects can be seen by the user. For example, the Send function sends keystrokes, but may return before the keystrokes reach their destination and cause their intended effect.

207 |
Parameters
208 |

Usually a function accepts parameters which tell it how to operate or what to operate on. Each parameter is a value, such as a string or number. For example, WinMove moves a window, so its parameters tell it which window to move and where to move it to. Parameters can also be called arguments. Common abbreviations include param and arg.

209 |
Pass parameters
210 |

Parameters are passed to a function, meaning that a value is specified for each parameter of the function when it is called. For example, one can pass the name of a key to GetKeyState to determine whether that key is being held down.

211 |
Return a value
212 |

Functions return a value, so the result of the function is often called a return value. For example, StrLen returns the number of characters in a string. Functions may also store results in variables, such as when there is more than one result (see Returning Values).

213 |
Command
214 |

A function call is sometimes called a command, such as if it commands the program to take a specific action. (For historical reasons, command may refer to a particular style of calling a function, where the parentheses are omitted and the return value is discarded. However, this is technically a function call statement.)

215 |
216 |

Functions usually expect parameters to be written in a specific order, so the meaning of each parameter value depends on its position in the comma-delimited list of parameters. Some parameters can be omitted, in which case the parameter can be left blank, but the comma following it can only be omitted if all remaining parameters are also omitted. For example, the syntax for ControlSend is:

217 |
ControlSend Keys , Control, WinTitle, WinText, ExcludeTitle, ExcludeText
218 | 
219 |

Square brackets signify that the enclosed parameters are optional (the brackets themselves should not appear in the actual code). However, usually one must also specify the target window. For example:

220 |
221 | ControlSend "^{Home}", "Edit1", "A"  ; Correct. Control is specified.
222 | ControlSend "^{Home}", "A"           ; Incorrect: Parameters are mismatched.
223 | ControlSend "^{Home}",, "A"          ; Correct. Control is omitted.
224 | 
225 | 226 |

Methods

227 |

A method is a function associated with a specific object or type of object. To call a method, one must specify an object and a method name. The method name does not uniquely identify the function; instead, what happens when the method call is attempted depends on the object. For example, x.Show() might show a menu, show a GUI, raise an error or do something else, depending on what x is. In other words, a method call simply passes a message to the object, instructing it to do something. For details, see Object Protocol and Operators for Objects.

228 | 229 |

Control Flow

230 |

Control flow is the order in which individual statements are executed. Normally statements are executed sequentially from top to bottom, but a control flow statement can override this, such as by specifying that statements should be executed repeatedly, or only if a certain condition is met.

231 |
232 |
Statement
233 |

A statement is simply the smallest standalone element of the language that expresses some action to be carried out. In AutoHotkey, statements include assignments, function calls and other expressions. However, directives, double-colon hotkey and hotstring tags, and declarations without assignments are not statements; they are processed when the program first starts up, before the script executes.

234 |
Execute
235 |

Carry out, perform, evaluate, put into effect, etc. Execute basically has the same meaning as in non-programming speak.

236 |
Body
237 |

The body of a control flow statement is the statement or group of statements to which it applies. For example, the body of an if statement is executed only if a specific condition is met.

238 |
239 |

For example, consider this simple set of instructions:

240 |
    241 |
  1. Open Notepad
  2. 242 |
  3. Wait for Notepad to appear on the screen
  4. 243 |
  5. Type "Hello, world!"
  6. 244 |
245 |

We take one step at a time, and when that step is finished, we move on to the next step. In the same way, control in a program or script usually flows from one statement to the next statement. But what if we want to type into an existing Notepad window? Consider this revised set of instructions:

246 |
    247 |
  1. If Notepad is not running: 248 |
      249 |
    1. Open Notepad
    2. 250 |
    3. Wait for Notepad to appear on the screen
    4. 251 |
    252 |
  2. 253 |
  3. Otherwise: 254 |
      255 |
    1. Activate Notepad
    2. 256 |
    257 |
  4. 258 |
  5. Type "Hello, world!"
  6. 259 |
260 |

So we either open Notepad or activate Notepad depending on whether it is already running. #1 is a conditional statement, also known as an if statement; that is, we execute its body (#1.1 - #1.2) only if a condition is met. #2 is an else statement; we execute its body (#2.1) only if the condition of a previous if statement (#1) is not met. Depending on the condition, control flows one of two ways: #1 (if true) → #1.1 → #1.2 → #3; or #1 (if false) → #2 (else) → #2.1 → #3.

261 |

The instructions above can be translated into the code below:

262 |
if (not WinExist("ahk_class Notepad"))
263 | {
264 |     Run "Notepad"
265 |     WinWait "ahk_class Notepad"
266 | }
267 | else
268 |     WinActivate "ahk_class Notepad"
269 | Send "Hello, world{!}"
270 | 
271 |

In our written instructions, we used indentation and numbering to group the statements. Scripts work a little differently. Although indentation makes code easier to read, in AutoHotkey it does not affect the grouping of statements. Instead, statements are grouped by enclosing them in braces, as shown above. This is called a block.

272 |

For details about syntax - that is, how to write or recognise control flow statements in AutoHotkey - see Control Flow.

273 | 274 |

Details

275 | 276 |

String Encoding

277 |

Each character in the string is represented by a number, called its ordinal number, or character code. For example, the value "Abc" would be represented as follows:

278 | 279 | 280 | 281 |
Abc
6598990
282 |

Encoding: The encoding of a string defines how symbols are mapped to ordinal numbers, and ordinal numbers to bytes. There are many different encodings, but as all of those supported by AutoHotkey include ASCII as a subset, character codes 0 to 127 always have the same meaning. For example, 'A' always has the character code 65.

283 |

Null-termination: Each string is terminated with a "null character", or in other words, a character with ordinal value of zero marks the end of the string. The length of the string can be inferred by the position of the null-terminator, but AutoHotkey also stores the length, for performance and to permit null characters within the string's length.

284 |

Note: Due to reliance on null-termination, many built-in functions and most expression operators do not support strings with embedded null characters, and instead read only up to the first null character. However, basic manipulation of such strings is supported; e.g. concatenation, ==, !==, Chr(0), StrLen, SubStr, assignments, parameter values and return.

285 |

Native encoding: Although AutoHotkey provides ways to work with text in various encodings, the built-in functions--and to some degree the language itself--all assume string values to be in one particular encoding. This is referred to as the native encoding. The native encoding depends on the version of AutoHotkey:

286 | 294 |

Note: AutoHotkey v2 natively uses Unicode and does not have an ANSI version.

295 |

Character: Generally, other parts of this documentation use the term "character" to mean a string's smallest unit; bytes for ANSI strings and 16-bit code units for Unicode (UTF-16) strings. For practical reasons, the length of a string and positions within a string are measured by counting these fixed-size units, even though they may not be complete Unicode characters.

296 |

FileRead, FileAppend, FileOpen and the File object provide ways of reading and writing text in files with a specific encoding.

297 |

The functions StrGet and StrPut can be used to convert strings between the native encoding and some other specified encoding. However, these are usually only useful in combination with data structures and the DllCall function. Strings which are passed directly to or from DllCall can be converted to ANSI or UTF-16 by using the AStr or WStr parameter types.

298 |

Techniques for dealing with the differences between ANSI and Unicode versions of AutoHotkey can be found under Unicode vs ANSI.

299 | 300 |

Pure Numbers

301 |

A pure or binary number is one which is stored in memory in a format that the computer's CPU can directly work with, such as to perform math. In most cases, AutoHotkey automatically converts between numeric strings and pure numbers as needed, and rarely differentiates between the two types. AutoHotkey primarily uses two data types for pure numbers:

302 | 306 |

These data types affect the range and precision of pure numeric values for variables, properties, array/map elements and indices, function parameters and return values, and temporary results of operators in an expression. Mathematical operators and functions perform 64-bit integer or floating-point operations. Bitwise operators perform 64-bit integer operations.

307 |

In other words, scripts are affected by the following limitations:

308 | 316 |

Note: There are some decimal fractions which the binary floating-point format cannot precisely represent, so a number is rounded to the closest representable number. This may lead to unexpected results. For example:

317 |
318 | MsgBox 0.1 + 0           ; 0.10000000000000001
319 | MsgBox 0.1 + 0.2         ; 0.30000000000000004
320 | MsgBox 0.3 + 0           ; 0.29999999999999999
321 | MsgBox 0.1 + 0.2 = 0.3   ; 0 (not equal)
322 | 
323 |

One strategy for dealing with this is to avoid direct comparison, instead comparing the difference. For example:

324 |
MsgBox Abs((0.1 + 0.2) - (0.3)) < 0.0000000000000001
325 | 
326 |

Another strategy is to explicitly apply rounding before comparison, such as by converting to a string. There are generally two ways to do this while specifying the precision, and both are shown below:

327 |
MsgBox Round(0.1 + 0.2, 15) = Format("{:.15f}", 0.3)
328 | 
329 | 330 |

Names

331 |

AutoHotkey uses the same set of rules for naming various things, including variables, functions, window groups, classes, properties and methods. The rules are as follows.

332 |

Case sensitivity: None for ASCII characters. For example, CurrentDate is the same as currentdate. However, uppercase non-ASCII characters such as 'Ä' are not considered equal to their lowercase counterparts, regardless of the current user's locale. This helps the script to behave consistently across multiple locales.

333 |

Maximum length: 253 characters.

334 |

Allowed characters: Letters, digits, underscore and non-ASCII characters; however, only property names can begin with a digit.

335 |

Reserved words: as, and, contains, false, in, is, IsSet, not, or, super, true, unset. These words are reserved for future use or other specific purposes.

336 |

Declaration keywords and names of control flow statements are also reserved, primarily to detect mistakes. This includes: Break, Case, Catch, Continue, Else, Finally, For, Global, Goto, If, Local, Loop, Return, Static, Switch, Throw, Try, Until, While

337 |

Names of properties, methods and window groups are permitted to be reserved words.

338 | 339 |

References to Objects

340 |

Scripts interact with an object only indirectly, through a reference to the object. When you create an object, the object is created at some location you don't control, and you're given a reference. Passing this reference to a function or storing it in a variable or another object creates a new reference to the same object.

341 |

For example, if myObj contains a reference to an object, yourObj := myObj creates a new reference to the same object. A change such as myObj.ans := 42 would be reflected by both myObj.ans and yourObj.ans, since they both refer to the same object. However, myObj := Object() only affects the variable myObj, not the variable yourObj, which still refers to the original object.

342 |

A reference is released by simply using an assignment to replace it with any other value. An object is deleted only after all references have been released; you cannot delete an object explicitly, and should not try. (However, you can delete an object's properties, content or associated resources, such as an Array's elements, the window associated with a Gui, the items of a Menu object, and so on.)

343 |
ref1 := Object()  ; Create an object and store first reference
344 | ref2 := ref1      ; Create a new reference to the same object
345 | ref1 := ""        ; Release the first reference
346 | ref2 := ""        ; Release the second reference; object is deleted
347 | 
348 |

If that's difficult to understand, try thinking of an object as a rental unit. When you rent a unit, you're given a key which you can use to access the unit. You can get more keys and use them to access the same unit, but when you're finished with the unit, you must hand all keys back to the rental agent. Usually a unit wouldn't be deleted, but maybe the agent will have any junk you left behind removed; just as any values you stored in an object are freed when the object is deleted.

349 | 350 | 351 | 352 | -------------------------------------------------------------------------------- /docs/FAQ.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Frequently Asked Questions (FAQ) | AutoHotkey v2 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Frequently Asked Questions (FAQ)

14 | 15 |

Table of Contents

16 |

General Troubleshooting

17 | 30 |

Common Tasks

31 | 49 |

Hotkeys, Hotstrings, and Remapping

50 | 63 | 64 |

General Troubleshooting

65 |

What can I do if AutoHotkey won't install?

66 |

If AutoHotkey cannot be installed the normal way, see How to Install AutoHotkey for more help.

67 | 68 |

How do I restore the right-click context menu options for .ahk files?

69 |

Normally if AutoHotkey is installed, right-clicking an AutoHotkey script (.ahk) file should give the following options:

70 | 77 |

Note: On Windows 11, some of these options are usually relegated to a submenu that can be accessed by selecting "Show more options".

78 |

Sometimes these options are overridden by settings in the current user's profile, such as if Open With has been used to change the default program for opening .ahk files. This can be fixed by deleting the following registry key:

79 |
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ahk\UserChoice
80 |

This can be done by applying this registry patch or by running UX\reset-assoc.ahk from the AutoHotkey installation directory.

81 |

It may also be necessary to repair the default registry values, either by reinstalling AutoHotkey or by running UX\install.ahk from the AutoHotkey installation directory.

82 | 83 |

Why doesn't my script work on Windows xxx even though it worked on a previous version?

84 |

There are many variations of this problem, such as:

85 | 90 |

If you've switched operating systems, it is likely that something else has also changed and may be affecting your script. For instance, if you've got a new computer, it might have different drivers or other software installed. If you've also updated to a newer version of AutoHotkey, find out which version you had before and then check the changelog and compatibility notes.

91 |

Also refer to the following question:

92 | 93 |

How do I work around problems caused by User Account Control (UAC)?

94 |

By default, User Account Control (UAC) protects "elevated" programs (that is, programs which are running as admin) from being automated by non-elevated programs, since that would allow them to bypass security restrictions. Hotkeys are also blocked, so for instance, a non-elevated program cannot spy on input intended for an elevated program.

95 |

UAC may also prevent SendPlay and BlockInput from working.

96 |

Common workarounds are as follows:

97 | 109 | 110 |

I can't edit my script via tray icon because it won't start due to an error. What should I do?

111 |

You need to fix the error in your script before you can get your tray icon back. This will require locating the script and opening it in an editor by some other means than the tray icon.

112 |

If you are running an AutoHotkey executable file directly, the name of the script depends on the executable. For example, if you are running AutoHotkey32.exe, look for AutoHotkey32.ahk in the same directory. Note that depending on your system settings the ".ahk" part may be hidden, but the file should have an icon like [H]

113 |

You can usually edit a script file by right clicking it and selecting Edit Script. If that doesn't work, you can open the file in Notepad or another editor.

114 |

Normally, you should create a script file (something.ahk) anywhere you like, and run that script file instead of running AutoHotkey.

115 |

See also Command Line Parameter "Script Filename" and Portability of AutoHotkey.exe.

116 |

How can I find and fix errors in my code?

117 |

For simple scripts, see Debugging a Script. To show contents of a variable, use MsgBox or ToolTip. For complex scripts, see Interactive Debugging.

118 |

Why is the Run function unable to launch my game or program?

119 |

Some programs need to be started in their own directories (when in doubt, it is usually best to do so). For example:

120 |
Run A_ProgramFiles "\Some Application\App.exe", A_ProgramFiles "\Some Application"
121 |

If the program you are trying to start is in A_WinDir "\System32" and you are using AutoHotkey 32-bit on a 64-bit system, the File System Redirector may be interfering. To work around this, use A_WinDir "\SysNative" instead; this is a virtual directory only visible to 32-bit programs running on 64-bit systems.

122 | 123 |

Why are the non-ASCII characters in my script displaying or sending incorrectly?

124 |

Short answer: Save the script as UTF-8, preferably with BOM.

125 |

Non-ASCII characters are represented by different binary values depending on the chosen encoding. In order for such characters to be interpreted correctly, your text editor and AutoHotkey must be on the same codepage, so to speak. AutoHotkey v2 defaults to UTF-8 for all script files, although this can be overridden with the /CP command line switch.

126 |

It is recommended to save the script as UTF-8 with BOM (byte order mark) to ensure that editors (and maybe other applications) can determine with certainty that the file is indeed UTF-8. Without BOM, the editor has to guess the encoding of the file, which can sometimes be wrong.

127 |

To save as UTF-8 in Notepad, select UTF-8 or UTF-8 with BOM from the Encoding drop-down in the Save As dialog. Note that Notepad in Windows 10 v1903 and later defaults to UTF-8 (without BOM).

128 |

To read other UTF-8 files which lack a byte order mark (BOM), use FileEncoding "UTF-8-RAW", the *P65001 option with FileRead, or "UTF-8-RAW" for the third parameter of FileOpen. The -RAW suffix can be omitted, but in that case any newly created files will have a BOM.

129 |

Note that INI files accessed with the standard INI functions do not support UTF-8; they must be saved as ANSI or UTF-16.

130 | 131 |

Why don't Hotstrings, Send, and Click work in certain games?

132 |

Not all games allow AHK to send keys and clicks or receive pixel colors.

133 |

But there are some alternatives, try all the solutions mentioned below. If all these fail, it may not be possible for AHK to work with your game. Sometimes games have a hack and cheat prevention measure, such as GameGuard and Hackshield. If they do, there is a high chance that AutoHotkey will not work with that game.

134 | 168 |

How can performance be improved for games or at other times when the CPU is under heavy load?

169 |

If a script's Hotkeys, Clicks, or Sends are noticeably slower than normal while the CPU is under heavy load, raising the script's process-priority may help. To do this, include the following line near the top of the script:

170 |
ProcessSetPriority "High"
171 |

My antivirus program flagged AutoHotkey or a compiled script as malware. Is it really a virus?

172 |

Although it is certainly possible that the file has been infected, most often these alerts are false positives, meaning that the antivirus program is mistaken. One common suggestion is to upload the file to an online service such as virustotal or Jotti and see what other antivirus programs have to say. If in doubt, you could send the file to the vendor of your antivirus software for confirmation. This might also help us and other AutoHotkey users, as the vendor may confirm it is a false positive and fix their product to play nice with AutoHotkey.

173 |

False positives might be more common for compiled scripts which have been compressed, such as with UPX (default for AutoHotkey 1.0 but not 1.1) or MPRESS (optional for AutoHotkey 1.1). As the default AutoHotkey installation does not include a compressor, compiled scripts are not compressed by default.

174 | 175 |

Common Tasks

176 | 177 |

Where can I find the official build, or older releases?

178 |

See download page of AutoHotkey.

179 |

Can I run AHK from a USB drive?

180 |

See Portability of AutoHotkey.exe.

181 |

How can the output of a command line operation be retrieved?

182 |

Testing shows that due to file caching, a temporary file can be very fast for relatively small outputs. In fact, if the file is deleted immediately after use, it often does not actually get written to disk. For example:

183 |
RunWait A_ComSpec ' /c dir > C:\My Temp File.txt'
184 | VarToContainContents := FileRead("C:\My Temp File.txt")
185 | FileDelete "C:\My Temp File.txt"
186 |

To avoid using a temporary file (especially if the output is large), consider using the Shell.Exec() method as shown in the examples for the Run function.

187 |

How can a script close, pause, suspend or reload other script(s)?

188 |

First, here is an example that closes another script:

189 |
DetectHiddenWindows True  ; Allows a script's hidden main window to be detected.
190 | SetTitleMatchMode 2  ; Avoids the need to specify the full path of the file below.
191 | WinClose "ScriptFileName.ahk - AutoHotkey"  ; Update this to reflect the script's name (case-sensitive).
192 |

To suspend, pause or reload another script, replace the last line above with one of these:

193 |
PostMessage 0x0111, 65305,,, "ScriptFileName.ahk - AutoHotkey"  ; Suspend.
194 | PostMessage 0x0111, 65306,,, "ScriptFileName.ahk - AutoHotkey"  ; Pause.
195 | PostMessage 0x0111, 65303,,, "ScriptFileName.ahk - AutoHotkey"  ; Reload.
196 |

How can a repeating action be stopped without exiting the script?

197 |

To pause or resume the entire script at the press of a key, assign a hotkey to the Pause function as in this example:

198 |
^!p::Pause  ; Press Ctrl+Alt+P to pause. Press it again to resume.
199 |

To stop an action that is repeating inside a Loop, consider the following working example, which is a hotkey that both starts and stops its own repeating action. In other words, pressing the hotkey once will start the loop. Pressing the same hotkey again will stop it.

200 |
#MaxThreadsPerHotkey 3
201 | #z::  ; Win+Z hotkey (change this hotkey to suit your preferences).
202 | {
203 |     static KeepWinZRunning := false
204 |     if KeepWinZRunning  ; This means an underlying thread is already running the loop below.
205 |     {
206 |         KeepWinZRunning := false  ; Signal that thread's loop to stop.
207 |         return  ; End this thread so that the one underneath will resume and see the change made by the line above.
208 |     }
209 |     ; Otherwise:
210 |     KeepWinZRunning := true
211 |     Loop
212 |     {
213 |         ; The next four lines are the action you want to repeat (update them to suit your preferences):
214 |         ToolTip "Press Win-Z again to stop this from flashing."
215 |         Sleep 1000
216 |         ToolTip
217 |         Sleep 1000
218 |         ; But leave the rest below unchanged.
219 |         if not KeepWinZRunning  ; The user signaled the loop to stop by pressing Win-Z again.
220 |             break  ; Break out of this loop.
221 |     }
222 |     KeepWinZRunning := false  ; Reset in preparation for the next press of this hotkey.
223 | }
224 | #MaxThreadsPerHotkey 1
225 |

How can context sensitive help for AutoHotkey functions be used in any editor?

226 |

Rajat created this script.

227 |

How to detect when a web page is finished loading?

228 |

With Internet Explorer, perhaps the most reliable method is to use DllCall and COM as demonstrated at this archived forum thread. On a related note, the contents of the address bar and status bar can be retrieved as demonstrated at this archived forum thread.

229 |

Older, less reliable method: The technique in the following example will work with MS Internet Explorer for most pages. A similar technique might work in other browsers:

230 |
Run "www.yahoo.com"
231 | MouseMove 0, 0  ; Prevents the status bar from showing a mouse-hover link instead of "Done".
232 | WinWait "Yahoo! - "
233 | WinActivate
234 | if StatusBarWait("Done", 30)
235 |     MsgBox "The page is done loading."
236 | else
237 |     MsgBox "The wait timed out or the window was closed."
238 | 
239 |

How can dates and times be compared or manipulated?

240 |

The DateAdd function can add or subtract a quantity of days, hours, minutes, or seconds to a time-string that is in the YYYYMMDDHH24MISS format. The following example subtracts 7 days from the specified time:

241 |
Result := DateAdd(VarContainingTimestamp, -7, "days")
242 |

To determine the amount of time between two dates or times, see DateDiff, which gives an example. Also, the built-in variable A_Now contains the current local time. Finally, there are several built-in date/time variables, as well as the FormatTime function to create a custom date/time string.

243 |

How can I send the current Date and/or Time?

244 |

Use FormatTime or built-in variables for date and time.

245 |

How can I send text to a window which isn't active or isn't visible?

246 |

Use ControlSend.

247 |

How can Winamp be controlled even when it isn't active?

248 |

See Automating Winamp.

249 |

How can MsgBox's button names be changed?

250 |

Here is an example.

251 |

How can I change the default editor, which is accessible via context menu or tray icon?

252 |

In the example section of Edit you will find a script that allows you to change the default editor.

253 |

How can I save the contents of my GUI controls?

254 |

Use Gui.Submit. For Example:

255 |
MyGui := Gui()
256 | MyGui.Add("Text",, "Enter some Text and press Submit:")
257 | MyGui.Add("Edit", "vMyEdit")
258 | MyGui.Add("Button",, "Submit").OnEvent("Click", Submit)
259 | MyGui.Show()
260 | 
261 | Submit(*)
262 | {
263 |     Saved := MyGui.Submit(false)
264 |     MsgBox "Content of the edit control: " Saved.MyEdit
265 | }
266 |

Can I draw something with AHK?

267 |

See GDI+ standard library by tic. It's also possible with some rudimentary methods using Gui, but in a limited way.

268 |

How can I start an action when a window appears, closes or becomes [in]active?

269 |

Use WinWait, WinWaitClose or WinWait[Not]Active.

270 |

There are also user-created solutions such as OnWin.ahk and [How to] Hook on to Shell to receive its messages on the archived forum.

271 |

Hotkeys, Hotstrings, and Remapping

272 |

How do I put my hotkeys and hotstrings into effect automatically every time I start my PC?

273 |

There are several ways to make a script (or any program) launch automatically every time you start your PC. The easiest is to place a shortcut to the script in the Startup folder:

274 |
    275 |
  1. Find the script file, select it, and press Ctrl+C.
  2. 276 |
  3. Press Win+R to open the Run dialog, then enter shell:startup and click OK or Enter. This will open the Startup folder for the current user. To instead open the folder for all users, enter shell:common startup (however, in that case you must be an administrator to proceed).
  4. 277 |
  5. Right click inside the window, and click "Paste Shortcut". The shortcut to the script should now be in the Startup folder.
  6. 278 |
279 |

I'm having trouble getting my mouse buttons working as hotkeys. Any advice?

280 |

The left and right mouse buttons should be assignable normally (for example, #LButton:: is the Win+LeftButton hotkey). Similarly, the middle button and the turning of the mouse wheel should be assignable normally except on mice whose drivers directly control those buttons.

281 |

The fourth button (XButton1) and the fifth button (XButton2) might be assignable if your mouse driver allows their clicks to be seen by the system. If they cannot be seen -- or if your mouse has more than five buttons that you want to use -- you can try configuring the software that came with the mouse (sometimes accessible in the Control Panel or Start Menu) to send a keystroke whenever you press one of these buttons. Such a keystroke can then be defined as a hotkey in a script. For example, if you configure the fourth button to send Ctrl+F1, you can then indirectly configure that button as a hotkey by using ^F1:: in a script.

282 |

If you have a five-button mouse whose fourth and fifth buttons cannot be seen, you can try changing your mouse driver to the default driver included with the OS. This assumes there is such a driver for your particular mouse and that you can live without the features provided by your mouse's custom software.

283 |

How can Tab and Space be defined as hotkeys?

284 |

Use the names of the keys (Tab and Space) rather than their characters. For example, #Space is Win+Space and ^!Tab is Ctrl+Alt+Tab.

285 |

How can keys or mouse buttons be remapped so that they become different keys?

286 |

This is described on the remapping page.

287 |

How do I detect the double press of a key or button?

288 |

Use built-in variables for hotkeys as follows:

289 |
~Ctrl::
290 | {
291 |     if (ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 200)
292 |         MsgBox "double-press"
293 | }
294 |

How can a hotkey or hotstring be made exclusive to certain program(s)? In other words, I want a certain key to act as it normally does except when a specific window is active.

295 |

The preferred method is #HotIf. For example:

296 |
#HotIf WinActive("ahk_class Notepad")
297 | ^a::MsgBox "You pressed Control-A while Notepad is active."
298 | 
299 |

How can a prefix key be made to perform its native function rather than doing nothing?

300 |

Consider the following example, which makes Numpad0 into a prefix key:

301 |
Numpad0 & Numpad1::MsgBox "You pressed Numpad1 while holding down Numpad0."
302 |

Now, to make Numpad0 send a real Numpad0 keystroke whenever it wasn't used to launch a hotkey such as the above, add the following hotkey:

303 |
 $Numpad0::Send "{Numpad0}"
304 |

The $ prefix is needed to prevent a warning dialog about an infinite loop (since the hotkey "sends itself"). In addition, the above action occurs at the time the key is released.

305 |

How can the built-in Windows shortcut keys, such as Win+U (Utility Manager) and Win+R (Run), be changed or disabled?

306 |

Here are some examples.

307 |

Can I use wildcards or regular expressions in Hotstrings?

308 |

Use the script by polyethene (examples are included).

309 |

How can I use a hotkey that is not in my keyboard layout?

310 |

See Special Keys.

311 |

My keypad has a special 000 key. Is it possible to turn it into a hotkey?

312 |

You can. This example script makes 000 into an equals key. You can change the action by replacing the Send "=" line with line(s) of your choice.

313 | 314 | 315 | -------------------------------------------------------------------------------- /docs/Functions.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Functions - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Functions

14 | 15 |

Table of Contents

16 | 52 |

Introduction and Simple Examples

53 |

A function is a reusable block of code that can be executed by calling it. A function can optionally accept parameters (inputs) and return a value (output). Consider the following simple function that accepts two numbers and returns their sum:

54 |
Add(x, y)
 55 | {
 56 |     return x + y
 57 | }
58 |

The above is known as a function definition because it creates a function named "Add" (not case-sensitive) and establishes that anyone who calls it must provide exactly two parameters (x and y). To call the function, assign its result to a variable with the := operator. For example:

59 |
Var := Add(2, 3)  ; The number 5 will be stored in Var.
60 |

Also, a function may be called without storing its return value:

61 |
Add(2, 3)
 62 | Add 2, 3  ; Parentheses can be omitted if used at the start of a line.
63 |

But in this case, any value returned by the function is discarded; so unless the function produces some effect other than its return value, the call would serve no purpose.

64 |

Within an expression, a function call "evaluates to" the return value of the function. The return value can be assigned to a variable as shown above, or it can be used directly as shown below:

65 |
if InStr(MyVar, "fox")
 66 |     MsgBox "The variable MyVar contains the word fox."
67 | 68 |

Parameters

69 |

When a function is defined, its parameters are listed in parentheses next to its name (there must be no spaces between its name and the open-parenthesis). If a function does not accept any parameters, leave the parentheses empty; for example: GetCurrentTimestamp().

70 |

Known limitation:

71 | 74 | 75 |

ByRef Parameters

76 |

From the function's point of view, parameters are essentially the same as local variables unless they are marked as ByRef as in this example:

77 |
a := 1, b := 2
 78 | Swap(&a, &b)
 79 | MsgBox a ',' b
 80 | 
 81 | Swap(&Left, &Right)
 82 | {
 83 |     temp := Left
 84 |     Left := Right
 85 |     Right := temp
 86 | }
87 |

In the example above, the use of & requires the caller to pass a VarRef, which usually corresponds to one of the caller's variables. Each parameter becomes an alias for the variable represented by the VarRef. In other words, the parameter and the caller's variable both refer to the same contents in memory. This allows the Swap function to alter the caller's variables by moving Left's contents into Right and vice versa.

88 |

By contrast, if ByRef were not used in the example above, Left and Right would be copies of the caller's variables and thus the Swap function would have no external effect. However, the function could instead be changed to explicitly dereference each VarRef. For example:

89 |
Swap(Left, Right)
 90 | {
 91 |     temp := %Left%
 92 |     %Left% := %Right%
 93 |     %Right% := temp
 94 | }
95 |

Since return can send back only one value to a function's caller, VarRefs can be used to send back extra results. This is achieved by having the caller pass in a reference to a variable (usually empty) in which the function stores a value.

96 |

When passing large strings to a function, ByRef enhances performance and conserves memory by avoiding the need to make a copy of the string. Similarly, using ByRef to send a long string back to the caller usually performs better than something like Return HugeString. However, what the function receives is not a reference to the string, but a reference to the variable. Future improvements might supersede the use of ByRef for these purposes.

97 |

Known limitations:

98 | 102 | 103 |

Optional Parameters

104 |

When defining a function, one or more of its parameters can be marked as optional.

105 |

Append := followed by a literal number, quoted/literal string such as "fox" or "", or an expression that should be evaluated each time the parameter needs to be initialized with its default value. For example, X:=[] would create a new Array each time.

106 |

Append ? or := unset to define a parameter which is unset by default.

107 |

The following function has its Z parameter marked optional:

108 |
Add(X, Y, Z := 0) {
109 |     return X + Y + Z
110 | }
111 |

When the caller passes three parameters to the function above, Z's default value is ignored. But when the caller passes only two parameters, Z automatically receives the value 0.

112 |

It is not possible to have optional parameters isolated in the middle of the parameter list. In other words, all parameters that lie to the right of the first optional parameter must also be marked optional. However, optional parameters may be omitted from the middle of the parameter list when calling the function, as shown below:

113 |
MyFunc(1,, 3)
114 | MyFunc(X, Y:=2, Z:=0) {  ; Note that Z must still be optional in this case.
115 |     MsgBox X ", " Y ", " Z
116 | }
117 |

ByRef parameters also support default values; for example: MyFunc(&p1 := "") {. Whenever the caller omits such a parameter, the function creates a local variable to contain the default value; in other words, the function behaves as though the symbol "&" is absent.

118 | 119 |

Unset Parameters

120 |

To mark a parameter as optional without supplying a default value, use the keyword unset or the ? suffix. In that case, whenever the parameter is omitted, the corresponding variable will have no value. Use IsSet to determine whether the parameter has been given a value, as shown below:

121 |
122 | MyFunc(p?) {  ; Equivalent to MyFunc(p := unset)
123 |     if IsSet(p)
124 |         MsgBox "Caller passed " p
125 |     else
126 |         MsgBox "Caller did not pass anything"
127 | }
128 | 
129 | MyFunc(42)
130 | MyFunc
131 | 
132 |

Attempting to read the parameter's value when it has none is considered an error, the same as for any uninitialized variable. To pass an optional parameter through to another function even when the parameter has no value, use the maybe operator (var?). For example:

133 |
134 | Greet(title?) {
135 |     MsgBox("Hello!", title?)
136 | }
137 | 
138 | Greet "Greeting"  ; Title is "Greeting"
139 | Greet             ; Title is A_ScriptName
140 | 
141 | 142 |

Returning Values to Caller

143 |

As described in introduction, a function may optionally return a value to its caller.

144 |
145 | MsgBox returnTest()
146 | 
147 | returnTest() {
148 |     return 123
149 | }
150 | 
151 |

If you want to return extra results from a function, you may also use ByRef (&):

152 |
153 | returnByRef(&A,&B,&C)
154 | MsgBox A "," B "," C
155 | 
156 | returnByRef(&val1, &val2, val3)
157 | {
158 |     val1 := "A"
159 |     val2 := 100
160 |     %val3% := 1.1  ; % is used because & was omitted.
161 |     return
162 | }
163 | 
164 |

Objects and Arrays can be used to return multiple values or even named values:

165 |
166 | Test1 := returnArray1()
167 | MsgBox Test1[1] "," Test1[2]
168 | 
169 | Test2 := returnArray2()
170 | MsgBox Test2[1] "," Test2[2]
171 | 
172 | Test3 := returnObject()
173 | MsgBox Test3.id "," Test3.val
174 | 
175 | returnArray1() {
176 |     Test := [123,"ABC"]
177 |     return Test
178 | }
179 | 
180 | returnArray2() {
181 |     x := 456
182 |     y := "EFG"
183 |     return [x, y]
184 | }
185 | 
186 | returnObject() {
187 |     Test := {id: 789, val: "HIJ"}
188 |     return Test
189 | }
190 | 
191 |

Variadic Functions

192 |

When defining a function, write an asterisk after the final parameter to mark the function as variadic, allowing it to receive a variable number of parameters:

193 |
Join(sep, params*) {
194 |     for index,param in params
195 |         str .= param . sep
196 |     return SubStr(str, 1, -StrLen(sep))
197 | }
198 | MsgBox Join("`n", "one", "two", "three")
199 |

When a variadic function is called, surplus parameters can be accessed via an object which is stored in the function's final parameter. The first surplus parameter is at params[1], the second at params[2] and so on. As it is an array, params.Length can be used to determine the number of parameters.

200 |

Attempting to call a non-variadic function with more parameters than it accepts is considered an error. To permit a function to accept any number of parameters without creating an array to store the surplus parameters, write * as the final parameter (without a parameter name).

201 |

Note: The "variadic" parameter can only appear at the end of the formal parameter list.

202 | 203 |

Variadic Function Calls

204 |

While variadic functions can accept a variable number of parameters, an array of parameters can be passed to any function by applying the same syntax to a function-call:

205 |
substrings := ["one", "two", "three"]
206 | MsgBox Join("`n", substrings*)
207 |

Notes:

208 | 213 |

Known limitations:

214 | 219 |

Local and Global Variables

220 |

Local Variables

221 |

Local variables are specific to a single function and are visible only inside that function. Consequently, a local variable may have the same name as a global variable but have separate contents. Separate functions may also safely use the same variable names.

222 |

All local variables which are not static are automatically freed (made empty) when the function returns, with the exception of variables which are bound to a closure or VarRef (such variables are freed at the same time as the closure or VarRef).

223 |

Built-in variables such as A_Clipboard and A_TimeIdle are never local (they can be accessed from anywhere), and cannot be redeclared. (This does not apply to built-in classes such as Object; they are predefined as global variables.)

224 |

Functions are assume-local by default. Variables accessed or created inside an assume-local function are local by default, with the following exceptions:

225 | 229 |

The default may also be overridden by declaring the variable using the local keyword, or by changing the mode of the function (as shown below).

230 | 231 |

Global Variables

232 |

Any variable reference in an assume-local function may resolve to a global variable if it is only read. However, if a variable is used in an assignment or with the reference operator (&), it is automatically local by default. This allows functions to read global variables or call global or built-in functions without declaring them inside the function, while protecting the script from unintended side-effects when the name of a local variable being assigned coincides with a global variable. For example:

233 |
LogToFile(TextToLog)
234 | {
235 |     ; LogFileName was previously given a value somewhere outside this function.
236 |     ; FileAppend is a predefined global variable containing a built-in function.
237 |     FileAppend TextToLog "`n", LogFileName
238 | }
239 |

Otherwise, to refer to an existing global variable inside a function (or create a new one), declare the variable as global prior to using it. For example:

240 |
SetDataDir(Dir)
241 | {
242 |     global LogFileName
243 |     LogFileName := Dir . "\My.log"
244 |     global DataDir := Dir  ; Declaration combined with assignment, described below.
245 | }
246 | 
247 |

Assume-global mode: If a function needs to access or create a large number of global variables, it can be defined to assume that all its variables are global (except its parameters) by making its first line the word "global". For example:

248 |
SetDefaults()
249 | {
250 |     global
251 |     MyGlobal := 33  ; Assigns 33 to a global variable, first creating the variable if necessary.
252 |     local x, y:=0, z  ; Local variables must be declared in this mode, otherwise they would be assumed global.
253 | }
254 | 255 |

Static Variables

256 |

Static variables are always implicitly local, but differ from locals because their values are remembered between calls. For example:

257 |
LogToFile(TextToLog)
258 | {
259 |     static LoggedLines := 0
260 |     LoggedLines += 1  ; Maintain a tally locally (its value is remembered between calls).
261 |     global LogFileName
262 |     FileAppend LoggedLines ": " TextToLog "`n", LogFileName
263 | }
264 |

A static variable may be initialized on the same line as its declaration by following it with := and any expression. For example: static X:=0, Y:="fox". Static declarations are evaluated the same as local declarations, except that after a static initializer (or group of combined initializers) is successfully evaluated, it is effectively removed from the flow of control and will not execute a second time.

265 |

Nested functions can be declared static to prevent them from capturing non-static local variables of the outer function.

266 |

Assume-static mode: A function may be defined to assume that all its undeclared local variables are static (except its parameters) by making its first line the word "static". For example:

267 |
GetFromStaticArray(WhichItemNumber)
268 | {
269 |     static
270 |     static FirstCallToUs := true  ; Each static declaration's initializer still runs only once.
271 |     if FirstCallToUs  ; Create a static array during the first call, but not on subsequent calls.
272 |     {
273 |         FirstCallToUs := false
274 |         StaticArray := []
275 |         Loop 10
276 |             StaticArray.Push("Value #" . A_Index)
277 |     }
278 |     return StaticArray[WhichItemNumber]
279 | }
280 |

In assume-static mode, any variable that should not be static must be declared as local or global (with the same exceptions as for assume-local mode).

281 | 282 |

More About Locals and Globals

283 |

Multiple variables may be declared on the same line by separating them with commas as in these examples:

284 |
global LogFileName, MaxRetries := 5
285 | static TotalAttempts := 0, PrevResult
286 |

A variable may be initialized on the same line as its declaration by following it with an assignment. Unlike static initializers, the initializers of locals and globals execute every time the function is called. In other words, a line like local x := 0 has the same effect as writing two separate lines: local x followed by x := 0. Any assignment operator can be used, but a compound assignment such as global HitCount += 1 would require that the variable has previously been assigned a value.

287 |

Because the words local, global, and static are processed immediately when the script launches, a variable cannot be conditionally declared by means of an IF statement. In other words, a declaration inside an IF's or ELSE's block takes effect unconditionally for the entire function (but any initializers included in the declaration are still conditional). A dynamic declaration such as global Array%i% is not possible, since all non-dynamic references to variables such as Array1 or Array99 would have already been resolved to addresses.

288 | 289 |

Dynamically Calling a Function

290 |

Although a function call expression usually begins with a literal function name, the target of the call can be any expression which produces a function object. In the expression GetKeyState("Shift"), GetKeyState is actually a variable reference, although it usually refers to a read-only variable containing a built-in function.

291 |

A function call is said to be dynamic if the target of the call is determined while the script is running, instead of before the script starts. The same syntax is used as for normal function calls; the only apparent difference is that certain error-checking is performed at load time for non-dynamic calls but only at run time for dynamic calls.

292 |

For example, MyFunc() would call the function object contained by MyFunc, which could be either the actual name of a function, or just a variable which has been assigned a function.

293 |

Other expressions can be used as the target of a function call, including double-derefs. For example, MyArray[1]() would call the function contained by the first element of MyArray, while %MyVar%() would call the function contained by the variable whose name is contained by MyVar. In other words, the expression preceding the parameter list is first evaluated to get a function object, then that object is called.

294 |

If the target value cannot be called due to one of the reasons below, an Error is thrown:

295 | 300 |

The caller of a function should generally know what each parameter means and how many there are before calling the function. However, for dynamic calls, the function is often written to suit the function call, and in such cases failure might be caused by a mistake in the function definition rather than incorrect parameter values.

301 | 302 |

Short-circuit Boolean Evaluation

303 |

When AND, OR, and the ternary operator are used within an expression, they short-circuit to enhance performance (regardless of whether any function calls are present). Short-circuiting operates by refusing to evaluate parts of an expression that cannot possibly affect its final result. To illustrate the concept, consider this example:

304 |
if (ColorName != "" AND not FindColor(ColorName))
305 |     MsgBox ColorName " could not be found."
306 |

In the example above, the FindColor() function never gets called if the ColorName variable is empty. This is because the left side of the AND would be false, and thus its right side would be incapable of making the final outcome true.

307 |

Because of this behavior, it's important to realize that any side-effects produced by a function (such as altering a global variable's contents) might never occur if that function is called on the right side of an AND or OR.

308 |

It should also be noted that short-circuit evaluation cascades into nested ANDs and ORs. For example, in the following expression, only the leftmost comparison occurs whenever ColorName is blank. This is because the left side would then be enough to determine the final answer with certainty:

309 |
if (ColorName = "" OR FindColor(ColorName, Region1) OR FindColor(ColorName, Region2))
310 |     break   ; Nothing to search for, or a match was found.
311 |

As shown by the examples above, any expensive (time-consuming) functions should generally be called on the right side of an AND or OR to enhance performance. This technique can also be used to prevent a function from being called when one of its parameters would be passed a value it considers inappropriate, such as an empty string.

312 |

The ternary conditional operator (?:) also short-circuits by not evaluating the losing branch.

313 | 314 |

Nested Functions

315 |

A nested function is one defined inside another function. For example:

316 |
317 | outer(x) {
318 |     inner(y) {
319 |         MsgBox(y, x)
320 |     }
321 |     inner("one")
322 |     inner("two")
323 | }
324 | outer("title")
325 | 
326 |

A nested function is not accessible by name outside of the function which immediately encloses it, but is accessible anywhere inside that function, including inside other nested functions (with exceptions).

327 |

By default, a nested function may access any static variable of any function which encloses it, even dynamically. However, a non-dynamic assignment inside a nested function typically resolves to a local variable if the outer function has neither a declaration nor a non-dynamic assignment for that variable.

328 |

By default, a nested function automatically "captures" a non-static local variable of an outer function when the following requirements are met:

329 |
    330 |
  1. The outer function must refer to the variable in at least one of the following ways: 331 |
      332 |
    1. By declaring it with local, or as a parameter or nested function.
    2. 333 |
    3. As the non-dynamic target of an assignment or the reference operator (&).
    4. 334 |
    335 |
  2. 336 |
  3. The inner function (or a function nested inside it) must refer to the variable non-dynamically.
  4. 337 |
338 |

A nested function which has captured variables is known as a closure.

339 |

Non-static local variables of the outer function cannot be accessed dynamically unless they have been captured.

340 |

Explicit declarations always take precedence over local variables of the function which encloses them. For example, local x declares a variable local to the current function, independent of any x in the outer function. Global declarations in the outer function also affect nested functions, except where overridden by an explicit declaration.

341 |

If a function is declared assume-global, any local or static variables created outside that function are not directly accessible to the function itself or any of its nested functions. By contrast, a nested function which is assume-static can still refer to variables from the outer function, unless the function itself is declared static.

342 |

Functions are assume-local by default, and this is true even for nested functions, even those inside an assume-static function. However, if the outer function is assume-global, nested functions behave as though assume-global by default, except that they can refer to local and static variables of the outer function.

343 |

Each function definition creates a read-only variable containing the function itself; that is, a Func or Closure object. See below for examples of how this might be used.

344 | 345 |

Static Functions

346 |

Any nested function which does not capture variables is automatically static; that is, every call to the outer function references the same Func. The keyword static can be used to explicitly declare a nested function as static, in which case any non-static local variables of the outer function are ignored. For example:

347 |
outer() {
348 |     x := "outer value"
349 |     static inner() {
350 |         x := "inner value"  ; Creates a variable local to inner
351 |         MsgBox type(inner)  ; Displays "Func"
352 |     }
353 |     inner()
354 |     MsgBox x  ; Displays "outer value"
355 | }
356 | outer()
357 |

A static function cannot refer to other nested functions outside its own body unless they are explicitly declared static. Note that even if the function is assume-static, a non-static nested function may become a closure if it references a function parameter.

358 | 359 |

Closures

360 |

A closure is a nested function bound to a set of free variables. Free variables are local variables of the outer function which are also used by nested functions. Closures allow one or more nested functions to share variables with the outer function even after the outer function returns.

361 |

To create a closure, simply define a nested function which refers to variables of the outer function. For example:

362 |
363 | make_greeter(f)
364 | {
365 |     greet(subject)  ; This will be a closure due to f.
366 |     {
367 |         MsgBox Format(f, subject)
368 |     }
369 |     return greet  ; Return the closure.
370 | }
371 | 
372 | g := make_greeter("Hello, {}!")
373 | g(A_UserName)
374 | g("World")
375 | 
376 |

Closures may also be used with built-in functions, such as SetTimer or Hotkey. For example:

377 |
378 | app_hotkey(keyname, app_title, app_path)
379 | {
380 |     activate(keyname)  ; This will be a closure due to app_title and app_path.
381 |     {
382 |         if WinExist(app_title)
383 |             WinActivate
384 |         else
385 |             Run app_path
386 |     }
387 |     Hotkey keyname, activate
388 | }
389 | ; Win+N activates or launches Notepad.
390 | app_hotkey "#n", "ahk_class Notepad", "notepad.exe"
391 | ; Win+W activates or launches WordPad.
392 | app_hotkey "#w", "ahk_class WordPadClass", "wordpad.exe"
393 | 
394 |

A nested function is automatically a closure if it captures any non-static local variables of the outer function. The variable corresponding to the closure itself (such as activate) is also a non-static local variable, so any nested functions which refer to a closure are automatically closures.

395 |

Each call to the outer function creates new closures, distinct from any previous calls.

396 |

It is best not to store a reference to a closure in any of the outer function's free variables, since that creates a reference cycle which must be broken (such as by clearing the variable) before the closure can be freed. However, a closure may safely refer to itself and other closures by their original variables without creating a problematic reference cycle. For example:

397 |
398 | timertest() {
399 |     x := "tock!"
400 |     tick() {
401 |         MsgBox x           ; x causes this to become a closure.
402 |         SetTimer tick, 0   ; Using the closure's original var is safe.
403 |         ; SetTimer t, 0    ; Capturing t would create a reference cycle.
404 |     }
405 |     t := tick              ; This is okay because t isn't captured above.
406 |     SetTimer t, 1000
407 | }
408 | timertest()
409 | 
410 |

Each time the outer function is called, all of its free variables are allocated as a set. This one set of free variables is linked to all of the function's closures. If the closure's original variable (tick in the example above) is captured by another closure within the same function, its lifetime is bound to the set. The set is deleted only when no references exist to any of its closures, except those in the original variables. This allows closures to refer to each other without causing a problematic reference cycle.

411 |

Closures which are not captured by other closures can be deleted before the set. All of the free variables within the set, including captured closures, cannot be deleted while such a closure exists.

412 | 413 |

Return, Exit, and General Remarks

414 |

If the flow of execution within a function reaches the function's closing brace prior to encountering a Return, the function ends and returns a blank value (empty string) to its caller. A blank value is also returned whenever the function explicitly omits Return's parameter.

415 |

When a function uses Exit to terminate the current thread, its caller does not receive a return value at all. For example, the statement Var := Add(2, 3) would leave Var unchanged if Add() exits. The same thing happens if the function is exited because of Throw or a runtime error (such as running a nonexistent file).

416 |

To call a function with one or more blank values (empty strings), use an empty pair of quotes as in this example: FindColor(ColorName, "").

417 |

Since calling a function does not start a new thread, any changes made by a function to settings such as SendMode and SetTitleMatchMode will go into effect for its caller too.

418 |

When used inside a function, ListVars displays a function's local variables along with their contents. This can help debug a script.

419 |

Style and Naming Conventions

420 |

You might find that complex functions are more readable and maintainable if their special variables are given a distinct prefix. For example, naming each parameter in a function's parameter list with a leading "p" or "p_" makes their special nature easy to discern at a glance, especially when a function has several dozen local variables competing for your attention. Similarly, the prefix "r" or "r_" could be used for ByRef parameters, and "s" or "s_" could be used for static variables.

421 |

The One True Brace (OTB) style may optionally be used to define functions. For example:

422 |
Add(x, y) {
423 |     return x + y
424 | }
425 | 426 |

Using #Include to Share Functions Among Multiple Scripts

427 |

The #Include directive may be used to load functions from an external file.

428 | 429 |

Built-in Functions

430 |

A built-in function is overridden if the script defines its own function of the same name. For example, a script could have its own custom WinExist function that is called instead of the standard one. However, the script would then have no way to call the original function.

431 |

External functions that reside in DLL files may be called with DllCall.

432 |

To get a list of all built-in functions, see Alphabetical Function Index.

433 | 434 | 435 | -------------------------------------------------------------------------------- /docs/HotkeyFeatures.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Advanced Hotkey Features | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Advanced Hotkey Features

14 | 15 | 16 |

Table of Contents

17 | 39 | 40 |

General

41 | 42 |

Remap easy to reach but rarely used keys

43 |

Some of the easiest keys to reach on the keyboard are also the least frequently used. Make these keys do something useful! For example, if you rarely use the right Alt, make it perform the action you do most often:

44 |
RAlt::MsgBox "You pressed the right ALT key."
45 |

You can even do the above without losing the native function of the right Alt by assigning the right Alt to be a "prefix" for at least one other hotkey. In the below example, the right Alt has become a prefix, which automatically allows it to modify all other keys as it normally would. But if you press and release the right Alt without having used it to modify another key, its hotkey action (above) will take effect immediately:

46 |
RAlt & j::AltTab
47 | 48 |

Use any keys as modifiers

49 |

Don't be limited to using only Ctrl, Alt, Shift, and Win as modifiers; you can combine any two keys or mouse buttons to form a custom hotkey. For example: Hold down Numpad0 and press Numpad1 to launch a hotkey (Numpad0 & Numpad1::); hold down CapsLock and press another key, or click a mouse button (CapsLock & RButton::). In this case, CapsLock's state (on or off) is not changed when it is used to launch the hotkey. For details, see custom combinations of keys.

50 | 51 |

Make the mouse wheel perform alt-tabbing

52 |

Convert the mouse wheel (or any other keys of your choice) into a complete substitute for Alt-Tab. Click the wheel to show or hide the menu, and turn it to navigate through the menu. The wheel will still function normally whenever the Alt-Tab menu isn't visible. Syntax:

53 |
MButton::AltTabMenu
 54 | WheelDown::AltTab
 55 | WheelUp::ShiftAltTab
56 | 57 |

Make a keyboard key become a mouse button

58 |

Make a keyboard key become a mouse button, or have an action repeated continuously while you're holding down a key or mouse button. See the remapping page for examples.

59 | 60 |

Make your hotkeys context-sensitive

61 |

Have your easiest-to-reach hotkeys perform an action appropriate to the type of window you're working with. In the following example, the right Ctrl performs a different action depending on whether Notepad or Calculator is the active window:

62 |
#HotIf WinActive("ahk_class Notepad")
 63 | RControl::Send "^s"  ; Save the current file in Notepad.
 64 | 
 65 | #HotIf WinActive("Calculator")
 66 | RControl::Send "^c!{tab}^v"  ; Copy the Calculator's result into the previously active window.
67 |

See #HotIf for details.

68 | 69 |

Define abbreviations that expand as you type them

70 |

Also known as hotstrings. No special training or scripting experience is needed. For example, a script containing the following lines would expand ceo, cfo, and btw wherever you type them:

71 |
::ceo::Chief Executive Officer
 72 | ::cfo::Chief Financial Officer
 73 | ::btw::by the way
74 | 75 |

Gaming

76 | 77 |

Reduce wear and tear on your fingers

78 |

Reduce wear and tear on your fingers by using virtually any key as a hotkey, including single letters, arrow keys, Numpad keys, and even the modifier keys themselves (Ctrl, Alt, Win, and Shift).

79 | 80 |

Create mouse hotkeys

81 |

Create mouse hotkeys, including the mouse wheel button (MButton) and the turning of the wheel up/down or left/right (WheelUp, WheelDown, WheelLeft, and WheelRight). You can also combine a keyboard key with a mouse button. For example, control-right-button would be expressed as ^RButton::.

82 | 83 |

Create "pass-through" hotkeys

84 |

For example, the left mouse button can trigger a hotkey action even while the click itself is being sent into the game normally (syntax: ~LButton::).

85 | 86 |

Automate game actions on the screen

87 |

Use functions such as PixelSearch, PixelGetColor, and ImageSearch to automate game actions.

88 | 89 |

Use the keyboard hook

90 |

Have the option of using the keyboard hook to implement hotkeys, which might be more responsive than other hotkey methods while the CPU is under load in a game. The hook might also be able to override any restrictions a game may have about which keys can be "mapped" to game actions.

91 | 92 | 93 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /docs/Hotkeys.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hotkeys - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Hotkeys (Mouse, Controller and Keyboard Shortcuts)

15 | 16 | 17 |

Table of Contents

18 | 29 | 30 |

Introduction and Simple Examples

31 |

Hotkeys are sometimes referred to as shortcut keys because of their ability to easily trigger an action (such as launching a program or keyboard macro). In the following example, the hotkey Win+N is configured to launch Notepad. The pound sign [#] stands for Win, which is known as a modifier key:

32 |
#n::
 33 | {
 34 |     Run "notepad"
 35 | }
36 |

In the above, the braces serve to define a function body for the hotkey. The opening brace may also be specified on the same line as the double-colon to support the OTB (One True Brace) style. However, if a hotkey needs to execute only a single line, that line can be listed to the right of the double-colon. In other words, the braces are implicit:

37 |
#n::Run "notepad"
38 |

When a hotkey is triggered, the name of the hotkey is passed as its first parameter named ThisHotkey (which excludes the trailing colons). For example:

39 |
#n::MsgBox ThisHotkey  ; Reports #n
40 |

With few exceptions, this is similar to the built-in variable A_ThisHotkey. The parameter name can be changed by using a named function.

41 |

To use more than one modifier with a hotkey, list them consecutively (the order does not matter). The following example uses ^!s to indicate Ctrl+Alt+S:

42 |
^!s::
 43 | {
 44 |     Send "Sincerely,{enter}John Smith"  ; This line sends keystrokes to the active (foremost) window.
 45 | }
46 |

Hotkey Modifier Symbols

47 |

You can use the following modifier symbols to define hotkeys:

48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 60 | 61 | 62 | 63 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 95 | 96 | 97 | 98 | 102 | 103 | 104 | 105 | 118 | 119 | 120 | 121 | 126 | 127 | 128 | 129 | 139 | 140 |
SymbolDescription
# 56 |

Win (Windows logo key).

57 |

Hotkeys that include Win (e.g. #a) will wait for Win to be released before sending any text containing an L keystroke. This prevents usages of Send within such a hotkey from locking the PC. This behavior applies to all sending modes except SendPlay (which doesn't need it), blind mode and text mode.

58 |

Note: Pressing a hotkey which includes Win may result in extra simulated keystrokes (Ctrl by default). See A_MenuMaskKey.

59 |
! 64 |

Alt

65 |

Note: Pressing a hotkey which includes Alt may result in extra simulated keystrokes (Ctrl by default). See A_MenuMaskKey.

66 |
^Ctrl
+Shift
&An ampersand may be used between any two keys or mouse buttons to combine them into a custom hotkey. See below for details.
<Use the left key of the pair. e.g. <!a is the same as !a except that only the left Alt will trigger it.
>Use the right key of the pair.
<^>!

AltGr (alternate graph, or alternate graphic). If your keyboard layout has AltGr instead of a right Alt key, this series of symbols can usually be used to stand for AltGr. For example:

91 |
<^>!m::MsgBox "You pressed AltGr+m."
 92 | <^<!m::MsgBox "You pressed LeftControl+LeftAlt+m."
93 |

Alternatively, to make AltGr itself into a hotkey, use the following hotkey (without any hotkeys like the above present):

94 |
LControl & RAlt::MsgBox "You pressed AltGr itself."
*

Wildcard: Fire the hotkey even if extra modifiers are being held down. This is often used in conjunction with remapping keys or buttons. For example:

99 |
*#c::Run "calc.exe"  ; Win+C, Shift+Win+C, Ctrl+Win+C, etc. will all trigger this hotkey.
100 | *ScrollLock::Run "notepad"  ; Pressing ScrollLock will trigger this hotkey even when modifier key(s) are down.
101 |

Wildcard hotkeys always use the keyboard hook, as do any hotkeys eclipsed by a wildcard hotkey. For example, the presence of *a:: would cause ^a:: to always use the hook.

~

When the hotkey fires, its key's native function will not be blocked (hidden from the system). In both of the below examples, the user's click of the mouse button will be sent to the active window:

106 |
~RButton::MsgBox "You clicked the right mouse button."
107 | ~RButton & C::MsgBox "You pressed C while holding down the right mouse button."
108 |

Unlike the other prefix symbols, the tilde prefix is allowed to be present on some of a hotkey's variants but absent on others. However, if a tilde is applied to the prefix key of any custom combination which has not been turned off or suspended, it affects the behavior of that prefix key for all combinations.

109 |

Special hotkeys that are substitutes for alt-tab always ignore the tilde prefix.

110 |

If the tilde prefix is applied to a custom modifier key (prefix key) which is also used as its own hotkey, that hotkey will fire when the key is pressed instead of being delayed until the key is released. For example, the ~RButton hotkey above is fired as soon as the button is pressed.

111 |

If the tilde prefix is applied only to the custom combination and not the non-combination hotkey, the key's native function will still be blocked. For example, in the script below, holding Menu will show the tooltip and will not trigger a context menu:

112 |
AppsKey::ToolTip "Press < or > to cycle through windows."
113 | AppsKey Up::ToolTip
114 | ~AppsKey & <::Send "!+{Esc}"
115 | ~AppsKey & >::Send "!{Esc}"
116 |

If at least one variant of a keyboard hotkey has the tilde modifier, that hotkey always uses the keyboard hook.

117 |
$ 122 |

This is usually only necessary if the script uses the Send function to send the keys that comprise the hotkey itself, which might otherwise cause it to trigger itself. The $ prefix forces the keyboard hook to be used to implement this hotkey, which as a side-effect prevents the Send function from triggering it. The $ prefix is equivalent to having specified #UseHook somewhere above the definition of this hotkey.

123 |

The $ prefix has no effect for mouse hotkeys, since they always use the mouse hook. It also has no effect for hotkeys which already require the keyboard hook, including any keyboard hotkeys with the tilde (~) or wildcard (*) modifiers, key-up hotkeys and custom combinations. To determine whether a particular hotkey uses the keyboard hook, use ListHotkeys.

124 |

#InputLevel and SendLevel provide additional control over which hotkeys and hotstrings are triggered by the Send function.

125 |
UP

The word UP may follow the name of a hotkey to cause the hotkey to fire upon release of the key rather than when the key is pressed down. The following example remaps the left Win to become the left Ctrl:

130 |
*LWin::Send "{LControl down}"
131 | *LWin Up::Send "{LControl up}"
132 | 
133 |

"Up" can also be used with normal hotkeys as in this example: ^!r Up::MsgBox "You pressed and released Ctrl+Alt+R". It also works with combination hotkeys (e.g. F1 & e Up::)

134 |

Limitations: 1) "Up" does not work with controller buttons; and 2) An "Up" hotkey without a normal/down counterpart hotkey will completely take over that key to prevent it from getting stuck down. One way to prevent this is to add a tilde prefix (e.g. ~LControl up::)

135 |

"Up" hotkeys and their key-down counterparts (if any) always use the keyboard hook.

136 |

On a related note, a technique similar to the above is to make a hotkey into a prefix key. The advantage is that although the hotkey will fire upon release, it will do so only if you did not press any other key while it was held down. For example:

137 |
LControl & F1::return  ; Make left-control a prefix by using it in front of "&" at least once.
138 | LControl::MsgBox "You released LControl without having used it to modify any other key."
141 |

Note: See the Key List for a complete list of keyboard keys and mouse/controller buttons.

142 |

Multiple hotkeys can be stacked vertically to have them perform the same action. For example:

143 |
^Numpad0::
144 | ^Numpad1::
145 | {
146 |     MsgBox "Pressing either Ctrl+Numpad0 or Ctrl+Numpad1 will display this."
147 | }
148 | 
149 |

A key or key-combination can be disabled for the entire system by having it do nothing. The following example disables the right-side Win:

150 |
RWin::return
151 | 152 |

Context-sensitive Hotkeys

153 |

The #HotIf directive can be used to make a hotkey perform a different action (or none at all) depending on a specific condition. For example:

154 |
#HotIf WinActive("ahk_class Notepad")
155 | ^a::MsgBox "You pressed Ctrl-A while Notepad is active. Pressing Ctrl-A in any other window will pass the Ctrl-A keystroke to that window."
156 | #c::MsgBox "You pressed Win-C while Notepad is active."
157 | 
158 | #HotIf
159 | #c::MsgBox "You pressed Win-C while any window except Notepad is active."
160 | 
161 | #HotIf MouseIsOver("ahk_class Shell_TrayWnd") ; For MouseIsOver, see #HotIf example 1.
162 | WheelUp::Send "{Volume_Up}"     ; Wheel over taskbar: increase/decrease volume.
163 | WheelDown::Send "{Volume_Down}" ;
164 | 
165 | 166 |

Custom Combinations

167 |

Normally shortcut key combinations consist of optional prefix/modifier keys (Ctrl, Alt, Shift and LWin/RWin) and a single suffix key. The standard modifier keys are designed to be used in this manner, so normally have no immediate effect when pressed down.

168 |

A custom combination of two keys (including mouse but not controller buttons) can be defined by using " & " between them. Because they are intended for use with prefix keys that are not normally used as such, custom combinations have the following special behavior:

169 | 173 |

Note: For combinations with standard modifier keys, it is usually better to use the standard syntax. For example, use <+s:: rather than LShift & s::.

174 |

In the below example, you would hold down Numpad0 then press the second key to trigger the hotkey:

175 |
Numpad0 & Numpad1::MsgBox "You pressed Numpad1 while holding down Numpad0."
176 | Numpad0 & Numpad2::Run "Notepad"
177 |

The prefix key loses its native function: In the above example, Numpad0 becomes a prefix key; but this also causes Numpad0 to lose its original/native function when it is pressed by itself. To avoid this, a script may configure Numpad0 to perform a new action such as one of the following:

178 |
Numpad0::WinMaximize "A"   ; Maximize the active/foreground window.
179 | Numpad0::Send "{Numpad0}"  ; Make the release of Numpad0 produce a Numpad0 keystroke. See comment below.
180 |

Fire on release: The presence of one of the above custom combination hotkeys causes the release of Numpad0 to perform the indicated action, but only if you did not press any other keys while Numpad0 was being held down. This behaviour can be avoided by applying the tilde prefix to either hotkey.

181 |

Modifiers: Unlike a normal hotkey, custom combinations act as though they have the wildcard (*) modifier by default. For example, 1 & 2:: will activate even if Ctrl or Alt is held down when 1 and 2 are pressed, whereas ^1:: would be activated only by Ctrl+1 and not Ctrl+Alt+1.

182 |

Combinations of three or more keys are not supported. Combinations which your keyboard hardware supports can usually be detected by using #HotIf and GetKeyState, but the results may be inconsistent. For example:

183 |
; Press AppsKey and Alt in any order, then slash (/).
184 | #HotIf GetKeyState("AppsKey", "P")
185 | Alt & /::MsgBox "Hotkey activated."
186 | 
187 | ; If the keys are swapped, Alt must be pressed first (use one at a time):
188 | #HotIf GetKeyState("Alt", "P")
189 | AppsKey & /::MsgBox "Hotkey activated."
190 | 
191 | ; [ & ] & \::
192 | #HotIf GetKeyState("[") && GetKeyState("]")
193 | \::MsgBox
194 |

Keyboard hook: Custom combinations involving keyboard keys always use the keyboard hook, as do any hotkeys which use the prefix key as a suffix. For example, a & b:: causes ^a:: to always use the hook.

195 | 196 |

Other Features

197 |

NumLock, CapsLock, and ScrollLock: These keys may be forced to be "AlwaysOn" or "AlwaysOff". For example: SetNumLockState "AlwaysOn".

198 |

Overriding Explorer's hotkeys: Windows' built-in hotkeys such as Win+E (#e) and Win+R (#r) can be individually overridden simply by assigning them to an action in the script. See the override page for details.

199 |

Substitutes for Alt-Tab: Hotkeys can provide an alternate means of alt-tabbing. For example, the following two hotkeys allow you to alt-tab with your right hand:

200 |
RControl & RShift::AltTab  ; Hold down right-control then press right-shift repeatedly to move forward.
201 | RControl & Enter::ShiftAltTab  ; Without even having to release right-control, press Enter to reverse direction.
202 |

For more details, see Alt-Tab.

203 | 204 |

Mouse Wheel Hotkeys

205 |

Hotkeys that fire upon turning the mouse wheel are supported via the key names WheelDown and WheelUp. Here are some examples of mouse wheel hotkeys:

206 |
MButton & WheelDown::MsgBox "You turned the mouse wheel down while holding down the middle button."
207 | ^!WheelUp::MsgBox "You rotated the wheel up while holding down Control+Alt."
208 |

If the mouse supports it, horizontal scrolling can be detected via the key names WheelLeft and WheelRight. Some mice have a single wheel which can be scrolled up and down or tilted left and right. Generally in those cases, WheelLeft or WheelRight signals are sent repeatedly while the wheel is held to one side, to simulate continuous scrolling. This typically causes the hotkeys to execute repeatedly.

209 |

The built-in variable A_EventInfo contains the amount by which the wheel was turned, which is typically 120. However, A_EventInfo can be greater or less than 120 under the following circumstances:

210 | 214 |

Some of the most useful hotkeys for the mouse wheel involve alternate modes of scrolling a window's text. For example, the following pair of hotkeys scrolls horizontally instead of vertically when you turn the wheel while holding down the left Ctrl:

215 |
~LControl & WheelUp::  ; Scroll left.
216 | {
217 |     Loop 2  ; <-- Increase this value to scroll faster.
218 |         SendMessage 0x0114, 0, 0, ControlGetFocus("A")  ; 0x0114 is WM_HSCROLL and the 0 after it is SB_LINELEFT.
219 | }
220 | 
221 | ~LControl & WheelDown::  ; Scroll right.
222 | {
223 |     Loop 2  ; <-- Increase this value to scroll faster.
224 |         SendMessage 0x0114, 1, 0, ControlGetFocus("A")  ; 0x0114 is WM_HSCROLL and the 1 after it is SB_LINERIGHT.
225 | }
226 |

Finally, since mouse wheel hotkeys generate only down-events (never up-events), they cannot be used as key-up hotkeys.

227 | 228 |

Hotkey Tips and Remarks

229 |

Each numpad key can be made to launch two different hotkey subroutines depending on the state of NumLock. Alternatively, a numpad key can be made to launch the same subroutine regardless of the state. For example:

230 |
NumpadEnd::
231 | Numpad1::
232 | {
233 |     MsgBox "This hotkey is launched regardless of whether NumLock is on."
234 | }
235 | 
236 |

If the tilde (~) symbol is used with a prefix key even once, it changes the behavior of that prefix key for all combinations. For example, in both of the below hotkeys, the active window will receive all right-clicks even though only one of the definitions contains a tilde:

237 |
~RButton & LButton::MsgBox "You pressed the left mouse button while holding down the right."
238 | RButton & WheelUp::MsgBox "You turned the mouse wheel up while holding down the right button."
239 |

The Suspend function can temporarily disable all hotkeys except for ones you make exempt. For greater selectivity, use #HotIf.

240 |

By means of the Hotkey function, hotkeys can be created dynamically while the script is running. The Hotkey function can also modify, disable, or enable the script's existing hotkeys individually.

241 |

Controller hotkeys do not currently support modifier prefixes such as ^ (Ctrl) and # (Win). However, you can use GetKeyState to mimic this effect as shown in the following example:

242 |
Joy2::
243 | {
244 |     if not GetKeyState("Control")  ; Neither the left nor right Control key is down.
245 |         return  ; i.e. Do nothing.
246 |     MsgBox "You pressed the first controller's second button while holding down the Control key."
247 | }
248 |

There may be times when a hotkey should wait for its own modifier keys to be released before continuing. Consider the following example:

249 |
^!s::Send "{Delete}"
250 |

Pressing Ctrl+Alt+S would cause the system to behave as though you pressed Ctrl+Alt+Del (due to the system's aggressive detection of this hotkey). To work around this, use KeyWait to wait for the keys to be released; for example:

251 |
^!s::
252 | {
253 |     KeyWait "Control"
254 |     KeyWait "Alt"
255 |     Send "{Delete}"
256 | }
257 | 
258 |

If a hotkey like #z:: produces an error like "Invalid Hotkey", your system's keyboard layout/language might not have the specified character ("Z" in this case). Try using a different character that you know exists in your keyboard layout.

259 |

A hotkey's function can be called explicitly by the script only if the function has been named. See Named Function Hotkeys.

260 |

One common use for hotkeys is to start and stop a repeating action, such as a series of keystrokes or mouse clicks. For an example of this, see this FAQ topic.

261 |

Finally, each script is quasi multi-threaded, which allows a new hotkey to be launched even when a previous hotkey subroutine is still running. For example, new hotkeys can be launched even while a message box is being displayed by the current hotkey.

262 | 263 |

Alt-Tab Hotkeys

264 |

Alt-Tab hotkeys simplify the mapping of new key combinations to the system's Alt-Tab hotkeys, which are used to invoke a menu for switching tasks (activating windows).

265 |

Each Alt-Tab hotkey must be either a single key or a combination of two keys, which is typically achieved via the ampersand symbol (&). In the following example, you would hold down the right Alt and press J or K to navigate the alt-tab menu:

266 |
RAlt & j::AltTab
267 | RAlt & k::ShiftAltTab
268 |

AltTab and ShiftAltTab are two of the special commands that are only recognized when used on the same line as a hotkey. Here is the complete list:

269 |

AltTab: If the alt-tab menu is visible, move forward in it. Otherwise, display the menu (only if the hotkey is a combination of two keys; otherwise, it does nothing).

270 |

ShiftAltTab: Same as above except move backward in the menu.

271 |

AltTabMenu: Show or hide the alt-tab menu.

272 |

AltTabAndMenu: If the alt-tab menu is visible, move forward in it. Otherwise, display the menu.

273 |

AltTabMenuDismiss: Close the Alt-tab menu.

274 |

To illustrate the above, the mouse wheel can be made into an entire substitute for Alt-tab. With the following hotkeys in effect, clicking the middle button displays the menu and turning the wheel navigates through it:

275 |
MButton::AltTabMenu
276 | WheelDown::AltTab
277 | WheelUp::ShiftAltTab
278 |

To cancel the Alt-Tab menu without activating the selected window, press or send Esc. In the following example, you would hold the left Ctrl and press CapsLock to display the menu and advance forward in it. Then you would release the left Ctrl to activate the selected window, or press the mouse wheel to cancel. Define the AltTabWindow window group as shown below before running this example.

279 |
LCtrl & CapsLock::AltTab
280 | #HotIf WinExist("ahk_group AltTabWindow")  ; Indicates that the alt-tab menu is present on the screen.
281 | *MButton::Send "{Blind}{Escape}"  ; The * prefix allows it to fire whether or not Alt is held down.
282 | #HotIf
283 |

If the script sent {Alt Down} (such as to invoke the Alt-Tab menu), it might also be necessary to send {Alt Up} as shown in the example further below.

284 | 285 |

General Remarks

286 |

Currently, all special Alt-tab actions must be assigned directly to a hotkey as in the examples above (i.e. they cannot be used as though they were functions). They are not affected by #HotIf.

287 |

An alt-tab action may take effect on key-down and/or key-up regardless of whether the up keyword is used, and cannot be combined with another action on the same key. For example, using both F1::AltTabMenu and F1 up::OtherAction() is unsupported.

288 |

Custom alt-tab actions can also be created via hotkeys. As the identity of the alt-tab menu differs between OS versions, it may be helpful to use a window group as shown below. For the examples above and below which use ahk_group AltTabWindow, this window group is expected to be defined during script startup. Alternatively, ahk_group AltTabWindow can be replaced with the appropriate ahk_class for your system.

289 |
GroupAdd "AltTabWindow", "ahk_class MultitaskingViewFrame"  ; Windows 10
290 | GroupAdd "AltTabWindow", "ahk_class TaskSwitcherWnd"  ; Windows Vista, 7, 8.1
291 | GroupAdd "AltTabWindow", "ahk_class #32771"  ; Older, or with classic alt-tab enabled
292 |

In the following example, you would press F1 to display the menu and advance forward in it. Then you would press F2 to activate the selected window, or press Esc to cancel:

293 |
*F1::Send "{Alt down}{tab}" ; Asterisk is required in this case.
294 | !F2::Send "{Alt up}"  ; Release the Alt key, which activates the selected window.
295 | #HotIf WinExist("ahk_group AltTabWindow")
296 | ~*Esc::Send "{Alt up}"  ; When the menu is cancelled, release the Alt key automatically.
297 | ;*Esc::Send "{Esc}{Alt up}"  ; Without tilde (~), Escape would need to be sent.
298 | #HotIf
299 | 300 |

Named Function Hotkeys

301 |

If the function of a hotkey is ever needed to be called without triggering the hotkey itself, one or more hotkeys can be assigned a named function by simply defining it immediately after the hotkey's double-colon as in this example:

302 |
; Ctrl+Shift+O to open containing folder in Explorer.
303 | ; Ctrl+Shift+E to open folder with current file selected.
304 | ; Supports SciTE and Notepad++ (may require title bar setting changes).
305 | ^+o::
306 | ^+e::
307 |     editor_open_folder(hk)
308 |     {
309 |         path := WinGetTitle("A")
310 |         if RegExMatch(path, "\*?\K(.*)\\[^\\]+(?= [-*] )", &path)
311 |             if (FileExist(path[0]) && hk = "^+e")
312 |                 Run Format('explorer.exe /select,"{1}"', path[0])
313 |             else
314 |                 Run Format('explorer.exe "{1}"', path[1])
315 |     }
316 |

If the function editor_open_folder is ever called explicitly by the script, the first parameter (hk) must be passed a value.

317 |

Hotstrings can also be defined this way. Multiple hotkeys or hotstrings can be stacked together to call the same function.

318 |

There must only be whitespace or comments between the hotkey and the function name.

319 |

Naming the function also encourages self-documenting hotkeys, like in the code above where the function name describes the hotkey.

320 |

The Hotkey function can also be used to assign a function or function object to a hotkey.

321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /docs/Hotstrings.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hotstrings - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Hotstrings

15 | 16 |

Table of Contents

17 | 28 | 29 |

Introduction and Simple Examples

30 |

Although hotstrings are mainly used to expand abbreviations as you type them (auto-replace), they can also be used to launch any scripted action. In this respect, they are similar to hotkeys except that they are typically composed of more than one character (that is, a string).

31 |

To define a hotstring, enclose the triggering abbreviation between pairs of colons as in this example:

32 |
::btw::by the way
33 |

In the above example, the abbreviation btw will be automatically replaced with "by the way" whenever you type it (however, by default you must type an ending character after typing btw, such as Space, ., or Enter).

34 |

The "by the way" example above is known as an auto-replace hotstring because the typed text is automatically erased and replaced by the string specified after the second pair of colons. By contrast, a hotstring may also be defined to perform any custom action as in the following examples. Note that the statements must appear beneath the abbreviation within the hotstring's function body:

35 |
::btw::
 36 | {
 37 |     MsgBox 'You typed "btw".'
 38 | }
 39 | 
 40 | :*:]d::  ; This hotstring replaces "]d" with the current date and time via the statement below.
 41 | {
 42 |     Send FormatTime(, "M/d/yyyy h:mm tt")  ; It will look like 9/1/2005 3:53 PM
 43 | }
44 |

In the above, the braces serve to define a function body for each hotstring. The opening brace may also be specified on the same line as the double-colon to support the OTB (One True Brace) style.

45 |

Even though the two examples above are not auto-replace hotstrings, the abbreviation you type is erased by default. This is done via automatic backspacing, which can be disabled via the b0 option.

46 |

When a hotstring is triggered, the name of the hotstring is passed as its first parameter named ThisHotkey (which excludes the trailing colons). For example:

47 |
:X:btw::MsgBox ThisHotkey  ; Reports :X:btw
48 |

With few exceptions, this is similar to the built-in variable A_ThisHotkey. The parameter name can be changed by using a named function.

49 | 50 |

Ending Characters

51 |

Unless the asterisk option is in effect, you must type an ending character after a hotstring's abbreviation to trigger it. Ending characters initially consist of the following: -()[]{}':;"/\,.?!`n`s`t (note that `n is Enter, `s is Space, and `t is Tab). This set of characters can be changed by editing the following example, which sets the new ending characters for all hotstrings, not just the ones beneath it:

52 |
#Hotstring EndChars -()[]{}:;'"/\,.?!`n`s`t
53 |

The ending characters can be changed while the script is running by calling the Hotstring function as demonstrated below:

54 |
Hotstring("EndChars", "-()[]{}:;")
55 | 56 |

Options

57 |

A hotstring's default behavior can be changed in two possible ways:

58 |
    59 |
  1. The #Hotstring directive, which affects all hotstrings physically beneath that point in the script. The following example puts the C and R options into effect: #Hotstring c r.
  2. 60 |
  3. Putting options inside a hotstring's first pair of colons. The following example puts the C and * options (case-sensitive and "ending character not required") into effect for a single hotstring: :c*:j@::john@somedomain.com.
  4. 61 |
62 |

The list below describes each option. When specifying more than one option using the methods above, spaces optionally may be included between them.

63 |

* (asterisk): An ending character (e.g. Space, ., or Enter) is not required to trigger the hotstring. For example:

64 |
:*:j@::jsmith@somedomain.com
65 |

The example above would send its replacement the moment you type the @ character. When using the #Hotstring directive, use *0 to turn this option back off.

66 |

? (question mark): The hotstring will be triggered even when it is inside another word; that is, when the character typed immediately before it is alphanumeric. For example, if :?:al::airline is a hotstring, typing "practical " would produce "practicairline ". Use ?0 to turn this option back off.

67 |

B0 (B followed by a zero): Automatic backspacing is not done to erase the abbreviation you type. Use a plain B to turn backspacing back on after it was previously turned off. A script may also do its own backspacing via {bs 5}, which sends Backspace five times. Similarly, it may send five times via {left 5}. For example, the following hotstring produces "<em></em>" and moves the caret 5 places to the left (so that it's between the tags):

68 |
:*b0:<em>::</em>{left 5}
69 |

C: Case-sensitive: When you type an abbreviation, it must exactly match the case defined in the script. Use C0 to turn case sensitivity back off.

70 |

C1: Do not conform to typed case. Use this option to make auto-replace hotstrings case-insensitive and prevent them from conforming to the case of the characters you actually type. Case-conforming hotstrings (which are the default) produce their replacement text in all caps if you type the abbreviation in all caps. If you type the first letter in caps, the first letter of the replacement will also be capitalized (if it is a letter). If you type the case in any other way, the replacement is sent exactly as defined. When using the #Hotstring directive, C0 can be used to turn this option back off, which makes hotstrings conform again.

71 |

Kn: Key-delay: This rarely-used option sets the delay between keystrokes produced by auto-backspacing or auto-replacement. Specify the new delay for n; for example, specify k10 to have a 10 ms delay and k-1 to have no delay. The exact behavior of this option depends on which sending mode is in effect:

72 | 77 |

O: Omit the ending character of auto-replace hotstrings when the replacement is produced. This is useful when you want a hotstring to be kept unambiguous by still requiring an ending character, but don't actually want the ending character to be shown on the screen. For example, if :o:ar::aristocrat is a hotstring, typing "ar" followed by the spacebar will produce "aristocrat" with no trailing space, which allows you to make the word plural or possessive without having to press Backspace. Use O0 (the letter O followed by a zero) to turn this option back off.

78 |

Pn: The priority of the hotstring (e.g. P1). This rarely-used option has no effect on auto-replace hotstrings.

79 |

R: Send the replacement text raw; that is, without translating {Enter} to Enter, ^c to Ctrl+C, etc. Use R0 to turn this option back off, or override it with T.

80 |

Note: Text mode may be more reliable. The R and T options are mutually exclusive.

81 |

S or S0: Specify the letter S to make the hotstring exempt from Suspend. Specify S0 (S with the number 0) to remove the exemption, allowing the hotstring to be suspended. When applied as a default option, either S or #SuspendExempt will make the hotstring exempt; that is, to override the directive, S0 must be used explicitly in the hotstring.

82 |

SI or SP or SE: Sets the method by which auto-replace hotstrings send their keystrokes. These options are mutually exclusive: only one can be in effect at a time. The following describes each option:

83 | 88 |

If none of the above options are used, the default mode is SendInput. However, unlike the SI option, SendEvent is used instead of SendPlay when SendInput is unavailable.

89 |

T: Send the replacement text using Text mode. That is, send each character by character code, without translating {Enter} to Enter, ^c to Ctrl+C, etc. and without translating each character to a keystroke. This option is put into effect automatically for hotstrings that have a continuation section. Use T0 or R0 to turn this option back off, or override it with R.

90 |

X: Execute. Instead of replacement text, the hotstring accepts a function call or expression to execute. For example, :X:~mb::MsgBox would cause a message box to be displayed when the user types "~mb" instead of auto-replacing it with the word "MsgBox". This is most useful when defining a large number of hotstrings which call functions, as it would otherwise require three lines per hotstring.

91 |

This option should not be used with the Hotstring function. To make a hotstring call a function when triggered, pass the function by reference.

92 |

Z: This rarely-used option resets the hotstring recognizer after each triggering of the hotstring. In other words, the script will begin waiting for an entirely new hotstring, eliminating from consideration anything you previously typed. This can prevent unwanted triggerings of hotstrings. To illustrate, consider the following hotstring:

93 |
:b0*?:11::
 94 | {
 95 |     Send "xx"
 96 | }
97 |

Since the above lacks the Z option, typing 111 (three consecutive 1's) would trigger the hotstring twice because the middle 1 is the last character of the first triggering but also the first character of the second triggering. By adding the letter Z in front of b0, you would have to type four 1's instead of three to trigger the hotstring twice. Use Z0 to turn this option back off.

98 |

Long Replacements

99 |

Hotstrings that produce a large amount of replacement text can be made more readable and maintainable by using a continuation section. For example:

100 |
::text1::
101 | (
102 | Any text between the top and bottom parentheses is treated literally.
103 | By default, the hard carriage return (Enter) between the previous line and this one is also preserved.
104 |     By default, the indentation (tab) to the left of this line is preserved.
105 | )
106 |

See continuation section for how to change these default behaviors. The presence of a continuation section also causes the hotstring to default to Text mode. The only way to override this special default is to specify an opposing option in each hotstring that has a continuation section (e.g. :t0:text1:: or :r:text2::).

107 |

Context-sensitive Hotstrings

108 |

The #HotIf directive can be used to make selected hotstrings context sensitive. Such hotstrings send a different replacement, perform a different action, or do nothing at all depending on any condition, such as the type of window that is active. For example:

109 |
#HotIf WinActive("ahk_class Notepad")
110 | ::btw::This replacement text will appear only in Notepad.
111 | #HotIf
112 | ::btw::This replacement text appears in windows other than Notepad.
113 | 114 |

AutoCorrect

115 |

The following script uses hotstrings to correct about 4700 common English misspellings on-the-fly. It also includes a Win+H hotkey to make it easy to add more misspellings:

116 |

Download: AutoCorrect.ahk (127 KB)

117 |

Author: Jim Biancolo and Wikipedia's Lists of Common Misspellings

118 | 119 |

Remarks

120 |

Expressions are not currently supported within the replacement text. To work around this, don't make such hotstrings auto-replace. Instead, use the Send function in the body of the hotstring or in combination with the X (execute) option.

121 |

To send an extra space or tab after a replacement, include the escape sequence `s or `t at the end of the replacement, e.g. :*:btw::by the way`s.

122 |

For an auto-replace hotstring which doesn't use the Text or Raw mode, sending a { alone, or one preceded only by white-space, requires it being enclosed in a pair of brackets, for example :*:brace::{{} and :*:space_brace:: {{}. Otherwise it is interpreted as the opening brace for the hotstring's function to support the OTB (One True Brace) style.

123 |

By default, any click of the left or right mouse button will reset the hotstring recognizer. In other words, the script will begin waiting for an entirely new hotstring, eliminating from consideration anything you previously typed (if this is undesirable, specify the line #Hotstring NoMouse anywhere in the script). This "reset upon mouse click" behavior is the default because each click typically moves the text insertion point (caret) or sets keyboard focus to a new control/field. In such cases, it is usually desirable to: 1) fire a hotstring even if it lacks the question mark option; 2) prevent a firing when something you type after clicking the mouse accidentally forms a valid abbreviation with what you typed before.

124 |

The hotstring recognizer checks the active window each time a character is typed, and resets if a different window is active than before. If the active window changes but reverts before any characters are typed, the change is not detected (but the hotstring recognizer may be reset for some other reason). The hotstring recognizer can also be reset by calling Hotstring "Reset".

125 |

The built-in variable A_EndChar contains the ending character that you typed to trigger the most recent non-auto-replace hotstring. If no ending character was required (due to the * option), this variable will be blank. A_EndChar is useful when making hotstrings that use the Send function or whose behavior should vary depending on which ending character you typed. To send the ending character itself, use SendText A_EndChar (SendText is used because characters such as !{} would not be sent correctly by the normal Send function).

126 |

Although single-colons within hotstring definitions do not need to be escaped unless they precede the double-colon delimiter, backticks and those semicolons having a space or tab to their left must always be escaped. See Escape Sequences for a complete list.

127 |

Although the Send function's special characters such as {Enter} are supported in auto-replacement text (unless the raw option is used), the hotstring abbreviations themselves do not use this. Instead, specify `n for Enter and `t (or a literal tab) for Tab (see Escape Sequences for a complete list). For example, the hotstring :*:ab`t:: would be triggered when you type "ab" followed by a tab.

128 |

Spaces and tabs are treated literally within hotstring definitions. For example, the following would produce two different results: ::btw::by the way and ::btw:: by the way.

129 |

Each hotstring abbreviation can be no more than 40 characters long. The program will warn you if this length is exceeded. By contrast, the length of hotstring's replacement text is limited to about 5000 characters when the sending mode is at its default of SendInput. That limit can be removed by switching to one of the other sending modes, or by using SendPlay or SendEvent in the body of the hotstring or in combination with the X (execute) option.

130 |

The order in which hotstrings are defined determines their precedence with respect to each other. In other words, if more than one hotstring matches something you type, only the one listed first in the script will take effect. Related topic: context-sensitive hotstrings.

131 |

Any backspacing you do is taken into account for the purpose of detecting hotstrings. However, the use of , , , , PgUp, PgDn, Home, and End to navigate within an editor will cause the hotstring recognition process to reset. In other words, it will begin waiting for an entirely new hotstring.

132 |

A hotstring may be typed even when the active window is ignoring your keystrokes. In other words, the hotstring will still fire even though the triggering abbreviation is never visible. In addition, you may still press Backspace to undo the most recently typed keystroke (even though you can't see the effect).

133 |

A hotstring's function can be called explicitly by the script only if the function has been named. See Named Function Hotstrings.

134 |

Hotstrings are not monitored and will not be triggered while input is blocked by an invisible Input hook.

135 |

By default, hotstrings are never triggered by keystrokes produced by any AutoHotkey script. This avoids the possibility of an infinite loop where hotstrings trigger each other over and over. This behaviour can be controlled with #InputLevel and SendLevel. However, auto-replace hotstrings always use send level 0 and therefore never trigger hook hotkeys or hotstrings.

136 |

The Suspend function can temporarily disable all hotstrings except for ones you make exempt. For greater selectivity, use #HotIf.

137 |

Hotstrings can be created dynamically by means of the Hotstring function, which can also modify, disable, or enable the script's existing hotstrings individually.

138 |

The InputHook function is more flexible than hotstrings for certain purposes. For example, it allows your keystrokes to be invisible in the active window (such as a game). It also supports non-character ending keys such as Esc.

139 |

The keyboard hook is automatically used by any script that contains hotstrings.

140 |

Hotstrings behave identically to hotkeys in the following ways:

141 | 147 |

Known limitation: On some systems in Java applications, hotstrings might interfere with the user's ability to type diacritical letters (via dead keys). To work around this, Suspend can be turned on temporarily (which disables all hotstrings).

148 | 149 |

Named Function Hotstrings

150 |

If the function of a hotstring is ever needed to be called without triggering the hotstring itself, one or more hotstrings can be assigned a named function by simply defining it immediately after the hotstring's double-colon, as in this example:

151 |
; This example also demonstrates one way to implement case conformity in a script.
152 | :C:BTW::  ; Typed in all-caps.
153 | :C:Btw::  ; Typed with only the first letter upper-case.
154 | : :btw::  ; Typed in any other combination.
155 |     case_conform_btw(hs) ; hs will hold the name of the hotstring which triggered the function.
156 |     {
157 |         if (hs == ":C:BTW")
158 |             Send "BY THE WAY"
159 |         else if (hs == ":C:Btw")
160 |             Send "By the way"
161 |         else
162 |             Send "by the way"
163 |     }
164 | 
165 |

If the function case_conform_btw is ever called explicitly by the script, the first parameter (hs) must be passed a value.

166 |

Hotkeys can also be defined this way. Multiple hotkeys or hotstrings can be stacked together to call the same function.

167 |

There must only be whitespace or comments between the hotstring and the function name.

168 |

Naming the function also encourages self-documenting hotstrings, like in the code above where the function name describes the hotstring.

169 |

The Hotstring function can also be used to assign a function or function object to a hotstring.

170 | 171 |

Hotstring Helper

172 |

Take a look at the first example in the example section of the Hotstring function's page, which might be useful if you are a heavy user of hotstrings. By pressing Win+H (or another hotkey of your choice), the currently selected text can be turned into a hotstring. For example, if you have "by the way" selected in a word processor, pressing Win+H will prompt you for its abbreviation (e.g. btw), add the new hotstring to the script and activate it.

173 | 174 | 175 | -------------------------------------------------------------------------------- /docs/KeyList.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | List of Keys (Keyboard, Mouse and Controller) | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

List of Keys (Keyboard, Mouse and Controller)

14 |

Table of Contents

15 | 39 | 40 |

Mouse

41 |

General Buttons

42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
NameDescription
LButtonPrimary mouse button. Which physical button this corresponds to depends on system settings; by default it is the left button.
RButtonSecondary mouse button. Which physical button this corresponds to depends on system settings; by default it is the right button.
MButtonMiddle or wheel mouse button
60 |

Advanced Buttons

61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
NameDescription
XButton14th mouse button. Typically performs the same function as Browser_Back.
XButton25th mouse button. Typically performs the same function as Browser_Forward.
75 |

Wheel

76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 93 | 94 |
NameDescription
WheelDownTurn the wheel downward (toward you).
WheelUpTurn the wheel upward (away from you).
WheelLeft
WheelRight

Scroll to the left or right.

92 |

These can be used as hotkeys with some (but not all) mice which have a second wheel or support tilting the wheel to either side. In some cases, software bundled with the mouse must instead be used to control this feature. Regardless of the particular mouse, Send and Click can be used to scroll horizontally in programs which support it.

95 |

Keyboard

96 |

Note: The names of the letter and number keys are the same as that single letter or digit. For example: b is B and 5 is 5.

97 |

Although any single character can be used as a key name, its meaning (scan code or virtual keycode) depends on the current keyboard layout. Additionally, some special characters may need to be escaped or enclosed in braces, depending on the context. The letters a-z or A-Z can be used to refer to the corresponding virtual keycodes (usually vk41-vk5A) even if they are not included in the current keyboard layout.

98 |

General Keys

99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 |
NameDescription
CapsLockCapsLock (caps lock key) 107 |

Note: Windows IME may interfere with the detection and functionality of CapsLock; see CapsLock and IME for details.

108 |
SpaceSpace (space bar)
TabTab (tabulator key)
EnterEnter
Escape (or Esc)Esc
Backspace (or BS)Backspace
131 |

Cursor Control Keys

132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 |
NameDescription
ScrollLockScrollLock (scroll lock key). While Ctrl is held down, ScrollLock produces the key code of CtrlBreak, but can be differentiated from Pause by scan code.
Delete (or Del)Del
Insert (or Ins)Ins
HomeHome
EndEnd
PgUpPgUp (page up key)
PgDnPgDn (page down key)
Up (up arrow key)
Down (down arrow key)
Left (left arrow key)
Right (right arrow key)
182 |

Numpad Keys

183 |

Due to system behavior, the following keys separated by a slash are identified differently depending on whether NumLock is ON or OFF. If NumLock is OFF but Shift is pressed, the system temporarily releases Shift and acts as though NumLock is ON.

184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 |
NameDescription
Numpad0 / NumpadIns0 / Ins
Numpad1 / NumpadEnd1 / End
Numpad2 / NumpadDown2 /
Numpad3 / NumpadPgDn3 / PgDn
Numpad4 / NumpadLeft4 /
Numpad5 / NumpadClear5 / typically does nothing
Numpad6 / NumpadRight6 /
Numpad7 / NumpadHome7 / Home
Numpad8 / NumpadUp8 /
Numpad9 / NumpadPgUp9 / PgUp
NumpadDot / NumpadDel. / Del
NumLockNumLock (number lock key). While Ctrl is held down, NumLock produces the key code of Pause, so use ^Pause in hotkeys instead of ^NumLock.
NumpadDiv/ (division)
NumpadMult* (multiplication)
NumpadAdd+ (addition)
NumpadSub- (subtraction)
NumpadEnterEnter
247 |

Function Keys

248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 |
NameDescription
F1 - F24The 12 or more function keys at the top of most keyboards.
258 |

Modifier Keys

259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 313 | 314 |
NameDescription
LWinLeft Win. Corresponds to the <# hotkey prefix.
RWin 271 |

Right Win. Corresponds to the ># hotkey prefix.

272 |

Note: Unlike Ctrl/Alt/Shift, there is no generic/neutral "Win" key because the OS does not support it. However, hotkeys with the # modifier can be triggered by either Win.

273 |
Control (or Ctrl)Ctrl. As a hotkey (Control::) it fires upon release unless it has the tilde prefix. Corresponds to the ^ hotkey prefix.
AltAlt. As a hotkey (Alt::) it fires upon release unless it has the tilde prefix. Corresponds to the ! hotkey prefix.
ShiftShift. As a hotkey (Shift::) it fires upon release unless it has the tilde prefix. Corresponds to the + hotkey prefix.
LControl (or LCtrl)Left Ctrl. Corresponds to the <^ hotkey prefix.
RControl (or RCtrl)Right Ctrl. Corresponds to the >^ hotkey prefix.
LShiftLeft Shift. Corresponds to the <+ hotkey prefix.
RShiftRight Shift. Corresponds to the >+ hotkey prefix.
LAltLeft Alt. Corresponds to the <! hotkey prefix.
RAlt 310 |

Right Alt. Corresponds to the >! hotkey prefix.

311 |

Note: If your keyboard layout has AltGr instead of RAlt, you can probably use it as a hotkey prefix via <^>! as described here. In addition, LControl & RAlt:: would make AltGr itself into a hotkey.

312 |
315 |

Multimedia Keys

316 |

The function assigned to each of the keys listed below can be overridden by modifying the Windows registry. This table shows the default function of each key on most versions of Windows.

317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 |
NameDescription
Browser_BackBack
Browser_ForwardForward
Browser_RefreshRefresh
Browser_StopStop
Browser_SearchSearch
Browser_FavoritesFavorites
Browser_HomeHomepage
Volume_MuteMute the volume
Volume_DownLower the volume
Volume_UpIncrease the volume
Media_NextNext Track
Media_PrevPrevious Track
Media_StopStop
Media_Play_PausePlay/Pause
Launch_MailLaunch default e-mail program
Launch_MediaLaunch default media player
Launch_App1Launch This PC (formerly My Computer or Computer)
Launch_App2Launch Calculator
395 |

Other Keys

396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 437 | 438 |
NameDescription
AppsKeyMenu. This is the key that invokes the right-click context menu.
PrintScreenPrtSc (print screen key)
CtrlBreakCtrl+Pause or Ctrl+ScrollLock
PausePause or Ctrl+NumLock. While Ctrl is held down, Pause produces the key code of CtrlBreak and NumLock produces Pause, so use ^CtrlBreak in hotkeys instead of ^Pause.
HelpHelp. This probably doesn't exist on most keyboards. It's usually not the same as F1.
SleepSleep. Note that the sleep key on some keyboards might not work with this.
SCnnnSpecify for nnn the scan code of a key. Recognizes unusual keys not mentioned above. See Special Keys for details.
VKnn

Specify for nn the hexadecimal virtual key code of a key. This rarely-used method also prevents certain types of hotkeys from requiring the keyboard hook. For example, the following hotkey does not use the keyboard hook, but as a side-effect it is triggered by pressing either Home or NumpadHome:

432 |
^VK24::MsgBox "You pressed Home or NumpadHome while holding down Control."
433 | 
434 |

Known limitation: VK hotkeys that are forced to use the keyboard hook, such as *VK24 or ~VK24, will fire for only one of the keys, not both (e.g. NumpadHome but not Home). For more information about the VKnn method, see Special Keys.

435 |

Warning: Only Send, GetKeyName, GetKeyVK, GetKeySC and A_MenuMaskKey support combining VKnn and SCnnn. If combined in any other case (or if any other invalid suffix is present), the key is not recognized. For example, vk1Bsc001:: raises an error.

436 |
439 |

Game Controller (Gamepad, Joystick, etc.)

440 |

Note: For historical reasons, the following button and control names begin with Joy, which stands for joystick. However, they usually also work for other game controllers such as gamepads or steering wheels.

441 |

Joy1 through Joy32: The buttons of the controller. To help determine the button numbers for your controller, use this test script. Note that hotkey prefix symbols such as ^ (control) and + (shift) are not supported (though GetKeyState can be used as a substitute). Also note that the pressing of controller buttons always "passes through" to the active window if that window is designed to detect the pressing of controller buttons.

442 |

Although the following control names cannot be used as hotkeys, they can be used with GetKeyState:

443 | 453 |

For example, when using Xbox Wireless/360 controllers, JoyX/JoyY is the left stick, JoyR/JoyU the right stick, JoyZ the left and right triggers, and JoyPOV the directional pad (D-pad).

454 |

Multiple controllers: If the computer has more than one controller and you want to use one beyond the first, include the controller number (max 16) in front of the control name. For example, 2joy1 is the second controller's first button.

455 |

Note: If you have trouble getting a script to recognize your controller, specify a controller number other than 1 even though only a single controller is present. It is unclear how this situation arises or whether it is normal, but experimenting with the controller number in the controller test script can help determine if this applies to your system.

456 |

See Also:

457 | 461 | 462 |

Hand-held Remote Controls

463 |

Respond to signals from hand-held remote controls via the WinLIRC client script.

464 |

Special Keys

465 |

If your keyboard or mouse has a key not listed above, you might still be able to make it a hotkey by using the following steps:

466 |
    467 |
  1. Ensure that at least one script is running that is using the keyboard hook. You can tell if a script has the keyboard hook by opening its main window and selecting "View->Key history" from the menu bar.
  2. 468 |
  3. Double-click that script's tray icon to open its main window.
  4. 469 |
  5. Press one of the "mystery keys" on your keyboard.
  6. 470 |
  7. Select the menu item "View->Key history"
  8. 471 |
  9. Scroll down to the bottom of the page. Somewhere near the bottom are the key-down and key-up events for your key. NOTE: Some keys do not generate events and thus will not be visible here. If this is the case, you cannot directly make that particular key a hotkey because your keyboard driver or hardware handles it at a level too low for AutoHotkey to access. For possible solutions, see further below.
  10. 472 |
  11. If your key is detectable, make a note of the 3-digit hexadecimal value in the second column of the list (e.g. 159).
  12. 473 |
  13. To define this key as a hotkey, follow this example: 474 |
    475 | SC159::MsgBox ThisHotkey " was pressed." ; Replace 159 with your key's value.
    476 | 
    Also see ThisHotkey.
  14. 477 |
478 |

Reverse direction: To remap some other key to become a "mystery key", follow this example:

479 |
; Replace 159 with the value discovered above. Replace FF (if needed) with the
480 | ; key's virtual key, which can be discovered in the first column of the Key History screen.
481 | #c::Send "{vkFFsc159}" ; See Send {vkXXscYYY} for more details.
482 |

Alternate solutions: If your key or mouse button is not detectable by the Key History screen, one of the following might help:

483 |
    484 |
  1. 485 |

    Reconfigure the software that came with your mouse or keyboard (sometimes accessible in the Control Panel or Start Menu) to have the "mystery key" send some other keystroke. Such a keystroke can then be defined as a hotkey in a script. For example, if you configure a mystery key to send Ctrl+F1, you can then indirectly make that key as a hotkey by using ^F1:: in a script.

    486 |
  2. 487 |
  3. 488 |

    Try AHKHID from the archived forum. You can also try searching the forum for a keywords like RawInput*, USB HID or AHKHID.

    489 |
  4. 490 |
  5. 491 |

    The following is a last resort and generally should be attempted only in desperation. This is because the chance of success is low and it may cause unwanted side-effects that are difficult to undo:
    492 | Disable or remove any extra software that came with your keyboard or mouse or change its driver to a more standard one such as the one built into the OS. This assumes there is such a driver for your particular keyboard or mouse and that you can live without the features provided by its custom driver and software.

    493 |
  6. 494 |
495 | 496 |

CapsLock and IME

497 |

Some configurations of Windows IME (such as Japanese input with English keyboard) use CapsLock to toggle between modes. In such cases, CapsLock is suppressed by the IME and cannot be detected by AutoHotkey. However, the Alt+CapsLock, Ctrl+CapsLock and Shift+CapsLock shortcuts can be disabled with a workaround. Specifically, send a key-up to modify the state of the IME, but prevent any other effects by signalling the keyboard hook to suppress the event. The following function can be used for this purpose:

498 |
499 | ; The keyboard hook must be installed.
500 | InstallKeybdHook
501 | SendSuppressedKeyUp(key) {
502 |     DllCall("keybd_event"
503 |         , "char", GetKeyVK(key)
504 |         , "char", GetKeySC(key)
505 |         , "uint", KEYEVENTF_KEYUP := 0x2
506 |         , "uptr", KEY_BLOCK_THIS := 0xFFC3D450)
507 | }
508 | 
509 |

After copying the function into a script or saving it as SendSuppressedKeyUp.ahk in a Lib folder and adding #Include <SendSuppressedKeyUp> to the script, it can be used as follows:

510 |
511 | ; Disable Alt+key shortcuts for the IME.
512 | ~LAlt::SendSuppressedKeyUp "LAlt"
513 | 
514 | ; Test hotkey:
515 | !CapsLock::MsgBox A_ThisHotkey
516 | 
517 | ; Remap CapsLock to LCtrl in a way compatible with IME.
518 | *CapsLock::
519 | {
520 |     Send "{Blind}{LCtrl DownR}"
521 |     SendSuppressedKeyUp "LCtrl"
522 | }
523 | *CapsLock up::
524 | {
525 |     Send "{Blind}{LCtrl Up}"
526 | }
527 | 
528 | 529 | 530 | 531 | -------------------------------------------------------------------------------- /docs/Language.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Scripting Language | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Scripting Language

13 |

An AutoHotkey script is basically a set of instructions for the program to follow, written in a custom language exclusive to AutoHotkey. This language bears some similarities to several other scripting languages, but also has its own unique strengths and pitfalls. This document describes the language and also tries to point out common pitfalls.

14 |

See Concepts and Conventions for more general explanation of various concepts utilised by AutoHotkey.

15 | 16 |

Table of Contents

17 | 55 | 61 | 62 |

General Conventions

63 |

Names: Variable and function names are not case-sensitive (for example, CurrentDate is the same as currentdate). For details such as maximum length and usable characters, see Names.

64 |

No typed variables: Variables have no explicitly defined type; instead, a value of any type can be stored in any variable (excluding constants and built-in variables). Numbers may be automatically converted to strings (text) and vice versa, depending on the situation.

65 |

Declarations are optional: Except where noted on the functions page, variables do not need to be declared. However, attempting to read a variable before it is given a value is considered an error.

66 |

Spaces are mostly ignored: Indentation (leading space) is important for writing readable code, but is not required by the program and is generally ignored. Spaces and tabs are generally ignored at the end of a line and within an expression (except between quotes). However, spaces are significant in some cases, including:

67 | 73 |

Line breaks are meaningful: Line breaks generally act as a statement separator, terminating the previous function call or other statement. (A statement is simply the smallest standalone element of the language that expresses some action to be carried out.) The exception to this is line continuation (see below).

74 |

Line continuation: Long lines can be divided up into a collection of smaller ones to improve readability and maintainability. This is achieved by preprocessing, so is not part of the language as such. There are three methods:

75 | 80 | 81 | 82 |

Comments

83 |

Comments are portions of text within the script which are ignored by the program. They are typically used to add explanation or disable parts of the code.

84 |

Scripts can be commented by using a semicolon at the beginning of a line. For example:

85 |
; This entire line is a comment.
86 |

Comments may also be added at the end of a line, in which case the semicolon must have at least one space or tab to its left. For example:

87 |
Run "Notepad"  ; This is a comment on the same line as a function call.
88 |

In addition, the /* and */ symbols can be used to comment out an entire section, as in this example:

89 |
/*
 90 | MsgBox "This line is commented out (disabled)."
 91 | MsgBox "Common mistake:" */ " this does not end the comment."
 92 | MsgBox "This line is commented out."
 93 | */
 94 | MsgBox "This line is not commented out."
 95 | /* This is also valid, but no other code can share the line. */
 96 | MsgBox "This line is not commented out."
 97 | 
98 |

Excluding tabs and spaces, /* must appear at the start of the line, while */ can appear only at the start or end of a line. It is also valid to omit */, in which case the remainder of the file is commented out.

99 |

Since comments are filtered out when the script is read from file, they do not impact performance or memory utilization.

100 | 101 |

Expressions

102 |

Expressions are combinations of one or more values, variables, operators and function calls. For example, 10, 1+1 and MyVar are valid expressions. Usually, an expression takes one or more values as input, performs one or more operations, and produces a value as the result. The process of finding out the value of an expression is called evaluation. For example, the expression 1+1 evaluates to the number 2.

103 |

Simple expressions can be pieced together to form increasingly more complex expressions. For example, if Discount/100 converts a discount percentage to a fraction, 1 - Discount/100 calculates a fraction representing the remaining amount, and Price * (1 - Discount/100) applies it to produce the net price.

104 |

Values are numbers, objects or strings. A literal value is one written physically in the script; one that you can see when you look at the code.

105 | 106 |

Strings / Text

107 |

For a more general explanation of strings, see Strings.

108 |

A string, or string of characters, is just a text value. In an expression, literal text must be enclosed in single or double quotation marks to differentiate it from a variable name or some other expression. This is often referred to as a quoted literal string, or just quoted string. For example, "this is a quoted string" and 'so is this'.

109 |

To include an actual quote character inside a quoted string, use the `" or `' escape sequence or enclose the character in the opposite type of quote mark. For example: 'She said, "An apple a day."'.

110 |

Quoted strings can contain other escape sequences such as `t (tab), `n (linefeed), and `r (carriage return).

111 | 112 |

Variables

113 |

For a basic explanation and general details about variables, see Variables.

114 |

Variables can be used in an expression simply by writing the variable's name. For example, A_ScreenWidth/2. However, variables cannot be used inside a quoted string. Instead, variables and other values can be combined with text through a process called concatenation. There are two ways to concatenate values in an expression:

115 | 119 |

Implicit concatenation is also known as auto-concat. In both cases, the spaces preceding the variable and dot are mandatory.

120 |

The Format function can also be used for this purpose. For example:

121 |
MsgBox Format("You are using AutoHotkey v{1} {2}-bit.", A_AhkVersion, A_PtrSize*8)
122 |

To assign a value to a variable, use the := assignment operator, as in MyVar := "Some text".

123 |

Percent signs within an expression are used to create dynamic variable references, but these are rarely needed.

124 | 125 |

Keyword Constants

126 |

A constant is simply an unchangeable value, given a symbolic name. AutoHotkey currently has the following constants:

127 | 128 | 129 | 130 | 131 |
NameValueTypeDescription
False0IntegerBoolean false, sometimes meaning "off", "no", etc.
True1IntegerBoolean true, sometimes meaning "on", "yes", etc.
132 |

Unlike the read-only built-in variables, these cannot be returned by a dynamic reference.

133 | 134 |

Operators

135 |

Operators take the form of a symbol or group of symbols such as + or :=, or one of the words and, or, not, is, in or contains. They take one, two or three values as input and return a value as the result. A value or sub-expression used as input for an operator is called an operand.

136 | 141 |

Some unary and binary operators share the same symbols, in which case the meaning of the operator depends on whether it is written before, after or in between two values. For example, x-y performs subtraction while -x inverts the sign of x (producing a positive value from a negative value and vice versa).

142 |

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

143 | 144 |

Function Calls

145 |

For a general explanation of functions and related terminology, see Functions.

146 |

Functions take a varying number of inputs, perform some action or calculation, and then return a result. The inputs of a function are called parameters or arguments. A function is called simply by writing the target function followed by parameters enclosed in parentheses. For example, GetKeyState("Shift") returns (evaluates to) 1 if Shift is being held down or 0 otherwise.

147 |

Note: There must not be any space between the function and open parenthesis.

148 |

For those new to programming, the requirement for parentheses may seem cryptic or verbose at first, but they are what allows a function call to be combined with other operations. For example, the expression GetKeyState("Shift", "P") and GetKeyState("Ctrl", "P") returns 1 only if both keys are being physically held down.

149 |

Although a function call expression usually begins with a literal function name, the target of the call can be any expression which produces a function object. In the expression GetKeyState("Shift"), GetKeyState is actually a variable reference, although it usually refers to a read-only variable containing a built-in function.

150 | 151 |

Function Call Statements

152 |

If the return value of the function is not needed and the function name is written at the start of the line (or in other contexts which allow a statement, such as following else or a hotkey), the parentheses can be omitted. In this case, the remainder of the line is taken as the function's parameter list. For example:

153 |
result := MsgBox("This one requires parentheses.",, "OKCancel")
154 | MsgBox "This one doesn't. The result was " result "."
155 |

Parentheses can also be omitted when calling a method in this same context, but only when the target object is either a variable or a directly named property, such as myVar.myMethod or myVar.myProp.myMethod.

156 |

As with function call expressions, the target of a function call statement does not have to be a predefined function; it can instead be a variable containing a function object.

157 |

A function call statement can span multiple lines.

158 |

Function call statements have the following limitations:

159 | 165 | 166 |

Optional Parameters

167 |

Optional parameters can simply be left blank, but the delimiting comma is still required unless all subsequent parameters are also omitted. For example, the Run function can accept between one and four parameters. All of the following are valid:

168 |
169 | Run "notepad.exe", "C:\"
170 | Run "notepad.exe",, "Min"
171 | Run("notepad.exe", , , &notepadPID)
172 | 
173 |

Within a function call, array literal or object literal, the keyword unset can be used to explicitly omit the parameter or value. An unset expression has one of the following effects:

174 | 180 |

The unset keyword can also be used in a function definition to indicate that a parameter is optional but has no default value. When the function executes, the local variable corresponding to that parameter will have no value if the parameter was omitted.

181 |

The maybe operator (var?) can be used to pass or omit a variable depending on whether it has a value. For example, Array(MyVar?) is equivalent to Array(IsSet(MyVar) ? MyVar : unset).

182 | 183 |

Operators for Objects

184 |

There are other symbols used in expressions which don't quite fit into any of the categories defined above, or that affect the meaning of other parts of the expression, as described below. These all relate to objects in some way. Providing a full explanation of what each construct does would require introducing more concepts which are outside the scope of this section.

185 |

Alpha.Beta is often called member access. Alpha is an ordinary variable, and could be replaced with a function call or some other sub-expression which returns an object. When evaluated, the object is sent a request "give me the value of property Beta", "store this value in property Beta" or "call the method named Beta". In other words, Beta is a name which has meaning to the object; it is not a local or global variable.

186 |

Alpha.Beta() is a method call, as described above. The parentheses can be omitted in specific cases; see Function Call Statements.

187 |

Alpha.Beta[Param] is a specialised form of member access which includes additional parameters in the request. While Beta is a simple name, Param is an ordinary variable or sub-expression, or a list of sub-expressions separated by commas (the same as in a function's parameter list). Variadic calls are permitted.

188 |

Alpha.%vBeta%, Alpha.%vBeta%[Param] and Alpha.%vBeta%() are also member access, but vBeta is a variable or sub-expression. This allows the name of the property or method to be determined while the script is running. Parentheses are required when calling a method this way.

189 |

Alpha[Index] accesses the default property of Alpha, giving Index as a parameter. Both Alpha and Index are variables in this case, and could be replaced with virtually any sub-expression. This syntax is usually used to retrieve an element of an Array or Map.

190 |

[A, B, C] creates an Array with the initial contents A, B and C (all variables in this case), where A is element 1.

191 |

{Prop1: Value1, Prop2: Value2} creates an Object with properties literally named Prop1 and Prop2. A value can later be retrieved by using the member access syntax described above. To evaluate a property name as an expression, enclose it in percent signs. For example: {%NameVar%: ValueVar}.

192 |

MyFunc(Params*) is a variadic function call. The asterisk must immediately precede the closing parenthesis at the end of the function's parameter list. Params must be a variable or sub-expression which returns an Array or other enumerable object. Although it isn't valid to use Params* just anywhere, it can be used in an array literal ([A, B, C, ArrayToAppend*]) or property parameter list (Alpha.Beta[Params*] or Alpha[Params*]).

193 | 194 |

Expression Statements

195 |

Not all expressions can be used alone on a line. For example, a line consisting of just 21*2 or "Some text" wouldn't make any sense. An expression statement is an expression used on its own, typically for its side-effects. Most expressions with side-effects can be used this way, so it is generally not necessary to memorise the details of this section.

196 |

The following types of expressions can be used as statements:

197 |

Assignments, as in x := y, compound assignments such as x += y, and increment/decrement operators such as ++x and x--.

198 |

Known limitation: For x++ and x--, there currently cannot be a space between the variable name and operator.

199 |

Function calls such as MyFunc(Params). However, a standalone function call cannot be followed by an open brace { (at the end of the line or on the next line), because it would be confused with a function declaration.

200 |

Method calls such as MyObj.MyMethod().

201 |

Member access using square brackets, such as MyObj[Index], which can have side-effects like a function call.

202 |

Ternary expressions such as x ? CallIfTrue() : CallIfFalse(). However, it is safer to utilize the rule below; that is, always enclose the expression (or just the condition) in parentheses.

203 |

Known limitation: Due to ambiguity with function call statements, conditions beginning with a variable name and space (but also containing other operators) should be enclosed in parentheses. For example, (x + 1) ? y : z and x+1 ? y : z are expression statements but x + 1 ? y : z is a function call statement.

204 |

Note: The condition cannot begin with ! or any other expression operator, as it would be interpreted as a continuation line.

205 |

Expressions starting with (. However, there usually must be a matching ) on the same line, otherwise the line would be interpreted as the start of a continuation section.

206 |

Expressions starting with a double-deref, such as %varname% := 1. This is primarily due to implementation complexity.

207 |

Expressions that start with any of those described above (but not those described below) are also allowed, for simplicity. For example, MyFunc()+1 is currently allowed, although the +1 has no effect and its result is discarded. Such expressions might become invalid in the future due to enhanced error-checking.

208 |

Function call statements are similar to expression statements, but are technically not pure expressions. For example, MsgBox "Hello, world!", myGui.Show or x.y.z "my parameter".

209 | 210 |

Control Flow Statements

211 |

For a general explanation of control flow, see Control Flow.

212 |

Statements are grouped together into a block by enclosing them in braces {}, as in C, JavaScript and similar languages, but usually the braces must appear at the start of a line. Control flow statements can be applied to an entire block or just a single statement.

213 |

The body of a control flow statement is always a single group of statements. A block counts as a single group of statements, as does a control flow statement and its body. The following related statements are also grouped with each other, along with their bodies: If with Else; Loop/For with Until or Else; Try with Catch and/or Else and/or Finally. In other words, when a group of these statements is used as a whole, it does not always need to be enclosed in braces (however, some coding styles always include the braces, for clarity).

214 |

Control flow statements which have a body and therefore must always be followed by a related statement or group of statements: If, Else, Loop, While, For, Try, Catch and Finally.

215 |

The following control flow statements exist:

216 | 237 | 238 |

Control Flow vs. Other Statements

239 |

Control flow statements differ from function call statements in several ways:

240 | 246 | 247 |

Loop Statement

248 |

There are several types of loop statements:

249 | 258 |

Break exits (terminates) a loop, effectively jumping to the next line after the loop's body.

259 |

Continue skips the rest of the current loop iteration and begins a new one.

260 |

Until causes a loop to terminate when an expression evaluates to true. The expression is evaluated after each iteration.

261 |

A label can be used to "name" a loop for Continue and Break. This allows the script to easily continue or break out of any number of nested loops without using Goto.

262 |

The built-in variable A_Index contains the number of the current loop iteration. It contains 1 the first time the loop's body is executed. For the second time, it contains 2; and so on. If an inner loop is enclosed by an outer loop, the inner loop takes precedence. A_Index works inside all types of loops, but contains 0 outside of a loop.

263 |

For some loop types, other built-in variables return information about the current loop item (registry key/value, file, substring or line of text). These variables have names beginning with A_Loop, such as A_LoopFileName and A_LoopReadLine. Their values always correspond to the most recently started (but not yet stopped) loop of the appropriate type. For example, A_LoopField returns the current substring in the innermost parsing loop, even if it is used inside a file or registry loop.

264 |
t := "column 1`tcolumn 2`nvalue 1`tvalue 2"
265 | Loop Parse t, "`n"
266 | {
267 |     rowtext := A_LoopField
268 |     rownum := A_Index  ; Save this for use in the second loop, below.
269 |     Loop Parse rowtext, "`t"
270 |     {
271 |         MsgBox rownum ":" A_Index " = " A_LoopField
272 |     }
273 | }
274 | 
275 |

Loop variables can also be used outside the body of a loop, such as in a function which is called from within a loop.

276 | 277 |

Not Control Flow

278 |

As directives, labels, double-colon hotkey and hotstring tags, and declarations without assignments are processed when the script is loaded from file, they are not subject to control flow. In other words, they take effect unconditionally, before the script ever executes any control flow statements. Similarly, the #HotIf directive cannot affect control flow; it merely sets the criteria for any hotkeys and hotstrings specified in the code. A hotkey's criteria is evaluated each time it is pressed, not when the #HotIf directive is encountered in the code.

279 | 280 |

Structure of a Script

281 | 282 |

Global Code

283 |

After the script has been loaded, the auto-execute thread begins executing at the script's top line, and continues until instructed to stop, such as by Return, ExitApp or Exit. The physical end of the script also acts as Exit.

284 |

Global code, or code in the global scope, is any executable code that is not inside a function or class definition. Any variable references there are said to be global, since they can be accessed by any function (with the proper declaration). Such code is often used to configure settings which apply to every newly launched thread, or to initialize global variables used by hotkeys and other functions.

285 |

Code to be executed at startup (immediately when the script starts) is often placed at the top of the file. However, such code can be placed throughout the file, in between (but not inside) function and class definitions. This is because the body of each function or class definition is skipped whenever it is encountered during execution. In some cases, the entire purpose of the script may be carried out with global code.

286 |

Related: Script Startup (the Auto-execute Thread)

287 | 288 |

Subroutines

289 |

A subroutine (also sub or procedure) is a reusable block of code which can be executed on demand. A subroutine is created by defining a function (see below). These terms are generally interchangeable for AutoHotkey v2, where functions are the only type of subroutine.

290 | 291 |

Functions

292 |

Related: Functions (all about defining functions)

293 |

Aside from calling the many useful predefined functions, a script can define its own functions. These functions can generally be used two ways:

294 |
    295 |
  1. A function can be called by the script itself. This kind of function might be used to avoid repetition, to make the code more manageable, or perhaps for other purposes.
  2. 296 |
  3. A function can be called by the program in response to some event, such as the user pressing a hotkey. For instance, each hotkey is associated with a function to execute whenever the hotkey is pressed.
  4. 297 |
298 |

There are multiple ways to define a function:

299 | 322 |

Variables in functions are local to that function by default, except in the following cases:

323 | 328 |

A function can optionally accept parameters. Parameters are defined by listing them inside the parentheses. For example:

329 |
MyFunction(FirstParameter, Second, &Third, Fourth:="")
330 | {
331 |     ;...
332 |     return "a value"
333 | }
334 | 
335 |

As with function calls, there must be no space between the function name and open-parenthesis.

336 |

The line break between the close-parenthesis and open-brace is optional. There can be any amount of whitespace or comments between the two.

337 |

The ByRef marker (&) indicates that the caller must pass a variable reference. Inside the function, any reference to the parameter will actually access the caller's variable. This is similar to omitting & and explicitly dereferencing the parameter inside the function (e.g. %Third%), but in this case the percent signs are omitted. If the parameter is optional and the caller omits it, the parameter acts as a normal local variable.

338 |

Optional parameters are specified by following the parameter name with := and a default value, which must be a literal quoted string, a number, true, false or unset.

339 |

The function can return a value. If it does not, the default return value is an empty string.

340 |

A function definition does not need to precede calls to that function.

341 |

See Functions for much more detail.

342 | 343 |

#Include

344 |

The #Include directive causes the script to behave as though the specified file's contents are present at this exact position. This is often used to organise code into separate files, or to make use of script libraries written by other users.

345 |

An #Include file can contain global code to be executed during script startup, but as with code in the main script file, such code will be executed only if the auto-execute thread is not terminated (such as with an unconditional Return) prior to the #Include directive. A warning is displayed by default if any code cannot be executed due to a prior Return.

346 |

Unlike in C/C++, #Include does nothing if the file has already been included by a previous directive. To include the contents of the same file multiple times, use #IncludeAgain.

347 |

To facilitate sharing scripts, #Include can search a few standard locations for a library script. For details, see Script Library Folders.

348 | 349 |

Miscellaneous

350 | 351 |

Dynamic Variables

352 |

A dynamic variable reference takes a text value and interprets it as the name of a variable.

353 |

Note: A variable cannot be created by a dynamic reference, but existing variables can be assigned. This includes all variables which the script contains non-dynamic references to, even if they have not been assigned values.

354 |

The most common form of dynamic variable reference is called a double reference or double-deref. Before performing a double reference, the name of the target variable is stored in a second variable. This second variable can then be used to assign a value to the target variable indirectly, using a double reference. For example:

355 |
target := 42
356 | second := "target"
357 | MsgBox  second   ; Normal (single) variable reference => target
358 | MsgBox %second%  ; Double-deref => 42
359 | 
360 |

Currently, second must always contain a variable name in the second case; arbitrary expressions are not supported.

361 |

A dynamic variable reference can also take one or more pieces of literal text and the content of one or more variables, and join them together to form a single variable name. This is done simply by writing the pieces of the name and percent-enclosed variables in sequence, without any spaces. For example, MyArray%A_Index% or MyGrid%X%_%Y%. This is used to access pseudo-arrays, described below.

362 |

These techniques can also be applied to properties and methods of objects. For example:

363 |
clr := {}
364 | for n, component in ["red", "green", "blue"]
365 |     clr.%component% := Random(0, 255)
366 | MsgBox clr.red "," clr.green "," clr.blue
367 | 368 |

Pseudo-arrays

369 |

A pseudo-array is actually just a bunch of discrete variables, but with a naming pattern which allows them to be used like elements of an array. For example:

370 |
371 | MyArray1 := "A"
372 | MyArray2 := "B"
373 | MyArray3 := "C"
374 | Loop 3
375 |     MsgBox MyArray%A_Index%  ; Shows A, then B, then C.
376 | 
377 |

The "index" used to form the final variable name does not have to be numeric; it could instead be a letter or keyword.

378 |

For these reasons, it is generally recommended to use an Array or Map instead of a pseudo-array:

379 | 386 | 387 |

Labels

388 |

A label identifies a line of code, and can be used as a Goto target or to specify a loop to break out of or continue. A label consist of a name followed by a colon:

389 |
this_is_a_label:
390 |

Aside from whitespace and comments, no other code can be written on the same line as a label. For more details, see Labels.

391 | 392 | 393 | -------------------------------------------------------------------------------- /docs/ObjList.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Built-in Classes | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Built-in Classes

15 | 16 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /docs/Objects.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Objects - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 |

Objects

18 | 19 |

An object combines a number of properties and methods.

20 |

Related topics:

21 | 26 | 27 |

IsObject can be used to determine if a value is an object:

28 |
Result := IsObject(expression)
29 | 30 |

See Built-in Classes for a list of standard object types. There are two fundamental types:

31 | 35 | 36 |

Table of Contents

37 | 76 | 77 |

Basic Usage

78 | 79 |

Arrays

80 |

Create an Array:

81 |
MyArray := [Item1, Item2, ..., ItemN]
 82 | MyArray := Array(Item1, Item2, ..., ItemN)
83 |

Retrieve an item (or array element):

84 |
Value := MyArray[Index]
85 |

Change the value of an item (Index must be between 1 and Length, or an equivalent reverse index):

86 |
MyArray[Index] := Value
87 |

Insert one or more items at a given index using the InsertAt method:

88 |
MyArray.InsertAt(Index, Value, Value2, ...)
89 |

Append one or more items using the Push method:

90 |
MyArray.Push(Value, Value2, ...)
91 |

Remove an item using the RemoveAt method:

92 |
RemovedValue := MyArray.RemoveAt(Index)
93 |

Remove the last item using the Pop method:

94 |
RemovedValue := MyArray.Pop()
95 |

Length returns the number of items in the array. Looping through an array's contents can be done either by index or with a For-loop. For example:

96 |
MyArray := ["one", "two", "three"]
 97 | 
 98 | ; Iterate from 1 to the end of the array:
 99 | Loop MyArray.Length
100 |     MsgBox MyArray[A_Index]
101 | 
102 | ; Enumerate the array's contents:
103 | For index, value in MyArray
104 |     MsgBox "Item " index " is '" value "'"
105 |     
106 | ; Same thing again:
107 | For value in MyArray
108 |     MsgBox "Item " A_Index " is '" value "'"
109 | 
110 | 111 |

Maps (Associative Arrays)

112 |

A Map or associative array is an object which contains a collection of unique keys and a collection of values, where each key is associated with one value. Keys can be strings, integers or objects, while values can be of any type. An associative array can be created as follows:

113 |
MyMap := Map("KeyA", ValueA, "KeyB", ValueB, ..., "KeyZ", ValueZ)
114 |

Retrieve an item, where Key is a variable or expression:

115 |
Value := MyMap[Key]
116 |

Assign an item:

117 |
MyMap[Key] := Value
118 |

Remove an item using the Delete method:

119 |
RemovedValue := MyMap.Delete(Key)
120 |

Enumerating items:

121 |
MyMap := Map("ten", 10, "twenty", 20, "thirty", 30)
122 | For key, value in MyMap
123 |     MsgBox key ' = ' value
124 | 125 |

Objects

126 |

An object can have properties and items (such as array elements). Items are accessed using [] as shown in the previous sections. Properties are usually accessed by writing a dot followed by an identifier (just a name). Methods are properties which can be called.

127 |

Examples:

128 |

Retrieve or set a property literally named Property:

129 |
Value := MyObject.Property
130 |
MyObject.Property := Value
131 |

Retrieve or set a property where the name is determined by evaluating an expression or variable:

132 |
Value := MyObject.%Expression%
133 |
MyObject.%Expression% := Value
134 |

Call a property/method literally named Method:

135 |
ReturnValue := MyObject.Method(Parameters)
136 |

Call a property/method where the name is determined by evaluating an expression or variable:

137 |
ReturnValue := MyObject.%Expression%(Parameters)
138 |

Sometimes parameters are accepted when retrieving or assigning properties:

139 |
Value := MyObject.Property[Parameters]
140 | MyObject.Property[Parameters] := Value
141 |

An object may also support indexing: MyArray[Index] actually invokes the __Item property of MyArray, passing Index as a parameter.

142 | 143 |

Object Literal

144 |

An object literal can be used within an expression to create an improvised object. An object literal consists of a pair of braces ({}) enclosing a list of comma-delimited name-value pairs. Each pair consists of a literal (unquoted) property name and a value (sub-expression) separated by a colon (:). For example:

145 |
Coord := {X: 13, Y: 240}
146 |

This is equivalent:

147 |
Coord := Object()
148 | Coord.X := 13
149 | Coord.Y := 240
150 |

Each name-value pair causes a value property to be defined, with the exception that Base can be set (with the same restrictions as a normal assignment).

151 |

Name substitution allows a property name to be determined by evaluating an expression or variable. For example:

152 |
parts := StrSplit("key = value", "=", " ")
153 | pair := {%parts[1]%: parts[2]}
154 | MsgBox pair.key
155 | 156 |

Freeing Objects

157 |

Scripts do not free objects explicitly. When the last reference to an object is released, the object is freed automatically. A reference stored in a variable is released automatically when that variable is assigned some other value. For example:

158 |
obj := {}  ; Creates an object.
159 | obj := ""  ; Releases the last reference, and therefore frees the object.
160 |

Similarly, a reference stored in a property or array element is released when that property or array element is assigned some other value or removed from the object.

161 |
arr := [{}]  ; Creates an array containing an object.
162 | arr[1] := {}  ; Creates a second object, implicitly freeing the first object.
163 | arr.RemoveAt(1)  ; Removes and frees the second object.
164 |

Because all references to an object must be released before the object can be freed, objects containing circular references aren't freed automatically. For instance, if x.child refers to y and y.parent refers to x, clearing x and y is not sufficient since the parent object still contains a reference to the child and vice versa. To resolve this situation, remove the circular reference.

165 |
166 | x := {}, y := {}             ; Create two objects.
167 | x.child := y, y.parent := x  ; Create a circular reference.
168 | 
169 | y.parent := ""               ; The circular reference must be removed before the objects can be freed.
170 | x := "", y := ""             ; Without the above line, this would not free the objects.
171 | 
172 |

For more advanced usage and details, see Reference Counting.

173 | 174 |

Extended Usage

175 | 176 |

Arrays of Arrays

177 |

Although "multi-dimensional" arrays are not supported, a script can combine multiple arrays or maps. For example:

178 |
179 | grid := [[1,2,3],
180 |          [4,5,6],
181 |          [7,8,9]]
182 | MsgBox grid[1][3] ; 3
183 | MsgBox grid[3][2] ; 8
184 | 
185 |

A custom object can implement multi-dimensional support by defining an __Item property. For example:

186 |
187 | class Array2D extends Array {
188 |     __new(x, y) {
189 |         this.Length := x * y
190 |         this.Width := x
191 |         this.Height := y
192 |     }
193 |     __Item[x, y] {
194 |         get => super.Has(this.i[x, y]) ? super[this.i[x, y]] : false
195 |         set => super[this.i[x, y]] := value
196 |     }
197 |     i[x, y] => this.Width * (y-1) + x
198 | }
199 | 
200 | grid := Array2D(4, 3)
201 | grid[4, 1] := "#"
202 | grid[3, 2] := "#"
203 | grid[2, 2] := "#"
204 | grid[1, 3] := "#"
205 | gridtext := ""
206 | Loop grid.Height {
207 |     y := A_Index
208 |     Loop grid.Width {
209 |         x := A_Index
210 |         gridtext .= grid[x, y] || "-"
211 |     }
212 |     gridtext .= "`n"
213 | }
214 | MsgBox gridtext
215 | 
216 |

A real script should perform error-checking and override other methods, such as __Enum to support enumeration.

217 | 218 |

Custom Objects

219 |

There are two general ways to create custom objects:

220 | 224 |

Meta-functions can be used to further control how an object behaves.

225 |

Note: Within this section, an object is any instance of the Object class. This section does not apply to COM objects.

226 | 227 |

Ad Hoc

228 |

Properties and methods (callable properties) can generally be added to new objects at any time. For example, an object with one property and one method might be constructed like this:

229 |
; Create an object.
230 | thing := {}
231 | ; Store a value.
232 | thing.foo := "bar"
233 | ; Define a method.
234 | thing.test := thing_test
235 | ; Call the method.
236 | thing.test()
237 | 
238 | thing_test(this) {
239 |     MsgBox this.foo
240 | }
241 |

You could similarly create the above object with thing := {foo: "bar"}. When using the {property:value} notation, quote marks must not be used for properties.

242 |

When thing.test() is called, thing is automatically inserted at the beginning of the parameter list. By convention, the function is named by combining the "type" of object and the method name, but this is not a requirement.

243 |

In the example above, test could be assigned some other function or value after it is defined, in which case the original function is lost and cannot be called via this property. An alternative is to define a read-only method, as shown below:

244 |
thing.DefineProp('test', {call: thing_test})
245 |

See also: DefineProp

246 | 247 |

Delegation

248 |

Objects are prototype-based. That is, any properties not defined in the object itself can instead be defined in the object's base. This is known as inheritance by delegation or differential inheritance, because an object can implement only the parts that make it different, while delegating the rest to its base.

249 |

Although a base object is also generally known as a prototype, we use "a class's Prototype" to mean the object upon which every instance of the class is based, and "base" to mean the object upon which an instance is based.

250 |

AutoHotkey's object design was influenced primarily by JavaScript and Lua, with a little C#. We use obj.base in place of JavaScript's obj.__proto__ and cls.Prototype in place of JavaScript's func.prototype. (Class objects are used in place of constructor functions.)

251 | 252 |

An object's base is also used to identify its type or class. For example, x := [] creates an object based on Array.Prototype, which means that the expressions x is Array and x.HasBase(Array.Prototype) are true, and type(x) returns "Array". Each class's Prototype is based on the Prototype of its base class, so x.HasBase(Object.Prototype) is also true.

253 |

Any instance of Object or a derived class can be a base object, but an object can only be assigned as the base of an object with the same native type. This is to ensure that built-in methods can always identify the native type of an object, and operate only on objects that have the correct binary structure.

254 |

Base objects can be defined two different ways:

255 | 259 |

A base object can be assigned to the base property of another object, but typically an object's base is set implicitly when it is created.

260 | 261 |

Creating a Base Object

262 |

Any object can be used as the base of any other object which has the same native type. The following example builds on the previous example under Ad Hoc (combine the two before running it):

263 |
other := {}
264 | other.base := thing
265 | other.test()
266 |

In this case, other inherits foo and test from thing. This inheritance is dynamic, so if thing.foo is modified, the change will be reflected by other.foo. If the script assigns to other.foo, the value is stored in other and any further changes to thing.foo will have no effect on other.foo. When other.test() is called, its this parameter contains a reference to other instead of thing.

267 | 268 |

Classes

269 |
In object-oriented programming, a class is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods). 270 | Wikipedia
271 |

In more general terms, a class is a set or category of things having some property or attribute in common. In AutoHotkey, a class defines properties to be shared by instances of the class (and methods, which are callable properties). An instance is just an object which inherits properties from the class, and can typically also be identified as belonging to that class (such as with the expression instance is ClassName). Instances are typically created by calling ClassName().

272 |

Since Objects are dynamic and prototype-based, each class consists of two parts:

273 | 277 |

The following shows most of the elements of a class definition:

278 |
class ClassName extends BaseClassName
279 | {
280 |     InstanceVar := Expression
281 |     
282 |     static ClassVar := Expression
283 | 
284 |     class NestedClass
285 |     {
286 |         ...
287 |     }
288 | 
289 |     Method()
290 |     {
291 |         ...
292 |     }
293 |     
294 |     static Method()
295 |     {
296 |         ...
297 |     }
298 | 
299 |     Property[Parameters]  ; Use brackets only when parameters are present.
300 |     {
301 |         get {
302 |             return value of property
303 |         }
304 |         set {
305 |             Store or otherwise handle value
306 |         }
307 |     }
308 |     
309 |     ShortProperty
310 |     {
311 |         get => Expression which calculates property value
312 |         set => Expression which stores or otherwise handles value
313 |     }
314 |     
315 |     ShorterProperty => Expression which calculates property value
316 | }
317 | 
318 |

When the script is loaded, this constructs a Class object and stores it in a global constant (read-only variable) with the name ClassName. If extends BaseClassName is present, BaseClassName must be the full name of another class. The full name of each class is stored in ClassName.Prototype.__Class.

319 |

Because the class itself is accessed through a variable, the class name cannot be used to both reference the class and create a separate variable (such as to hold an instance of the class) in the same context. For example, box := Box() will not work, because box and Box both resolve to the same thing. Attempting to reassign a top-level (not nested) class in this manner results in a load time error.

320 |

Within this documentation, the word "class" on its own usually means a class object constructed with the class keyword.

321 |

Class definitions can contain variable declarations, method definitions and nested class definitions.

322 | 323 |

Instance Variables

324 |

An instance variable is one that each instance of the class has its own copy of. They are declared and behave like normal assignments, but the this. prefix is omitted (only directly within the class body):

325 |
InstanceVar := Expression
326 |

These declarations are evaluated each time a new instance of the class is created with ClassName(), after all base-class declarations are evaluated but before __New is called. This is achieved by automatically creating a method named __Init containing a call to super.__Init() and inserting each declaration into it. Therefore, a single class definition must not contain both an __Init method and an instance variable declaration.

327 |

Expression can access other instance variables and methods via this. Global variables may be read, but not assigned. An additional assignment (or use of the reference operator) within the expression will generally create a variable local to the __Init method. For example, x := y := 1 would set this.x and a local variable y (which would be freed once all initializers have been evaluated).

328 |

To access an instance variable (even within a method), always specify the target object; for example, this.InstanceVar.

329 |

Declarations like x.y := z are also supported, provided that x was previously defined in this class. For example, x := {}, x.y := 42 declares x and also initializes this.x.y.

330 | 331 |

Static/Class Variables

332 |

Static/class variables belong to the class itself, but their values can be inherited by subclasses. They are declared like instance variables, but using the static keyword:

333 |
static ClassVar := Expression
334 |

These declarations are evaluated only once, when the class is initialized. A static method named __Init is automatically defined for this purpose.

335 |

Each declaration acts as a normal property assignment, with the class object as the target. Expression has the same interpretation as for instance variables, except that this refers to the class itself.

336 |

To assign to a class variable anywhere else, always specify the class object; for example, ClassName.ClassVar := Value. If a subclass does not own a property by that name, Subclass.ClassVar can also be used to retrieve the value; so if the value is a reference to an object, subclasses will share that object by default. However, Subclass.ClassVar := y would store the value in Subclass, not in ClassName.

337 |

Declarations like static x.y := z are also supported, provided that x was previously defined in this class. For example, static x := {}, x.y := 42 declares x and also initializes ClassName.x.y. Because Prototype is implicitly defined in each class, static Prototype.sharedValue := 1 can be used to set values which are dynamically inherited by all instances of the class (until shadowed by a property on the instance itself).

338 | 339 |

Nested Classes

340 |

Nested class definitions allow a class object to be associated with a static/class variable of the outer class instead of a separate global variable. In the example above, class NestedClass constructs a Class object and stores it in ClassName.NestedClass. Subclasses could inherit NestedClass or override it with their own nested class (in which case WhichClass.NestedClass() could be used to instantiate whichever class is appropriate).

341 |
342 | class NestedClass
343 | {
344 |     ...
345 | }
346 | 
347 |

Nesting a class does not imply any particular relationship to the outer class. The nested class is not instantiated automatically, nor do instances of the nested class have any connection with an instance of the outer class, unless the script explicitly makes that connection.

348 |

Each nested class definition produces a dynamic property with get and call accessor functions instead of a simple value property. This is to support the following behaviour (where class X contains the nested class Y):

349 | 354 | 355 |

Methods

356 |

Method definitions look identical to function definitions. Each method definition creates a Func with a hidden first parameter named this, and defines a property which is used to call the method or retrieve its function object.

357 |

There are two types of methods:

358 | 362 |

The method definition below creates a property of the same type as target.DefineProp('Method', {call: funcObj}). By default, target.Method returns funcObj and attempting to assign to target.Method throws an error. These defaults can be overridden by defining a property or calling DefineProp.

363 |
364 | Method()
365 | {
366 |     ...
367 | }
368 | 
369 | 370 |

Fat arrow syntax can be used to define a single-line method which returns an expression:

371 |
Method() => Expression
372 | 373 |

Super

374 |

Inside a method or a property getter/setter, the keyword super can be used in place of this to access the superclass versions of methods or properties which are overridden in a derived class. For example, super.Method() in the class defined above would typically call the version of Method which was defined within BaseClassName. Note:

375 | 381 |

The keyword super must be followed by one of the following symbols: .[(

382 |

super() is equivalent to super.call().

383 | 384 |

Properties

385 |

A property definition creates a dynamic property, which calls a method instead of simply storing or returning a value.

386 |
Property[Parameters]
387 | {
388 |     get {
389 |         return property value
390 |     }
391 |     set {
392 |         Store or otherwise handle value
393 |     }
394 | }
395 | 
396 |

Property is simply the name of the property, which will be used to invoke it. For example, obj.Property would call get while obj.Property := value would call set. Within get or set, this refers to the object being invoked. Within set, value contains the value being assigned.

397 |

Parameters can be defined by enclosing them in square brackets to the right of the property name, and are passed the same way - but they should be omitted when parameters are not present (see below). Aside from using square brackets, parameters of properties are defined the same way as parameters of methods - optional, ByRef and variadic parameters are supported.

398 |

If a property is invoked with parameters but has none defined, parameters are automatically forwarded to the __Item property of the object returned by get. For example, this.Property[x] would have the same effect as (this.Property)[x] or y := this.Property, y[x]. Empty brackets (this.Property[]) always cause the __Item property of Property's value to be invoked, but a variadic call such as this.Property[args*] has this effect only if the number of parameters is non-zero.

399 |

Static properties can be defined by preceding the property name with the separate keyword static. In that case, this refers to the class itself or a subclass.

400 |

The return value of set is ignored. For example, val := obj.Property := 42 always assigns val := 42 regardless of what the property does, unless it throws an exception or exits the thread.

401 |

Each class can define one or both halves of a property. If a class overrides a property, it can use super.Property to access the property defined by its base class. If Get or Set is not defined, it can be inherited from a base object. If Get is undefined, the property can return a value inherited from a base. If Set is undefined in this and all base objects (or is obscured by an inherited value property), attempting to set the property causes an exception to be thrown.

402 |

A property definition with both get and set actually creates two separate functions, which do not share local or static variables or nested functions. As with methods, each function has a hidden parameter named this, and set has a second hidden parameter named value. Any explicitly defined parameters come after those.

403 |

While a property definition defines the get and set accessor functions for a property in the same way as DefineProp, a method definition defines the call accessor function. Any class may contain a property definition and a method definition with the same name. If a property without a call accessor function (a method) is called, get is invoked with no parameters and the result is then called as a method.

404 | 405 |

Fat Arrow Properties

406 |

Fat arrow syntax can be used to define a property getter or setter which returns an expression:

407 |
ShortProperty[Parameters]
408 | {
409 |     get => Expression which calculates property value
410 |     set => Expression which stores or otherwise handles value
411 | }
412 |

When defining only a getter, the braces and get can be omitted:

413 |
ShorterProperty[Parameters] => Expression which calculates property value
414 |

In both cases, the square brackets must be omitted unless parameters are defined.

415 | 416 |

__Enum Method

417 |
__Enum(NumberOfVars)
418 |

The __Enum method is called when the object is passed to a for-loop. This method should return an enumerator which will return items contained by the object, such as array elements. If left undefined, the object cannot be passed directly to a for-loop unless it has an enumerator-compatible Call method.

419 |

NumberOfVars contains the number of variables passed to the for-loop. If NumberOfVars is 2, the enumerator is expected to assign the key or index of an item to the first parameter and the value to the second parameter. Each key or index should be accepted as a parameter of the __Item property. This enables DBGp-based debuggers to get or set a specific item after listing them by invoking the enumerator.

420 | 421 |

__Item Property

422 |

The __Item property is invoked when the indexing operator (array syntax) is used with the object. In the following example, the property is declared as static so that the indexing operator can be used on the Env class itself. For another example, see Array2D.

423 |
class Env {
424 |     static __Item[name] {
425 |         get => EnvGet(name)
426 |         set => EnvSet(name, value)
427 |     }
428 | }
429 | 
430 | Env["PATH"] .= ";" A_ScriptDir  ; Only affects this script and child processes.
431 | MsgBox Env["PATH"]
432 |

__Item is effectively a default property name (if such a property has been defined):

433 | 437 |

For example:

438 |
439 | obj := {}
440 | obj[] := Map()     ; Equivalent to obj.__Item := Map()
441 | obj["base"] := 10
442 | MsgBox obj.base = Object.prototype  ; True
443 | MsgBox obj["base"]                  ; 10
444 | 
445 |

Note: When an explicit property name is combined with empty brackets, as in obj.prop[], it is handled as two separate operations: first retrieve obj.prop, then invoke the default property of the result. This is part of the language syntax, so is not dependent on the object.

446 | 447 |

Construction and Destruction

448 |

Whenever an object is created by the default implementation of ClassName(), the new object's __New method is called in order to allow custom initialization. Any parameters passed to ClassName() are forwarded to __New, so can affect the object's initial content or how it is constructed. When an object is destroyed, __Delete is called. For example:

449 |
m1 := GMem(0, 10)
450 | m2 := {base: GMem.Prototype}, m2.__New(0, 30)
451 | 
452 | ; Note: For general memory allocations, use Buffer() instead.
453 | class GMem
454 | {
455 |     __New(aFlags, aSize)
456 |     {
457 |         this.ptr := DllCall("GlobalAlloc", "UInt", aFlags, "Ptr", aSize, "Ptr")
458 |         if !this.ptr
459 |             throw MemoryError()
460 |         MsgBox "New GMem of " aSize " bytes at address " this.ptr "."
461 |     }
462 | 
463 |     __Delete()
464 |     {
465 |         MsgBox "Delete GMem at address " this.ptr "."
466 |         DllCall("GlobalFree", "Ptr", this.ptr)
467 |     }
468 | }
469 |

__Delete is not called for any object which owns a property named "__Class". Prototype objects have this property by default.

470 |

If an exception or runtime error is thrown while __Delete is executing and is not handled within __Delete, it acts as though __Delete was called from a new thread. That is, an error dialog is displayed and __Delete returns, but the thread does not exit (unless it was already exiting).

471 |

If the script is directly terminated by any means, including the tray menu or ExitApp, any functions which have yet to return do not get the chance to do so. Therefore, any objects referenced by local variables of those functions are not released, so __Delete is not called. Temporary references on the expression evaluation stack are also not released under such circumstances.

472 |

When the script exits, objects contained by global and static variables are released automatically in an arbitrary, implementation-defined order. When __Delete is called during this process, some global or static variables may have already been released, but any references contained by the object itself are still valid. It is therefore best for __Delete to be entirely self-contained, and not rely on any global or static variables.

473 | 474 |

Class Initialization

475 |

Each class is initialized automatically when a reference to the class is evaluated for the first time. For example, if MyClass has not yet been initialized, MyClass.MyProp would cause the class to be initialized before the property is retrieved. Initialization consists of calling two static methods: __Init and __New.

476 |

static __Init is defined automatically for every class, and always begins with a reference to the base class if one was specified, to ensure it is initialized. Static/class variables and nested classes are initialized in the order that they were defined, except when a nested class is referenced during initialization of a previous variable or class.

477 |

If the class defines or inherits a static __New method, it is called immediately after __Init. It is important to note that __New may be called once for the class in which it is defined and once for each subclass which does not define its own (or which calls super.__New()). This can be used to perform common initialization tasks for each subclass, or modify subclasses in some way before they are used.

478 |

If static __New is not intended to act on derived classes, that can be avoided by checking the value of this. In some cases it may be sufficient for the method to delete itself, such as with this.DeleteProp('__New'); however, the first execution of __New might be for a subclass if one is nested in the base class or referenced during initialization of a static/class variable.

479 |

A class definition also has the effect of referencing the class. In other words, when execution reaches a class definition during script startup, __Init and __New are called automatically, unless the class was already referenced by the script. However, if execution is prevented from reaching the class definition, such as by return or an infinite loop, the class is initialized only if it is referenced.

480 |

Once automatic initialization begins, it will not occur again for the same class. This is generally not a problem unless multiple classes refer to each other. For example, consider the two classes below. When A is initialized first, evaluating B.SharedArray (A1) causes B to be initialized before retrieving and returning the value, but A.SharedValue (A3) is undefined and does not cause initialization of A because it is already in progress. In other words, if A is accessed or initialized first, the order is A1 to A3; otherwise it is B1 to B4:

481 |
MsgBox A.SharedArray.Length
482 | MsgBox B.SharedValue
483 | 
484 | class A {
485 |     static SharedArray := B.SharedArray   ; A1          ; B3
486 |     static SharedValue := 42                            ; B4
487 | }
488 | 
489 | class B {
490 |     static SharedArray := StrSplit("XYZ") ; A2          ; B1
491 |     static SharedValue := A.SharedValue   ; A3 (Error)  ; B2
492 | }
493 | 494 |

Meta-Functions

495 |
496 | class ClassName {
497 |     __Get(Name, Params)
498 |     __Set(Name, Params, Value)
499 |     __Call(Name, Params)
500 | }
501 | 
502 |
503 |
Name
504 |

The name of the property or method.

505 |
Params
506 |

An Array of parameters. This includes only the parameters between () or [], so may be empty. The meta-function is expected to handle cases such as x.y[z] where x.y is undefined.

507 |
Value
508 |

The value being assigned.

509 |
510 |

Meta-functions define what happens when an undefined property or method is invoked. For example, if obj.unk has not been assigned a value, it invokes the __Get meta-function. Similarly, obj.unk := value invokes __Set and obj.unk() invokes __Call.

511 |

Properties and methods can be defined in the object itself or any of its base objects. In general, for a meta-function to be called for every property, one must avoid defining any properties. Built-in properties such as Base can be overridden with a property definition or DefineProp.

512 |

If a meta-function is defined, it must perform whatever default action is required. For example, the following might be expected:

513 | 519 |

Any callable object can be used as a meta-function by assigning it to the relevant property.

520 |

Meta-functions are not called in the following cases:

521 | 526 | 527 |

Dynamic Properties

528 |

Property syntax and DefineProp can be used to define properties which compute a value each time they are evaluated, but each property must be defined in advance. By contrast, __Get and __Set can be used to implement properties which are known only at the moment they are invoked.

529 |

For example, a "proxy" object could be created which sends requests for properties over the network (or through some other channel). A remote server would send back a response containing the value of the property, and the proxy would return the value to its caller. Even if the name of each property was known in advance, it would not be logical to define each property individually in the proxy class since every property does the same thing (send a network request). Meta-functions receive the property name as a parameter, so are a good solution to this problem.

530 | 531 |

Primitive Values

532 |

Primitive values, such as strings and numbers, cannot have their own properties and methods. However, primitive values support the same kind of delegation as objects. That is, any property or method call on a primitive value is delegated to a predefined prototype object, which is also accessible via the Prototype property of the corresponding class. The following classes relate to primitive values:

533 | 542 |

Although checking the Type string is generally faster, the type of a value can be tested by checking whether it has a given base. For example, n.HasBase(Number.Prototype) or n is Number is true if n is a pure Integer or Float, but not if n is a numeric string, since String does not derive from Number. By contrast, IsNumber(n) is true if n is a number or a numeric string.

543 |

ObjGetBase and the Base property return one of the predefined prototype objects when appropriate.

544 |

Note that x is Any would ordinarily be true for any value within AutoHotkey's type hierarchy, but false for COM objects.

545 | 546 |

Adding Properties and Methods

547 |

Properties and methods can be added for all values of a given type by modifying that type's prototype object. However, since a primitive value is not an Object and cannot have its own properties or methods, the primitive prototype objects do not derive from Object.Prototype. In other words, methods such as DefineProp and HasOwnProp are not accessible by default. They can be called indirectly. For example:

548 |
549 | DefProp := {}.DefineProp
550 | DefProp( "".base, "Length", { get: StrLen } )
551 | MsgBox A_AhkPath.length " == " StrLen(A_AhkPath)
552 | 
553 |

Although primitive values can inherit value properties from their prototype, an exception is thrown if the script attempts to set a value property on a primitive value. For example:

554 |
"".base.test := 1  ; Don't try this at home.
555 | MsgBox "".test  ; 1
556 | "".test := 2  ; Error: Property is read-only.
557 |

Although __Set and property setters can be used, they are not useful since primitive values should be considered immutable.

558 | 559 |

Implementation

560 |

Reference Counting

561 |

AutoHotkey uses a basic reference counting mechanism to automatically free the resources used by an object when it is no longer referenced by the script. Understanding this mechanism can be essential for properly managing the lifetime of an object, allowing it to be deleted when it is no longer needed, and not before then.

562 |

An object's reference count is incremented whenever a reference is stored. When a reference is released, the count is used to determine whether that reference is the last one. If it is, the object is deleted; otherwise, the count is decremented. The following example shows how references are counted in some simple cases:

563 |
564 | a := {Name: "Bob"}  ; Bob's ref count is initially 1
565 | b := [a]            ; Bob's ref count is incremented to 2
566 | a := ""             ; Bob's ref count is decremented to 1
567 | c := b.Pop()        ; Bob is transferred, ref count still 1
568 | c := ""             ; Bob is deleted...
569 | 
570 |

Temporary references returned by functions, methods or operators within an expression are released after evaluation of that expression has completed or been aborted. In the following example, the new GMem object is freed only after MsgBox has returned:

571 |
MsgBox DllCall("GlobalSize", "ptr", GMem(0, 20).ptr, "ptr")  ; 20
572 |

Note: In this example, .ptr could have been omitted since the Ptr arg type permits objects with a Ptr property. However, the pattern shown above will work even with other property names.

573 |

To run code when the last reference to an object is being released, implement the __Delete meta-function.

574 |

Problems with Reference Counting

575 |

Relying solely on reference counting sometimes creates catch-22 situations: an object is designed to free its resources when deleted, but would only be deleted if its resources are first freed. Specifically, this occurs when those resources are other objects or functions which retain a reference to the object, often indirectly.

576 |

A circular reference or reference cycle is when an object directly or indirectly refers to itself. If each reference which is part of the cycle is included in the count, the object cannot be deleted until the cycle is manually broken. For example, the following creates a reference cycle:

577 |
parent := {}  ; parent: 1 (reference count)
578 | child := {parent: parent}  ; parent: 2, child: 1
579 | parent.child := child  ; parent: 2, child: 2
580 |

If the variables parent and child are reassigned, the reference count for each object is decremented to 1. Both objects would be inaccessible to the script, but would not be deleted because the last references are not released.

581 |

A cycle is often less obvious than this, and can involve several objects. For example, ShowRefCycleGui demonstrates a cycle involving a Gui, MenuBar, Menu and closures. The use of a separate object to handle GUI events is also prone to cycles, if the handler object has a reference to the GUI.

582 |

Non-cyclic references to an object can also cause issues. For instance, objects with a dependency on built-in functions like SetTimer or OnMessage generally cause the program to hold an indirect reference to the object. This would prevent the object from being deleted, which means that it cannot use __New and __Delete to manage the timer or message monitor.

583 |

Below are several strategies for solving issues like those described above.

584 |

Avoid cycles: If reference cycles are a problem, avoid creating them. For example, either parent.child or child.parent would not be set. This is often not practical, as related objects may need a way to refer to each other.

585 |

When defining event handlers for OnEvent (Gui), avoid capturing the source Gui in a closure or bound function and instead utilize the Gui or Gui.Control parameter. Likewise for Add (Menu) and the callback's Menu parameter, but of course, a menu item which needs to refer to a Gui cannot use this approach.

586 |

In some cases, the other object can be retrieved by an indirect method which doesn't rely on a counted reference. For example, retain a HWND and use GuiFromHwnd(hwnd) to retrieve a Gui object. Retaining a reference is not necessary to prevent deletion while the window is visible, as the Gui itself handles this.

587 |

Break cycles: If the script can avoid relying on reference counting and instead manage the lifetime of the object directly, it needs only break the cycle when the objects are to be deleted:

588 |
child.parent := unset  ; parent: 1, child: 2
589 | child := unset  ; parent: 1, child: 1
590 | parent := unset  ; both deleted
591 |

Dispose: __Delete is called precisely when the last reference is released, so one might come to think of a simple assignment like myGui := "" as a cleanup step which triggers deletion of the object. Sometimes this is done explicitly when the object is no longer needed, but it is neither reliable nor truly showing the intent of the code. An alternative pattern is to define a Dispose or Destroy method which frees the object's resources, and design it to do nothing if called a second time. It can then also be called from __Delete, as a safeguard.

592 |

An object following this pattern would still need to break any reference cycles when it is disposed, otherwise some memory would not be reclaimed, and __Delete would not be called for other objects referenced by the object.

593 |

Cycles caused by a Gui object's event handlers, MenuBar or event sink object are automatically "broken" when Destroy is called, as it releases those objects. (This is demonstrated in the ShowRefCycleGui example.) However, this would not break cycles caused by new properties which the script has added, as Destroy does not delete them.

594 |

Similar to the Dispose pattern, InputHook has a Stop method which must be called explicitly, so it does not rely on __Delete to signal when its operation should end. While operating, the program effectively holds a reference to the object which prevents it from being deleted, but this becomes a strength rather than a flaw: event callbacks can still be called and will receive the InputHook as a parameter. When the operation ends, the internal reference is released and the InputHook is deleted if the script has no reference to it.

595 |

Pointers: Storing any number of pointer values does not affect the reference count of the object, since a pointer is just an integer. A pointer retrieved with ObjPtr can be used to produce a reference by passing it to ObjFromPtrAddRef. The AddRef version of the function must be used because the reference count will be decremented when the temporary reference is automatically released.

596 |

For example, suppose that an object needs to update some properties each second. A timer holds a reference to the callback function, which has the object bound as a parameter. Normally this would prevent the object from being deleted before the timer is deleted. Storing a pointer instead of a reference allows the object to be deleted regardless of the timer, so it can be managed automatically by __New and __Delete.

597 |
a := SomeClass()
598 | Sleep 5500  ; Let the timer run 5 times.
599 | a := ""
600 | Sleep 3500  ; Prevent exit temporarily to show that the timer has stopped.
601 | 
602 | class SomeClass {
603 |     __New() {
604 |         ; The closure must be stored so that the timer can be deleted later.
605 |         ; Synthesize a counted reference each time the method needs to be called.
606 |         this.Timer := (p => ObjFromPtrAddRef(p).Update()).Bind(ObjPtr(this))
607 |         SetTimer this.Timer, 1000
608 |     }
609 |     __Delete() {
610 |         SetTimer this.Timer, 0
611 |         ; If this object is truly deleted, all properties will be
612 |         ; deleted and the following __Delete method will be called.
613 |         ; This is just for confirmation and wouldn't normally be used.
614 |         this.Test := {__Delete: test => ToolTip("object deleted")}
615 |     }
616 |     ; This is just to demonstrate that the timer is running.
617 |     ; Hypothetically, this class has some other purpose.
618 |     count := 0
619 |     Update() => ToolTip(++this.count)
620 | }
621 |

A drawback of this approach is that the pointer is not directly usable as an object, and is not recognized as such by Type or the debugger. The script must be absolutely certain not to use the pointer after the object is deleted, as doing so is invalid and the result would be indeterminate.

622 |

If the pointer-reference is needed in multiple places, encapsulating it might make sense. For instance, b := ObjFromPtrAddRef.Bind(ObjPtr(this)) would produce a BoundFunc which can be called (b()) to retrieve the reference, while ((this, p) => ObjFromPtrAddRef(p)).Bind(ObjPtr(this)) can be used as a property getter (the property would return a reference).

623 |

Uncounted references: If the object's reference count accounts for a reference, we call it a counted reference, otherwise we call it an uncounted reference. The idea of the latter is to allow the script to store a reference which does not prevent the object from being deleted.

624 |

Note: This is about how the object's reference count relates to a given reference as per the script's logic, and doesn't affect the nature of the reference itself. The program will still attempt to release the reference automatically at whatever time it would normally, so the terms weak reference and strong reference are unsuitable.

625 |

A counted reference can be turned into an uncounted reference by simply decrementing the object's reference count. This must be reversed before the reference is released, which must occur before the object is deleted. Since the point of an uncounted reference is to allow the object to be deleted without first manually unsetting the reference, generally the count must be corrected within that object's own __Delete method.

626 |

For example, __New and __Delete from the previous example can be replaced with the following.

627 |
    __New() {
628 |         ; The BoundFunc must be stored so that the timer can be deleted later.
629 |         SetTimer this.Timer := this.Update.Bind(this), 1000
630 |         ; Decrement ref count to compensate for the AddRef done by Bind.
631 |         ObjRelease(ObjPtr(this))
632 |     }
633 |     __Delete() {
634 |         ; Increment ref count so that the ref within the BoundFunc
635 |         ; can be safely released.
636 |         ObjPtrAddRef(this)
637 |         ; Delete the timer to release its reference to the BoundFunc.
638 |         SetTimer this.Timer, 0
639 |         ; Release the BoundFunc. This may not happen automatically
640 |         ; due to the reference cycle which exists now that the ref
641 |         ; in the BoundFunc is counted again.
642 |         this.Timer := unset
643 |         ; If this object is truly deleted, all properties will be
644 |         ; deleted and the following __Delete method will be called.
645 |         ; This is just for confirmation and wouldn't normally be used.
646 |         this.Test := {__Delete: test => ToolTip("object deleted")}
647 |     }
648 |

This can generally be applied regardless of where the uncounted reference is stored and what it is used for. The key points are:

649 | 654 |

The reference count must be incremented and decremented as many times as there are references which are intended to be uncounted. This may not be practical if the script cannot accurately predict how many references will be stored by some function.

655 | 656 |

Pointers to Objects

657 |

As part of creating an object, some memory is allocated to hold the basic structure of the object. This structure is essentially the object itself, so we call its address a pointer to the object. An address is an integer value which corresponds to a location within the virtual memory of the current process, and is valid only until the object is deleted.

658 |

In some rare cases it may be necessary to pass an object to external code via DllCall or store it in a binary data structure for later retrieval. An object's address can be retrieved via address := ObjPtr(myObject); however, this effectively makes two references to the object, but the program only knows about the one in myObject. If the last known reference to the object was released, the object would be deleted. Therefore, the script must inform the object that it has gained a reference. This can be done as follows (the two lines below are equivalent):

659 |
660 | ObjAddRef(address := ObjPtr(myObject))
661 | address := ObjPtrAddRef(myObject)
662 | 
663 |

The script must also inform the object when it is finished with that reference:

664 |
ObjRelease(address)
665 |

Generally each new copy of an object's address should be treated as another reference to the object, so the script should call ObjAddRef when it gains a copy and ObjRelease immediately before losing one. For example, whenever an address is copied via something like x := address, ObjAddRef should be called. Similarly, when the script is finished with x (or is about to overwrite x's value), it should call ObjRelease.

666 |

To convert an address to a proper reference, use the ObjFromPtr function:

667 |
myObject := ObjFromPtr(address)
668 |

ObjFromPtr assumes that address is a counted reference, and claims ownership of it. In other words, myObject := "" would cause the reference originally represented by address to be released. After that, address must be considered invalid. To instead make a new reference, use one of the following:

669 |
670 | ObjAddRef(address), myObject := ObjFromPtr(address)
671 | myObject := ObjFromPtrAddRef(address)
672 | 
673 | 674 | 675 | 676 | -------------------------------------------------------------------------------- /docs/Program.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Using the Program | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Using the Program

13 |

AutoHotkey doesn't do anything on its own; it needs a script to tell it what to do. A script is simply a plain text file with the .ahk filename extension containing instructions for the program, like a configuration file, but much more powerful. A script can do as little as performing a single action and then exiting, but most scripts define a number of hotkeys, with each hotkey followed by one or more actions to take when the hotkey is pressed.

14 |
#z::Run "https://www.autohotkey.com"  ; Win+Z
 15 | 
 16 | ^!n::  ; Ctrl+Alt+N
 17 | {
 18 |     if WinExist("Untitled - Notepad")
 19 |         WinActivate
 20 |     else
 21 |         Run "Notepad"
 22 | }
23 |

Tip: If your browser supports it, you can download any code block (such as the one above) as a script file by clicking the button which appears in the top-right of the code block when you hover your mouse over it.

24 | 25 |

Table of Contents

26 | 43 | 44 |

Create a Script

45 |

There are a few common ways to create a script file:

46 | 52 |

See Scripting Language for details about how to write a script.

53 | 54 |

Edit a Script

55 |

To open a script for editing, right-click on the script file and select Edit Script. If the script is already running, you can use the Edit function or right-click the script's tray icon and select Edit Script. If you haven't selected a default editor yet, you should be prompted to select one. Otherwise, you can change your default editor via Editor settings in the Dash. Of course, you can always open a text editor first and then open the script as you would any other text file.

56 |

After editing a script, you must run or reload the script for the changes to take effect. A running script can usually be reloaded via its tray menu.

57 | 58 |

Run a Script

59 |

With AutoHotkey installed, there are several ways to run a script:

60 | 66 |

Most scripts have an effect only while they are running. Use the tray menu or the ExitApp function to exit a script. Scripts are also forced to exit when Windows shuts down. To configure a script to start automatically after the user logs in, the easiest way is to place a shortcut to the script file in the Startup folder.

67 |

Scripts can also be compiled; that is, combined together with an AutoHotkey binary file to form a self-contained executable (.exe) file.

68 | 69 |

Tray Icon

70 |

By default, each script adds its own icon to the taskbar notification area (commonly known as the tray).

71 |

The tray icon usually looks like this:

72 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
green H iconThe default tray icon.
green icon with a Pause symbolThe script is paused.
green icon with a transparent HThe script is suspended.
green icon with a transparent Pause symbolThe script is paused and suspended.
96 |

Right-click the tray icon to show the tray menu, which has the following options by default:

97 | 107 |

By default, double-clicking the tray icon shows the script's main window.

108 |

The behavior and appearance of the tray icon and menu can be customized:

109 | 115 | 116 |

Main Window

117 |

The script's main window is usually hidden, but can be shown via the tray icon or one of the functions listed below to gain access to information useful for debugging the script. Items under the View menu control what the main window displays:

118 | 124 |

Known issue: Keyboard shortcuts for menu items do not work while the script is displaying a message box or other dialog.

125 |

The built-in variable A_ScriptHwnd contains the unique ID (HWND) of the script's main window.

126 |

Closing this window with WinClose (even from another script) causes the script to exit, but most other methods just hide the window and leave the script running.

127 |

Minimizing the main window causes it to automatically be hidden. This is done to prevent any owned windows (such as GUI windows or certain dialog windows) from automatically being minimized, but also has the effect of hiding the main window's taskbar button. To instead allow the main window to be minimized normally, override the default handling with OnMessage. For example:

128 |
; This prevents the main window from hiding on minimize:
129 | OnMessage 0x0112, PreventAutoMinimize ; WM_SYSCOMMAND = 0x0112
130 | OnMessage 0x0005, PreventAutoMinimize ; WM_SIZE = 0x0005
131 | ; This prevents owned GUI windows (but not dialogs) from automatically minimizing:
132 | OnMessage 0x0018, PreventAutoMinimize
133 | Persistent
134 | 
135 | PreventAutoMinimize(wParam, lParam, uMsg, hwnd) {
136 |     if (uMsg = 0x0112 && wParam = 0xF020 && hwnd = A_ScriptHwnd) { ; SC_MINIMIZE = 0xF020
137 |         WinMinimize
138 |         return 0 ; Prevent main window from hiding.
139 |     }
140 |     if (uMsg = 0x0005 && wParam = 1 && hwnd = A_ScriptHwnd) ; SIZE_MINIMIZED = 1
141 |         return 0 ; Prevent main window from hiding.
142 |     if (uMsg = 0x0018 && lParam = 1) ; SW_PARENTCLOSING = 1
143 |         return 0 ; Prevent owned window from minimizing.
144 | }
145 | 146 |

Main Window Title

147 |

The title of the script's main window is used by the #SingleInstance and Reload mechanisms to identify other instances of the same script. Changing the title prevents the script from being identified as such. The default title depends on how the script was loaded:

148 | 149 | 150 | 151 | 152 | 153 |
Loaded FromTitle ExpressionExample
.ahk fileA_ScriptFullPath " - AutoHotkey v" A_AhkVersionE:\My Script.ahk - AutoHotkey v1.1.33.09
Main resource (compiled script)A_ScriptFullPathE:\My Script.exe
Any other resourceA_ScriptFullPath " - " A_LineFileE:\My AutoHotkey.exe - *BUILTIN-TOOL.AHK
154 |

The following code illustrates how the default title could be determined by the script itself (but the actual title can be retrieved with WinGetTitle):

155 |
156 | title := A_ScriptFullPath
157 | if !A_IsCompiled
158 |     title .= " - AutoHotkey v" A_AhkVersion
159 | ; For the correct result, this must be evaluated by the resource being executed,
160 | ; not an #include (unless the #include was merged into the script by Ahk2Exe):
161 | else if SubStr(A_LineFile, 1, 1) = "*" && A_LineFile != "*#1"
162 |     title .= " - " A_LineFile
163 | 
164 | 165 |

Embedded Scripts

166 |

Scripts may be embedded into a standard AutoHotkey .exe file by adding them as Win32 (RCDATA) resources using the Ahk2Exe compiler. To add additional scripts, see the AddResource compiler directive.

167 |

An embedded script can be specified on the command line or with #Include by writing an asterisk (*) followed by the resource name. For an integer ID, the resource name must be a hash sign (#) followed by a decimal number.

168 |

The program may automatically load script code from the following resources, if present in the file:

169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
IDSpecUsage
1*#1This is the means by which a compiled script is created from an .exe file. This script is executed automatically and most command line switches are passed to the script instead of being interpreted by the program. External scripts and alternative embedded scripts can be executed by using the /script switch.
2*#2If present, this script is automatically "included" before any script that the program loads, and before any file specified with /include.
180 |

When the source of the main script is an embedded resource, the program acts in "compiled script" mode, with the exception that A_AhkPath always contains the path of the current executable file (the same as A_ScriptFullPath). For resources other than *#1, the resource specifier is included in the main window's title to support #SingleInstance and Reload.

181 |

When referenced from code that came from an embedded resource, A_LineFile contains an asterisk (*) followed by the resource name.

182 | 183 |

Command Line Usage

184 |

See Passing Command Line Parameters to a Script for command line usage, including a list of command line switches which affect the program's behavior.

185 | 186 |

Portability of AutoHotkey.exe

187 |

The file AutoHotkey.exe is all that is needed to launch any .ahk script.

188 |

Renaming AutoHotkey.exe also changes which script it runs by default, which can be an alternative to compiling a script for use on a computer without AutoHotkey installed. For instance, MyScript.exe automatically runs MyScript.ahk if a filename is not supplied, but is also capable of running other scripts.

189 | 190 |

Launcher

191 |

The launcher enables the use of v1 and v2 scripts on one system, with a single filename extension, without necessarily giving preference to one version or requiring different methods of launching scripts. It does this by checking the script for clues about which version it requires, and then locating an appropriate exe to run the script.

192 |

If the script contains the #Requires directive, the launcher looks for an exe that satisfies the requirement. Otherwise, the launcher optionally checks syntax. That is, it checks for patterns that are valid only in one of the two major versions. Some of the common patterns it may find include:

193 | 200 |

Detection is conservative; if a case is ambiguous, it should generally be ignored.

201 |

In any case where detection fails, by default a menu is shown for the user to select a version. This default can be changed to instead launch either v1 or v2.

202 |

Known limitations:

203 | 209 |

Note: Declaring the required version with #Requires at the top of the main file eliminates any ambiguity.

210 | 211 |

Launch Settings

212 |

The launcher can be enabled, disabled or configured via the Launch Settings GUI, which can be accessed via the dash.

213 |

Run all scripts with a specific interpreter disables the launcher and allows the user to select which exe to use to run all scripts, the traditional way. Be aware that selecting a v1 exe will make it difficult to run any of the support scripts, except via the "AutoHotkey" shortcut in the Start menu.

214 |

Auto-detect version when launching script enables the launcher. Additional settings control how the launcher selects which interpreter to use.

215 | 216 |

Criteria

217 |

When multiple interpreters with the same version number are found, the launcher can rank them according to a predetermined or user-defined set of criteria. The criteria can be expressed as a comma-delimited list of substrings, where each substring may be prefixed with "!" to negate a match. A score is calculated based on which substrings matched, with the left-most substring having highest priority.

218 |

Substrings are matched in the file's description, with the exception of "UIA", which matches if the filename contains "_UIA".

219 |

For example, _H, 64, !ANSI would prefer AutoHotkey_H if available, 64-bit if compatible with the system, and finally Unicode over ANSI.

220 |

Although the Launcher Settings GUI presents drop-down lists with options such as "Unicode 32-bit", a list of substrings can be manually entered.

221 |

Additional (higher-priority) criteria can be specified on the command line with the /RunWith launcher switch.

222 |

Criteria can be specified within the script by using the #Requires directive, either as a requirement (if supported by the target AutoHotkey version), or appended to the directive as a comment beginning with "prefer" and ending with a full stop or line ending. For example:

223 |
#Requires AutoHotkey v1.1.35 ; prefer 64-bit, Unicode.  More comments.
224 | 225 |

Run *Launch

226 |

The installer registers a hidden shell verb named "launch", which executes the launcher with the /Launch switch. It can be utilized by following this example:

227 |
pid := RunWait('*Launch "' PathOfScript '"')
228 |

By contrast with the default action for .ahk files:

229 | 233 | 234 |

Command Line Usage

235 |

The launcher can be explicitly executed at the command line for cases where .ahk files are not set to use the launcher by default, or for finer control over its behaviour. If the launcher is compiled, its usage is essentially the same as AutoHotkey.exe except for the additional launcher switches. Otherwise, the format for command line use is as follows:

236 |
AutoHotkeyUX.exe launcher.ahk [Switches] [Script Filename] [Script Parameters]
237 |

Typically full paths and quote marks would be used for the path to AutoHotkeyUX.exe and launcher.ahk, which can be found in the UX subdirectory of the AutoHotkey installation. An appropriate version of AutoHotkey32.exe or AutoHotkey64.exe can be used instead of AutoHotkeyUX.exe (which is just a copy).

238 |

Switches can be a mixture of any of the standard switches and the following launcher-only switches:

239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 262 | 263 |
SwitchMeaning
/LaunchCauses the launcher to exit immediately after launching the script, instead of waiting in the background for it to terminate. The launcher's exit code is the process ID (PID) of the new script process.
/RunWith criteriaSpecifies additional criteria for determining which executable to use to launch the script. For example, /RunWith UIA.
/Which 252 |

Causes the launcher to identify which interpreter it would use and return it instead of running the script.

253 |

The launcher's exit code is the major version number (1 or 2) if identified by #Requires or syntax (if syntax detection is enabled), otherwise 0.

254 |

Stdout receives the following UTF-8 strings, each terminated with `n:

255 |
    256 |
  • The version number. If #Requires was detected, this is whatever number it specified, excluding "v". Otherwise, it is an integer the same as the exit code, unless the version wasn't detected, in which case this is 0 to indicate that the user would have been prompted, or 1 or 2 to indicate the user's preferred version as configured in the Launch Settings.
  • 257 |
  • The path of the interpreter EXE that would be used, if one was found. This is blank if the user would have been prompted or no compatible interpreters were found.
  • 258 |
  • Any additional command-line switches that the launcher would insert, such as /CP65001.
  • 259 |
260 |

Additional lines may be returned in future.

261 |
264 | 265 |

Dash

266 |

The dash provides access to support scripts and documentation. It can be opened via the "AutoHotkey" shortcut in the Start menu after installation, or by directly running UX\ui-dash.ahk from the installation directory. Currently it is little more than a menu containing the following items, but it might be expanded to provide controls for active scripts, or other convenient functions.

267 | 275 |

Note that although the Start menu shortcut launches the dash, if it is pinned to the taskbar (or to the Start menu in Windows 7 or 10), the jump list will include any recent scripts launched with the open, runas or UIAccess shell verbs (which are normally accessed via the Explorer context menu or by double-clicking a file). Scripts can be pinned for easy access.

276 | 277 |

New Script

278 |

The New Script GUI can be accessed via the dash or by right-clicking within a folder in Explorer and selecting New → AutoHotkey Script. It can be used to create a new script file from a preinstalled or user-defined template, and optionally open it for editing.

279 |

Right-clicking on a template in the list gives the following options:

280 | 285 |

By default, the GUI closes after creating a file unless the Ctrl key is held down.

286 |

Additional settings can be accessed via the settings button at the bottom-left of the GUI:

287 | 294 | 295 |

Templates

296 |

Template files are drawn from UX\Templates (preinstalled) and %A_MyDocuments%\AutoHotkey\Templates (user), with a user-defined template overriding any preinstalled template which has the same name. If a file exists at %A_WinDir%\ShellNew\Template.ahk, it is shown as "Legacy" and can be overridden by a user-defined template of that name.

297 |

Each template may contain an INI section as follows:

298 |
/*
299 | [NewScriptTemplate]
300 | Description = Descriptive text
301 | Execute = true|false|1|0
302 | */
303 |

If the INI section starts with /* and ends with */ as shown above, it is not included in the created file.

304 |

Description is optional. It is shown in the GUI, in addition to the file's name.

305 |

Execute is optional. If set to true, the template script is executed with A_Args[1] containing the path of the file to be created and A_Args[2] containing either "Create" or "Edit", depending on which button the user clicked. The template script is expected to create the file and open it for editing if applicable. If the template script needs to #include other files, they can be placed in a subdirectory to avoid having them shown in the template list.

306 | 307 |

Installation

308 |

This installer and related scripts are designed to permit multiple versions of AutoHotkey to coexist. The installer provides very few options, as most things can be configured after installation. Only the following choices must be made during installation:

309 | 313 |

By default the installer will install to "%A_ProgramFiles%\AutoHotkey" for all users. This is recommended, as the UI Access option requires the program to be installed under Program Files. If the installer is not already running as admin, it will attempt to elevate when the Install button is clicked, as indicated by the shield icon on the button.

314 |

Current user installation does not require admin rights, as long as the user has write access to the chosen directory. The default directory for a current user installation is "%LocalAppData%\Programs\AutoHotkey".

315 | 316 |

Installing with v1

317 |

There are two methods of installing v1 and v2 together:

318 |
    319 |
  1. Install v1 first, and then v2. In that case, the v1 files are left in the root of the installation directory, to avoid breaking any external tools or shortcuts that rely on their current path.
  2. 320 |
  3. Install v1 as an additional version. Running a v1.1.34.03 or later installer gives this option. Alternatively, use the /install switch described below. Each version installs into its own subdirectory.
  4. 321 |
322 |

Running a v1.1.34.02 or older installer (or a custom install with v1.1.34.03 or newer) will overwrite some of the values set in the registry by the v2 installer, such as the version number, uninstaller entry and parts of the file type registration. It will also register the v1 uninstaller, which is not capable of correctly uninstalling both versions. To re-register v2, re-run any v2 installer or run UX\install.ahk using AutoHotkey32.exe or AutoHotkey64.exe.

323 | 324 |

Default Version

325 |

Unlike a v1 installation, a default version is not selected during installation. Defaults are instead handled more dynamically by the launcher, and can be configured per-user.

326 | 327 |

Command Line Usage

328 |

To directly install to the DESTINATION directory, use /installto or /to (the two switches are interchangeable) as shown below, from within the source directory. Use either a downloaded setup.exe or files extracted from a downloaded zip or other source.

329 |
AutoHotkey_setup.exe /installto "%DESTINATION%"
330 |
AutoHotkey32.exe UX\install.ahk /to "%DESTINATION%"
331 |

To install an additional version from SOURCE (which should be a directory containing AutoHotkey*.exe files), execute the following from within the current installation directory (adjusting the path of AutoHotkey32.exe as needed):

332 |
AutoHotkey32.exe UX\install.ahk /install "%SOURCE%"
333 |

The full command string for the above is registered as InstallCommand under HKLM\Software\AutoHotkey or HKCU\Software\AutoHotkey, with %1 as the substitute for the source directory. Using this registry value may be more future-proof.

334 |

To re-register the current installation:

335 |
AutoHotkey32.exe UX\install.ahk
336 |

To uninstall:

337 |
AutoHotkey32.exe UX\install.ahk /uninstall
338 |

Alternatively, read the QuietUninstallString value from one of the following registry keys, and execute it:

339 |
HKLM\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey
340 | HKCU\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey
341 |

Use the /silent switch to suppress warning or confirmation dialogs and prevent the Dash from being shown when installation is complete. The following actions may be taken automatically, without warning:

342 | 346 | 347 |

Taskbar Buttons

348 |

The v2 installer does not provide an option to separate taskbar buttons. This was previously achieved by registering each AutoHotkey executable as a host app (IsHostApp), but this approach has limitations, and becomes less manageable when multiple versions can be installed. Instead, each script should set the AppUserModelID of its process or windows to control grouping.

349 | 350 |

Run with UI Access

351 |

When installing under Program Files, the installer creates an additional set of AutoHotkey exe files that can be used to work around some common UAC-related issues. These files are given the "_UIA.exe" suffix. When one of these UIA.exe files is used by an administrator to run a script, the script is able to interact with windows of programs that run as admin, without the script itself running as admin.

352 |

The installer does the following:

353 | 359 |

The launcher can also be configured to run v1 scripts, v2 scripts or both with UI Access by default, but this option has no effect if a UIA.exe file does not exist for the selected version and build.

360 |

Scripts which need to run other scripts with UI access can simply Run the appropriate UIA.exe file with the normal command line parameters. Alternatively, if the UIAccess shell verb is registered, it can be used via Run. For example: Run '*UIAccess "Script.ahk"'

361 |

Known limitations:

362 | 372 |

For more details, see Enable interaction with administrative programs on the archived forum.

373 | 374 | 375 | 376 | -------------------------------------------------------------------------------- /docs/Scripts.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Scripts - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Scripts

14 |

Related topics:

15 | 20 | 21 |

Table of Contents

22 | 32 |

Introduction

33 |

Each script is a plain text file containing lines to be executed by the program (AutoHotkey.exe). A script may also contain hotkeys and hotstrings, or even consist entirely of them. However, in the absence of hotkeys and hotstrings, a script will perform its functions sequentially from top to bottom the moment it is launched.

34 |

The program loads the script into memory line by line. During loading, the script is optimized and validated. Any syntax errors will be displayed, and they must be corrected before the script can run.

35 | 36 |

Script Startup (the Auto-execute Thread)

37 |

After the script has been loaded, the auto-execute thread begins executing at the script's top line, and continues until instructed to stop, such as by Return, ExitApp or Exit. The physical end of the script also acts as Exit.

38 |

The script will terminate after completing startup if it lacks hotkeys, hotstrings, visible GUIs, active timers, clipboard monitors and InputHooks, and has not called the Persistent function. Otherwise, it will stay running in an idle state, responding to events such as hotkeys, hotstrings, GUI events, custom menu items, and timers. If these conditions change after startup completes (for example, the last timer is disabled), the script may exit when the last running thread completes or the last GUI closes.

39 |

Whenever any new thread is launched (whether by a hotkey, hotstring, timer, or some other event), the following settings are copied from the auto-execute thread. If not set by the auto-execute thread, the standard defaults will apply (as documented on each of the following pages): CoordMode, Critical, DetectHiddenText, DetectHiddenWindows, FileEncoding, ListLines, SendLevel, SendMode, SetControlDelay, SetDefaultMouseSpeed, SetKeyDelay, SetMouseDelay, SetRegView, SetStoreCapsLockMode, SetTitleMatchMode, SetWinDelay, and Thread.

40 |

Each thread retains its own collection of the above settings, so changes made to those settings will not affect other threads.

41 |

The "default setting" for one of the above functions usually refers to the current setting of the auto-execute thread, which starts out the same as the program-defined default setting.

42 |

Traditionally, the top of the script has been referred to as the auto-execute section. However, the auto-execute thread is not limited to just the top of the script. Any functions which are called on the auto-execute thread may also affect the default settings. As directives and function, hotkey, hotstring and class definitions are skipped when encountered during execution, it is possible for startup code to be placed throughout each file. For example, a global variable used by a group of hotkeys may be initialized above (or even below) those hotkeys rather than at the top of the script.

43 | 44 |

Splitting a Long Line into a Series of Shorter Ones

45 |

Long lines can be divided up into a collection of smaller ones to improve readability and maintainability. This does not reduce the script's execution speed because such lines are merged in memory the moment the script launches.

46 |

There are three methods, and they can generally be used in combination:

47 | 52 |

Continuation operator: A line that starts with a comma or any other expression operator (except ++ and --) is automatically merged with the line directly above it. Similarly, a line that ends with an expression operator is automatically merged with the line below it. In the following example, the second line is appended to the first because it begins with a comma:

53 |
FileAppend "This is the text to append.`n"   ; A comment is allowed here.
 54 |     , A_ProgramFiles "\SomeApplication\LogFile.txt"  ; Comment.
55 |

Similarly, the following lines would get merged into a single line because the last two start with "and" or "or":

56 |
if Color = "Red" or Color = "Green"  or Color = "Blue"   ; Comment.
 57 |     or Color = "Black" or Color = "Gray" or Color = "White"   ; Comment.
 58 |     and ProductIsAvailableInColor(Product, Color)   ; Comment.
59 |

The ternary operator is also a good candidate:

60 |
ProductIsAvailable := (Color = "Red")
 61 |     ? false  ; We don't have any red products, so don't bother calling the function.
 62 |     : ProductIsAvailableInColor(Product, Color)
63 |

The following examples are equivalent to those above:

64 |
FileAppend "This is the text to append.`n",   ; A comment is allowed here.
 65 |     A_ProgramFiles "\SomeApplication\LogFile.txt"  ; Comment.
 66 | 
 67 | if Color = "Red" or Color = "Green"  or Color = "Blue" or   ; Comment.
 68 |     Color = "Black" or Color = "Gray" or Color = "White" and   ; Comment.
 69 |     ProductIsAvailableInColor(Product, Color)   ; Comment.
 70 | 
 71 | ProductIsAvailable := (Color = "Red") ?
 72 |     false : ; We don't have any red products, so don't bother calling the function.
 73 |     ProductIsAvailableInColor(Product, Color)
74 |

Although the indentation used in the examples above is optional, it might improve clarity by indicating which lines belong to ones above them. Also, blank lines or comments may be added between or at the end of any of the lines in the above examples.

75 |

A continuation operator cannot be used with an auto-replace hotstring or directive other than #HotIf.

76 |

Continuation by enclosure: If a line contains an expression or function/property definition with an unclosed (/[/{, it is joined with subsequent lines until the number of opening and closing symbols balances out. In other words, a sub-expression enclosed in parentheses, brackets or braces can automatically span multiple lines in most cases. For example:

77 |
 78 | myarray := [
 79 |   "item 1",
 80 |   "item 2",
 81 | ]
 82 | MsgBox(
 83 |     "The value of item 2 is " myarray[2],
 84 |     "Title",
 85 |     "ok iconi"
 86 |     )
 87 | 
88 |

Continuation expressions may contain both types of comments.

89 |

Continuation expressions may contain normal continuation sections. Therefore, as with any line containing an expression, if a line begins with a non-escaped open parenthesis ((), it is considered to be the start of a continuation section unless there is a closing parenthesis ()) on the same line.

90 |

Quoted strings cannot span multiple lines using this method alone. However, see above.

91 |

Continuation by enclosure can be combined with a continuation operator. For example:

92 |
myarray :=  ; The assignment operator causes continuation.
 93 | [  ; Brackets enclose the following two lines.
 94 |   "item 1",
 95 |   "item 2",
 96 | ]
97 |

Brace ({) at the end of a line does not cause continuation if the program determines that it should be interpreted as the beginning of a block (OTB style) rather than the start of an object literal. Specifically (in descending order of precedence):

98 | 103 |

A brace can be safely used for line continuation with any function call, expression or control flow statement which does not require a body. For example:

104 |
myfn() {
105 |     return {
106 |         key: "value"
107 |     }
108 | }
109 |

Continuation section: This method should be used to merge a large number of lines or when the lines are not suitable for the other methods. Although this method is especially useful for auto-replace hotstrings, it can also be used with any expression. For example:

110 |
; EXAMPLE #1:
111 | Var := "
112 | (
113 | A line of text.
114 | By default, the hard carriage return (Enter) between the previous line and this one will be stored.
115 | 	This line is indented with a tab; by default, that tab will also be stored.
116 | Additionally, "quote marks" are automatically escaped when appropriate.
117 | )"
118 | 
119 | ; EXAMPLE #2:
120 | FileAppend "
121 | (
122 | Line 1 of the text.
123 | Line 2 of the text. By default, a linefeed (`n) is present between lines.
124 | )", A_Desktop "\My File.txt"
125 |

In the examples above, a series of lines is bounded at the top and bottom by a pair of parentheses. This is known as a continuation section. Notice that any code after the closing parenthesis is also joined with the other lines (without any delimiter), but the opening and closing parentheses are not included.

126 |

If the line above the continuation section ends with a name character and the section does not start inside a quoted string, a single space is automatically inserted to separate the name from the contents of the continuation section.

127 |

Quote marks are automatically escaped (i.e. they are interpreted as literal characters) if the continuation section starts inside a quoted string, as in the examples above. Otherwise, quote marks act as they do normally; that is, continuation sections can contain expressions with quoted strings.

128 |

By default, leading spaces or tabs are omitted based on the indentation of the first line inside the continuation section. If the first line mixes spaces and tabs, only the first type of character is treated as indentation. If any line is indented less than the first line or with the wrong characters, all leading whitespace on that line is left as is.

129 |

By default, trailing spaces or tabs are omitted.

130 |

The default behavior of a continuation section can be overridden by including one or more of the following options to the right of the section's opening parenthesis. If more than one option is present, separate each one from the previous with a space. For example: ( LTrim Join|.

131 |

JoinString: Specifies how lines should be connected together. If this option is not used, each line except the last will be followed by a linefeed character (`n). If String is omitted, lines are connected directly to each other without any characters in between. Otherwise, specify for String a string of up to 15 characters. For example, Join`s would insert a space after each line except the last. Another example is Join`r`n, which inserts CR+LF between lines. Similarly, Join| inserts a pipe between lines. To have the final line in the section also ended by String, include a blank line immediately above the section's closing parenthesis.

132 |

LTrim: Omits all spaces and tabs at the beginning of each line. This is usually unnecessary because of the default "smart" behaviour.

133 |

LTrim0 (LTrim followed by a zero): Turns off the omission of spaces and tabs from the beginning of each line.

134 |

RTrim0 (RTrim followed by a zero): Turns off the omission of spaces and tabs from the end of each line.

135 |

Comments (or Comment or Com or C): Allows semicolon comments inside the continuation section (but not /*..*/). Such comments (along with any spaces and tabs to their left) are entirely omitted from the joined result rather than being treated as literal text. Each comment can appear to the right of a line or on a new line by itself.

136 |

` (accent): Treats each backtick character literally rather than as an escape character. This also prevents the translation of any explicitly specified escape sequences such as `r and `t.

137 |

( or ): If an opening or closing parenthesis appears to the right of the initial opening parenthesis (except as a parameter of the Join option), the line is reinterpreted as an expression instead of the beginning of a continuation section. This enables expressions like (x.y)[z]() to be used at the start of a line, and also allows multi-line expressions to start with a line like (( or (MyFunc(.

138 | 139 |

Remarks

140 |

Escape sequences such as `n (linefeed) and `t (tab) are supported inside the continuation section except when the accent (`) option has been specified.

141 |

When the comment option is absent, semicolon and /*..*/ comments are not supported within the interior of a continuation section because they are seen as literal text. However, comments can be included on the bottom and top lines of the section. For example:

142 |
FileAppend "   ; Comment.
143 | ; Comment.
144 | ( LTrim Join    ; Comment.
145 |      ; This is not a comment; it is literal. Include the word Comments in the line above to make it a comment.
146 | )", "C:\File.txt"   ; Comment.
147 |

As a consequence of the above, semicolons never need to be escaped within a continuation section.

148 |

Since a closing parenthesis indicates the end of a continuation section, to have a line start with literal closing parenthesis, precede it with an accent/backtick: `). However, this cannot be combined with the accent (`) option.

149 |

A continuation section can be immediately followed by a line containing the open-parenthesis of another continuation section. This allows the options mentioned above to be varied during the course of building a single line.

150 |

The piecemeal construction of a continuation section by means of #Include is not supported.

151 | 152 |

Script Library Folders

153 |

The library folders provide a few standard locations to keep shared scripts which other scripts utilise by means of #Include. A library script typically contains a function or class which is designed to be used and reused in this manner. Placing library scripts in one of these locations makes it easier to write scripts that can be shared with others and work across multiple setups. The library locations are:

154 |
A_ScriptDir "\Lib\"  ; Local library.
155 | A_MyDocuments "\AutoHotkey\Lib\"  ; User library.
156 | "directory-of-the-currently-running-AutoHotkey.exe\Lib\"  ; Standard library.
157 |

The library folders are searched in the order shown above.

158 |

For example, if a script includes the line #Include <MyLib>, the program searches for a file named "MyLib.ahk" in the local library. If not found there, it searches for it in the user library, and then the standard library. If a match is still not found and the library's name contains an underscore (e.g. MyPrefix_MyFunc), the program searches again with just the prefix (e.g. MyPrefix.ahk).

159 |

Although by convention a library file generally contains only a single function or class of the same name as its filename, it may also contain private functions that are called only by it. However, such functions should have fairly distinct names because they will still be in the global namespace; that is, they will be callable from anywhere in the script.

160 | 161 |

Convert a Script to an EXE (Ahk2Exe)

162 |

A script compiler (courtesy of fincs, with additions by TAC109) is available as a separate automatic download.

163 |

Once a script is compiled, it becomes a standalone executable; that is, AutoHotkey.exe is not required in order to run the script. The compilation process creates an executable file which contains the following: the AutoHotkey interpreter, the script, any files it includes, and any files it has incorporated via the FileInstall function. Additional files can be included using compiler directives.

164 |

The same compiler is used for v1.1 and v2 scripts. The compiler distinguishes script versions by checking the major version of the base file supplied.

165 |

Compiler Topics

166 | 173 |

Running the Compiler

174 |

Ahk2Exe can be used in the following ways:

175 | 247 |

Notes:

248 | 256 |

The compiler's source code and newer versions can be found at GitHub.

257 | 258 |

Base Executable File

259 |

Each compiled script .exe is based on an executable file which implements the interpreter. The base files included in the Compiler directory have the ".bin" extension; these are versions of the interpreter which do not include the capability to load external script files. Instead, the program looks for a Win32 (RCDATA) resource named ">AUTOHOTKEY SCRIPT<" and loads that, or fails if it is not found.

260 |

The standard AutoHotkey executable files can also be used as the base of a compiled script, by embedding a Win32 (RCDATA) resource with ID 1. (Additional scripts can be added with the AddResource compiler directive.) This allows the compiled script .exe to be used with the /script switch to execute scripts other than the main embedded script. For more details, see Embedded Scripts.

261 | 262 |

Script Compiler Directives

263 |

Script compiler directives allow the user to specify details of how a script is to be compiled. Some of the features are:

264 | 270 |

See Script Compiler Directives for more details.

271 | 272 |

Compressing Compiled Scripts

273 |

Ahk2Exe optionally uses MPRESS or UPX freeware to compress compiled scripts. If MPRESS.exe and/or UPX.exe has been copied to the "Compiler" subfolder where AutoHotkey was installed, either can be used to compress the .exe as directed by the /compress parameter or the GUI setting.

274 |

MPRESS: archived official website (downloads and information) | direct download (95 KB)

275 |

UPX: official website (downloads and information)

276 |

Note: While compressing the script executable prevents casual inspection of the script's source code using a plain text editor like Notepad or a PE resource editor, it does not prevent the source code from being extracted by tools dedicated to that purpose.

277 | 278 |

Background Information

279 |

The following folder structure is supported, where the running version of Ahk2Exe.exe is in the first \Compiler directory shown below:

280 |
\AutoHotkey 
281 |    AutoHotkeyA32.exe 
282 |    AutoHotkeyU32.exe
283 |    AutoHotkeyU64.exe
284 |    \Compiler
285 |       Ahk2Exe.exe  ; the master version of Ahk2Exe
286 |       ANSI 32-bit.bin
287 |       Unicode 32-bit.bin
288 |       Unicode 64-bit.bin
289 |    \AutoHotkey v2.0-a135
290 |       AutoHotkey32.exe
291 |       AutoHotkey64.exe
292 |       \Compiler
293 |    \v2.0-beta.1
294 |       AutoHotkey32.exe
295 |       AutoHotkey64.exe
296 |

The base file search algorithm runs for a short amount of time when Ahk2Exe starts, and works as follows:

297 |

Qualifying AutoHotkey .exe files and all .bin files are searched for in the compiler's directory, the compiler's parent directory, and any of the compiler's sibling directories with directory names that start with AutoHotkey or V, but do not start with AutoHotkey_H. The selected directories are searched recursively. Any AutoHotkey.exe files found are excluded, leaving files such as AutoHotkeyA32.exe, AutoHotkey64.exe, etc. plus all .bin files found. All .exe files that are included must have a name starting with AutoHotkey and a file description containing the word AutoHotkey, and must have a version of 1.1.34+ or 2.0-a135+.

298 |

A version of the AutoHotkey interpreter is also needed (as a utility) for a successful compile, and one is selected using a similar algorithm. In most cases the version of the interpreter used will match the version of the base file selected by the user for the compile.

299 | 300 | 301 |

Passing Command Line Parameters to a Script

302 |

Scripts support command line parameters. The format is:

303 |
AutoHotkey.exe [Switches] [Script Filename] [Script Parameters]
304 |

And for compiled scripts, the format is:

305 |
CompiledScript.exe [Switches] [Script Parameters]
306 |

Switches: Zero or more of the following:

307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 337 | 338 | 339 | 340 | 341 | 346 | 347 | 348 | 349 | 350 | 354 | 355 | 356 | 357 | 358 | 361 | 362 | 363 | 364 | 365 | 372 | 373 | 374 |
SwitchMeaningWorks compiled?
/forceLaunch unconditionally, skipping any warning dialogs. This has the same effect as #SingleInstance Off.Yes
/restartIndicate that the script is being restarted and should attempt to close a previous instance of the script (this is also used by the Reload function, internally).Yes
/ErrorStdOut

/ErrorStdOut=Encoding
322 |

Send syntax errors that prevent a script from launching to the standard error stream (stderr) rather than displaying a dialog. See #ErrorStdOut for details.

323 |

An encoding can optionally be specified. For example, /ErrorStdOut=UTF-8 encodes messages as UTF-8 before writing them to stderr.

324 |
No
/DebugConnect to a debugging client. For more details, see Interactive Debugging.No
/CPn 335 |

Overrides the default codepage used to read script files. For more details, see Script File Codepage.

336 |
No
/Validate 342 |

AutoHotkey loads the script and then exits instead of running it.

343 |

By default, load-time errors and warnings are displayed as usual. The /ErrorStdOut switch can be used to suppress or capture any error messages.

344 |

The process exit code is zero if the script successfully loaded, or non-zero if there was an error.

345 |
No
/iLib "OutFile" 351 |

Deprecated: Equivalent to /validate; use that instead.

352 |

"OutFile" must be specified but is ignored. In previous versions of AutoHotkey, filenames of auto-included files were written to the file specified by OutFile, formatted as #Include directives.

353 |
No
/include "IncFile" 359 |

Includes a file prior to the main script. Only a single file can be included by this method. When the script is reloaded, this switch is automatically passed to the new instance.

360 |
No
/script 366 |

When used with a compiled script based on an .exe file, this switch causes the program to ignore the main embedded script. This allows a compiled script .exe to execute external script files or embedded scripts other than the main one. Other switches not normally supported by compiled scripts can be used but must be listed to the right of this switch. For example:

367 |
CompiledScript.exe /script /ErrorStdOut MyScript.ahk "Script's arg 1"
368 |

If the current executable file does not have an embedded script, this switch is permitted but has no effect.

369 |

This switch is not supported by compiled scripts which are based on a .bin file.

370 |

See also: Base Executable File (Ahk2Exe)

371 |
N/A
375 | 376 |

Script Filename: This can be omitted if there are no Script Parameters. If omitted, it defaults to the path and name of the AutoHotkey executable, replacing ".exe" with ".ahk". For example, if you rename AutoHotkey.exe to MyScript.exe, it will attempt to load MyScript.ahk. If you run AutoHotkey32.exe without parameters, it will attempt to load AutoHotkey32.ahk.

377 |

Specify an asterisk (*) for the filename to read the script text from standard input (stdin). This also puts the following into effect:

378 | 383 |

For an example, see ExecScript().

384 |

If the current executable file has embedded scripts, this parameter can be an asterisk followed by the resource name or ID of an embedded script. For compiled scripts (i.e. if an embedded script with the ID #1 exists), this parameter must be preceded by the /script switch.

385 |

Script Parameters: The string(s) you want to pass into the script, with each separated from the next by one or more spaces. Any parameter that contains spaces should be enclosed in quotation marks. If you want to pass an empty string as a parameter, specify two consecutive quotation marks. A literal quotation mark may be passed in by preceding it with a backslash (\"). Consequently, any trailing slash in a quoted parameter (such as "C:\My Documents\") is treated as a literal quotation mark (that is, the script would receive the string C:\My Documents"). To remove such quotes, use A_Args[1] := StrReplace(A_Args[1], '"')

386 |

Incoming parameters, if present, are stored as an array in the built-in variable A_Args, and can be accessed using array syntax. A_Args[1] contains the first parameter. The following example exits the script when too few parameters are passed to it:

387 |
if A_Args.Length < 3
388 | {
389 |     MsgBox "This script requires at least 3 parameters but it only received " A_Args.Length "."
390 |     ExitApp
391 | }
392 |

If the number of parameters passed into a script varies (perhaps due to the user dragging and dropping a set of files onto a script), the following example can be used to extract them one by one:

393 |
for n, param in A_Args  ; For each parameter:
394 | {
395 |     MsgBox "Parameter number " n " is " param "."
396 | }
397 | 
398 |

If the parameters are file names, the following example can be used to convert them to their case-corrected long names (as stored in the file system), including complete/absolute path:

399 |
for n, GivenPath in A_Args  ; For each parameter (or file dropped onto a script):
400 | {
401 |     Loop Files, GivenPath, "FD"  ; Include files and directories.
402 |         LongPath := A_LoopFileFullPath
403 |     MsgBox "The case-corrected long path name of file`n" GivenPath "`nis:`n" LongPath
404 | }
405 | 406 |

Script File Codepage

407 |

In order for non-ASCII characters to be read correctly from file, the encoding used when the file was saved (typically by the text editor) must match what AutoHotkey uses when it reads the file. If it does not match, characters will be decoded incorrectly. AutoHotkey uses the following rules to decide which encoding to use:

408 | 413 |

Note that this applies only to script files loaded by AutoHotkey, not to file I/O within the script itself. FileEncoding controls the default encoding of files read or written by the script, while IniRead and IniWrite always deal in UTF-16 or ANSI.

414 |

As all text is converted (where necessary) to the native string format, characters which are invalid or don't exist in the native codepage are replaced with a placeholder: '�'. This should only occur if there are encoding errors in the script file or the codepages used to save and load the file don't match.

415 |

RegWrite may be used to set the default for scripts launched from Explorer (e.g. by double-clicking a file):

416 |
; Uncomment the appropriate line below or leave them all commented to
417 | ;   reset to the default of the current build.  Modify as necessary:
418 | ; codepage := 0        ; System default ANSI codepage
419 | ; codepage := 65001    ; UTF-8
420 | ; codepage := 1200     ; UTF-16
421 | ; codepage := 1252     ; ANSI Latin 1; Western European (Windows)
422 | if (codepage != "")
423 |     codepage := " /CP" . codepage
424 | cmd := Format('"{1}"{2} "%1" %*', A_AhkPath, codepage)
425 | key := "AutoHotkeyScript\Shell\Open\Command"
426 | if A_IsAdmin    ; Set for all users.
427 |     RegWrite cmd, "REG_SZ", "HKCR\" key
428 | else            ; Set for current user only.
429 |     RegWrite cmd, "REG_SZ", "HKCU\Software\Classes\" key
430 |

This assumes AutoHotkey has already been installed. Results may be less than ideal if it has not.

431 | 432 |

Debugging a Script

433 |

Built-in functions such as ListVars and Pause can help you debug a script. For example, the following two lines, when temporarily inserted at carefully chosen positions, create "break points" in the script:

434 |
ListVars
435 | Pause
436 |

When the script encounters these two lines, it will display the current contents of all variables for your inspection. When you're ready to resume, un-pause the script via the File or Tray menu. The script will then continue until reaching the next "break point" (if any).

437 |

It is generally best to insert these "break points" at positions where the active window does not matter to the script, such as immediately before a WinActivate function. This allows the script to properly resume operation when you un-pause it.

438 |

The following functions are also useful for debugging: ListLines, KeyHistory, and OutputDebug.

439 |

Some common errors, such as typos and missing "global" declarations, can be detected by enabling warnings.

440 |

Interactive Debugging

441 |

Interactive debugging is possible with a supported DBGp client. Typically the following actions are possible:

442 | 448 |

Note that this functionality is disabled for compiled scripts which are based on a BIN file. For compiled scripts based on an EXE file, /debug must be specified after /script.

449 |

To enable interactive debugging, first launch a supported debugger client then launch the script with the /Debug command-line switch.

450 |
AutoHotkey.exe /Debug[=SERVER:PORT] ...
451 |

SERVER and PORT may be omitted. For example, the following are equivalent:

452 |
AutoHotkey /Debug "myscript.ahk"
453 | AutoHotkey /Debug=localhost:9000 "myscript.ahk"
454 |

To attach the debugger to a script which is already running, send it a message as shown below:

455 |
ScriptPath := "" ; SET THIS TO THE FULL PATH OF THE SCRIPT
456 | A_DetectHiddenWindows := true
457 | if WinExist(ScriptPath " ahk_class AutoHotkey")
458 |     ; Optional parameters:
459 |     ;   wParam  = the IPv4 address of the debugger client, as a 32-bit integer.
460 |     ;   lParam  = the port which the debugger client is listening on.
461 |     PostMessage DllCall("RegisterWindowMessage", "Str", "AHK_ATTACH_DEBUGGER")
462 | 
463 |

Once the debugger client is connected, it may detach without terminating the script by sending the "detach" DBGp command.

464 | 465 |

Script Showcase

466 |

See this page for some useful scripts.

467 | 468 | 469 | -------------------------------------------------------------------------------- /docs/Tutorial.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Beginner Tutorial | AutoHotkey v2 10 | 11 | 12 | 13 | 14 |

AutoHotkey Beginner Tutorial by tidbit

15 |

Table of Contents

16 |
    17 |
  1. The Basics 18 |
      19 |
    1. Downloading and installing AutoHotkey
    2. 20 |
    3. How to create a script
    4. 21 |
    5. How to find the help file on your computer
    6. 22 |
    23 |
  2. 24 |
  3. Hotkeys & Hotstrings 25 |
      26 |
    1. Keys and their mysterious symbols
    2. 27 |
    3. Window specific hotkeys/hotstrings
    4. 28 |
    5. Multiple hotkeys/hotstrings per file
    6. 29 |
    7. Examples
    8. 30 |
    31 |
  4. 32 |
  5. Sending Keystrokes 33 |
      34 |
    1. Games
    2. 35 |
    36 |
  6. 37 |
  7. Running Programs & Websites
  8. 38 |
  9. Function Calls with or without Parentheses 39 |
      40 |
    1. Code blocks
    2. 41 |
    42 |
  10. 43 |
  11. Variables 44 |
      45 |
    1. Getting user input
    2. 46 |
    3. Other Examples?
    4. 47 |
    48 |
  12. 49 |
  13. Objects 50 |
      51 |
    1. Creating Objects
    2. 52 |
    3. Using Objects
    4. 53 |
    54 |
  14. 55 |
  15. Other Helpful Goodies 56 |
      57 |
    1. The mysterious square brackets
    2. 58 |
    3. Finding your AHK version
    4. 59 |
    5. Trial and Error
    6. 60 |
    7. Indentation
    8. 61 |
    9. Asking for Help
    10. 62 |
    11. Other links
    12. 63 |
    64 |
  16. 65 |
66 | 67 |

1 - The Basics

68 |

Before we begin our journey, let me give some advice. Throughout this tutorial you will see a lot of text and a lot of code. For optimal learning power, it is advised that you read the text and try the code. Then, study the code. You can copy and paste most examples on this page. If you get confused, try reading the section again.

69 | 70 |

a. Downloading and installing AutoHotkey

71 | 72 | 76 |

Before learning to use AutoHotkey (AHK), you will need to download it. After downloading it, you may possibly need to install it. But that depends on the version you want. For this guide we will use the Installer since it is easiest to set up.

77 | 78 |

Text instructions:

79 |
    80 |
  1. Go to the AutoHotkey Homepage: https://www.autohotkey.com/
  2. 81 |
  3. Click Download. You should be presented with an option for each major version of AutoHotkey. This documentation is for v2, so choose that option or switch to the v1 documentation.
  4. 82 |
  5. The downloaded file should be named AutoHotkey_*_setup.exe or similar. Run this and click Install.
  6. 83 |
  7. Once done, great! Continue on to section b.
  8. 84 |
85 | 86 |

b. How to create a script

87 |

Once you have AutoHotkey installed, you will probably want it to do stuff. AutoHotkey is not magic, we all wish it was, but it is not. So we will need to tell it what to do. This process is called "Scripting".

88 | 89 |

Text instructions:

90 |
    91 |
  1. Right-Click on your desktop.
  2. 92 |
  3. Find "New" in the menu.
  4. 93 |
  5. Click "AutoHotkey Script" inside the "New" menu.
  6. 94 |
  7. Give the script a new name. It must end with a .ahk extension. For example: MyScript.ahk
  8. 95 |
  9. Find the newly created file on your desktop and right-click it.
  10. 96 |
  11. Click "Edit Script".
  12. 97 |
  13. A window should have popped up, probably Notepad. If so, SUCCESS! 98 |

    So now that you have created a script, we need to add stuff into the file. For a list of all built-in function and variables, see section 5.

    99 |

    Here is a very basic script containing a hotkey which types text using the Send function when the hotkey is pressed:

    100 |
    101 | ^j::
    102 | {
    103 |     Send "My First Script"
    104 | }
    105 |

    We will get more in-depth later on. Until then, here's an explanation of the above code:

    106 | 111 |
  14. 112 |
  15. Save the File.
  16. 113 |
  17. Double-click the file/icon in the desktop to run it. Open notepad or (anything you can type in) and press Ctrl and J.
  18. 114 |
  19. Hip Hip Hooray! Your first script is done. Go get some reward snacks then return to reading the rest of this tutorial.
  20. 115 |

For a video instruction, watch Install and Hello World on YouTube.

116 | 117 |

c. How to find the help file on your computer

118 |

Downloads for v2.0-a076 and later include an offline help file in the same zip as the main program. If you manually extracted the files, the help file should be wherever you put it.

119 |

v2.0-beta.4 and later include an installation script. If you have used this to install AutoHotkey, the help file for each version should be in a subdirectory of the location where AutoHotkey was installed, such as "C:\Program Files\AutoHotkey\v2.0-beta.7". There may also be a symbolic link named "v2" pointing to the subdirectory of the last installed version. If v1.x is installed, a help file for that version may also be present in the root directory.

120 |

Look for AutoHotkey.chm or a file that says AutoHotkey and has a yellow question mark on it.

121 |

If you don't need to find the file itself, there are also a number of ways to launch it:

122 | 127 | 128 |

2 - Hotkeys & Hotstrings

129 | 130 |

What is a hotkey? A hotkey is a key that is hot to the touch. ... Just kidding. It is a key or key combination that the person at the keyboard presses to trigger some actions. For example:

131 |
^j::
132 | {
133 |     Send "My First Script"
134 | }
135 |

What is a hotstring? Hotstrings are mainly used to expand abbreviations as you type them (auto-replace), they can also be used to launch any scripted action. For example:

136 |
::ftw::Free the whales
137 |

The difference between the two examples is that the hotkey will be triggered when you press Ctrl+J while the hotstring will convert your typed "ftw" into "Free the whales".

138 |

"So, how exactly does a person such as myself create a hotkey?" Good question. A hotkey is created by using a single pair of colons. The key or key combo needs to go on the left of the ::. And the content needs to go below, enclosed in curly brackets.

139 |

Note: There are exceptions, but those tend to cause confusion a lot of the time. So it won't be covered in the tutorial, at least, not right now.

140 |
Esc::
141 | {
142 |     MsgBox "Escape!!!!"
143 | }
144 |

A hotstring has a pair of colons on each side of the text you want to trigger the text replacement. While the text to replace your typed text goes on the right of the second pair of colons.

145 |

Hotstrings, as mentioned above, can also launch scripted actions. That's fancy talk for "do pretty much anything". Same with hotkeys.

146 |
::btw::
147 | {
148 |     MsgBox "You typed btw."
149 | }
150 |

A nice thing to know is that you can have many lines of code for each hotkey, hotstring, label, and a lot of other things we haven't talked about yet.

151 |
^j::
152 | {
153 |     MsgBox "Wow!"
154 |     MsgBox "There are"
155 |     Run "notepad.exe"
156 |     WinActivate "Untitled - Notepad"
157 |     WinWaitActive "Untitled - Notepad"
158 |     Send "7 lines{!}{Enter}"
159 |     SendInput "inside the CTRL{+}J hotkey."
160 | }
161 | 162 |

a. Keys and their mysterious symbols

163 |

You might be wondering "How the crud am I supposed to know that ^ means Ctrl?!". Well, good question. To help you learn what ^ and other symbols mean, gaze upon this chart:

164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 |
SymbolDescription
#Win (Windows logo key)
!Alt
^Ctrl
+Shift
&An ampersand may be used between any two keys or mouse buttons to combine them into a custom hotkey.
190 |

(For the full list of symbols, see the Hotkey page)

191 |

Additionally, for a list of all/most hotkey names that can be used on the left side of a hotkey's double-colon, see List of Keys, Mouse Buttons, and Controller Controls.

192 |

You can define a custom combination of two (and only two) keys (except controller buttons) by using & between them. In the example below, you would hold down Numpad0 then press Numpad1 or Numpad2 to trigger one of the hotkeys:

193 | 194 |
Numpad0 & Numpad1::
195 | {
196 |     MsgBox "You pressed Numpad1 while holding down Numpad0."
197 | }
198 | 
199 | Numpad0 & Numpad2::
200 | {
201 |     Run "notepad.exe"
202 | }
203 | 204 |

But you are now wondering if hotstrings have any cool modifiers since hotkeys do. Yes, they do! Hotstring modifiers go between the first set of colons. For example:

205 |
:*:ftw::Free the whales
206 | 207 |

Visit Hotkeys and Hotstrings for additional hotkey and hotstring modifiers, information and examples.

208 |

b. Window specific hotkeys/hotstrings

209 | 210 |

Sometime you might want a hotkey or hotstring to only work (or be disabled) in a certain window. To do this, you will need to use one of the fancy commands with a # in-front of them, namely #HotIf, combined with the built-in function WinActive or WinExist:

211 |
#HotIf WinActive(WinTitle)
212 | #HotIf WinExist(WinTitle)
213 |

This special command (technically called "directive") creates context-sensitive hotkeys and hotstrings. Simply specify a window title for WinTitle. But in some cases you might want to specify criteria such as HWND, group or class. Those are a bit advanced and are covered more in-depth here: The WinTitle Parameter & the Last Found Window.

214 |
#HotIf WinActive("Untitled - Notepad")
215 | #Space::
216 | {
217 |     MsgBox "You pressed WIN+SPACE in Notepad."
218 | }
219 |

To turn off context sensitivity for subsequent hotkeys or hotstrings, specify #HotIf without its parameter. For example:

; Untitled - Notepad
220 | #HotIf WinActive("Untitled - Notepad")
221 | !q::
222 | {
223 |     MsgBox "You pressed ALT+Q in Notepad."
224 | }
225 | 
226 | ; Any window that isn't Untitled - Notepad
227 | #HotIf
228 | !q::
229 | {
230 |     MsgBox "You pressed ALT+Q in any window."
231 | }
232 | 
233 |

When #HotIf directives are never used in a script, all hotkeys and hotstrings are enabled for all windows.

234 |

The #HotIf directive is positional: it affects all hotkeys and hotstrings physically beneath it in the script, until the next #HotIf directive.

235 |
; Notepad
236 | #HotIf WinActive("ahk_class Notepad")
237 | #Space::
238 | {
239 |     MsgBox "You pressed WIN+SPACE in Notepad."
240 | }
241 | ::msg::You typed msg in Notepad
242 | 
243 | ; MSPaint
244 | #HotIf WinActive("Untitled - Paint")
245 | #Space::
246 | {
247 |     MsgBox "You pressed WIN+SPACE in MSPaint!"
248 | }
249 | ::msg::You typed msg in MSPaint!
250 |

For more in-depth information, check out the #HotIf page.

251 |

c. Multiple hotkeys/hotstrings per file

252 |

This, for some reason crosses some people's minds. So I'll set it clear: AutoHotkey has the ability to have as many hotkeys and hotstrings in one file as you want. Whether it's 1, or 3253 (or more).

253 |
#i::
254 | {
255 |     Run "https://www.google.com/"
256 | }
257 | 
258 | ^p::
259 | {
260 |     Run "notepad.exe"
261 | }
262 | 
263 | ~j::
264 | {
265 |     Send "ack"
266 | }
267 | 
268 | :*:acheiv::achiev
269 | ::achievment::achievement
270 | ::acquaintence::acquaintance
271 | :*:adquir::acquir
272 | ::aquisition::acquisition
273 | :*:agravat::aggravat
274 | :*:allign::align
275 | ::ameria::America
276 |

The above code is perfectly acceptable. Multiple hotkeys, multiple hotstrings. All in one big happy script file.

277 | 278 |

d. Examples

279 |
::btw::by the way  ; Replaces "btw" with "by the way" as soon as you press a default ending character.
280 |
:*:btw::by the way  ; Replaces "btw" with "by the way" without needing an ending character.
281 |
^n::  ; CTRL+N hotkey
282 | {
283 |     Run "notepad.exe"  ; Run Notepad when you press CTRL+N.
284 | }  ; This ends the hotkey. The code below this will not be executed when pressing the hotkey.
285 |
^b::  ; CTRL+B hotkey
286 | {
287 |     Send "{Ctrl down}c{Ctrl up}"  ; Copies the selected text. ^c could be used as well, but this method is more secure.
288 |     SendInput "[b]{Ctrl down}v{Ctrl up}[/b]" ; Wraps the selected text in BBCode tags to make it bold in a forum.
289 | }  ; This ends the hotkey. The code below this will not be executed when pressing the hotkey.
290 | 291 |

3 - Sending Keystrokes

292 |

So now you decided that you want to send (type) keys to a program. We can do that. Use the Send function. This function literally sends keystrokes, to simulate typing or pressing of keys.

293 |

But before we get into things, we should talk about some common issues that people have.

294 |

Just like hotkeys, the Send function has special keys too. Lots and lots of them. Here are the four most common symbols:

295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 |
SymbolDescription
!Sends Alt. For example, Send "This is text!a" would send the keys "This is text" and then press Alt+A. Note: !A produces a different effect in some programs than !a. This is because !A presses Alt+Shift+A and !a presses Alt+A. If in doubt, use lowercase.
+Sends Shift. For example, Send "+abC" would send the text "AbC", and Send "!+a" would press Alt+Shift+A.
^Sends Ctrl. For example, Send "^!a" would press Ctrl+Alt+A, and Send "^{Home}" would send Ctrl+Home. Note: ^A produces a different effect in some programs than ^a. This is because ^A presses Ctrl+Shift+A and ^a presses Ctrl+A. If in doubt, use lowercase.
#Sends Win (the key with the Windows logo) therefore Send "#e" would hold down Win and then press E.
317 |

The gigantic table on the Send page shows pretty much every special key built-in to AHK. For example: {Enter} and {Space}.

318 |

Caution: This table does not apply to hotkeys. Meaning, you do not wrap Ctrl or Enter (or any other key) inside curly brackets when making a hotkey.

319 |

An example showing what shouldn't be done to a hotkey:

320 |
; When making a hotkey...
321 | ; WRONG
322 | {LCtrl}::
323 | {
324 |     Send "AutoHotkey"
325 | }
326 | 
327 | ; CORRECT
328 | LCtrl::
329 | {
330 |     Send "AutoHotkey"
331 | }
332 | 
333 |

A common issue lots of people have is, they assume that the curly brackets are put in the documentation pages just for fun. But in fact they are needed. It's how AHK knows that {!} means "exclamation point" and not "press Alt". So please remember to check the table on the Send page and make sure you have your brackets in the right places. For example:

334 |
Send "This text has been typed{!}" ; Notice the ! between the curly brackets? That's because if it wasn't, AHK would press the ALT key.
335 | 
336 |
; Same as above, but with the ENTER key. AHK would type out "Enter" if
337 | ; it wasn't wrapped in curly brackets.
338 | Send "Multiple Enter lines have Enter been sent." ; WRONG
339 | Send "Multiple{Enter}lines have{Enter}been sent." ; CORRECT
340 | 
341 |

Another common issue is that people think that everything needs to be wrapped in brackets with the Send function. That is FALSE. If it's not in the chart, it does not need brackets. You do not need to wrap common letters, numbers or even some symbols such as . (period) in curly brackets. Also, with the Send functions you are able to send more than one letter, number or symbol at a time. So no need for a bunch of Send functions with one letter each. For example:

342 |
Send "{a}"       ; WRONG
343 | Send "{b}"       ; WRONG
344 | Send "{c}"       ; WRONG
345 | Send "{a}{b}{c}" ; WRONG
346 | Send "{abc}"     ; WRONG
347 | Send "abc"       ; CORRECT
348 | 349 |

To hold down or release a key, enclose the key name in curly brackets and then use the word UP or DOWN. For example:

350 |
; This is how you hold one key down and press another key (or keys).
351 | ; If one method doesn't work in your program, please try the other.
352 | Send "^s"                     ; Both of these send CTRL+S
353 | Send "{Ctrl down}s{Ctrl up}"  ; Both of these send CTRL+S
354 | Send "{Ctrl down}c{Ctrl up}"
355 | Send "{b down}{b up}"
356 | Send "{Tab down}{Tab up}"
357 | Send "{Up down}"  ; Press down the up-arrow key.
358 | Sleep 1000        ; Keep it down for one second.
359 | Send "{Up up}"    ; Release the up-arrow key.
360 | 361 |

But now you are wondering "How can I make my really long Send functions readable?". Easy. Use what is known as a continuation section. Simply specify an opening parenthesis on a new line, then your content, finally a closing parenthesis on its own line. For more information, read about Continuation Sections.

362 |
Send "
363 | (
364 | Line 1
365 | Line 2
366 | Apples are a fruit.
367 | )"
368 |

Note: There are several different forms of Send. Each has their own special features. If one form of Send does not work for your needs, try another type of Send. Simply replace the function name "Send" with one of the following: SendText, SendInput, SendPlay, SendEvent. For more information on what each one does, read this.

369 | 370 |

a. Games

371 |

This is important: Some games, especially multiplayer games, use anti-cheat programs. Things like GameGuard, Hackshield, PunkBuster and several others. Not only is bypassing these systems in violation of the games policies and could get you banned, they are complex to work around.

372 |

If a game has a cheat prevention system and your hotkeys, hotstrings and Send functions do not work, you are out of luck. However there are methods that can increase the chance of working in some games, but there is no magical "make it work in my game now!!!" button. So try all of these before giving up.

373 | 374 |

There are also known issues with DirectX. If you are having issues and you know the game uses DirectX, try the stuff described on the FAQ page. More DirectX issues may occur when using PixelSearch, PixelGetColor or ImageSearch. Colors might turn out black (0x000000) no matter the color you try to get. You should also try running the game in windowed mode, if possible. That fixes some DirectX issues.

375 |

There is no single solution to make AutoHotkey work in all programs. If everything you try fails, it may not be possible to use AutoHotkey for your needs.

376 | 377 |

4 - Running Programs & Websites

378 |

To run a program such as mspaint.exe, calc.exe, script.ahk or even a folder, you can use the Run function. It can even be used to open URLs such as https://www.autohotkey.com/. If your computer is setup to run the type of program you want to run, it's very simple:

379 |
; Run a program. Note that most programs will require a FULL file path:
380 | Run A_ProgramFiles "\Some_Program\Program.exe"
381 | 
382 | ; Run a website:
383 | Run "https://www.autohotkey.com"
384 |

There are some other advanced features as well, such as command line parameters and CLSID. If you want to learn more about that stuff, visit the Run page.

385 |

Here are a few more samples:

386 |
; Several programs do not need a full path, such as Windows-standard programs:
387 | Run "notepad.exe"
388 | Run "mspaint.exe"
389 | 
390 | ; Run the "My Documents" folder using a built-in variable:
391 | Run A_MyDocuments
392 | 
393 | ; Run some websites:
394 | Run "https://www.autohotkey.com"
395 | Run "https://www.google.com"
396 |

For more in-depth information and examples, check out the Run page.

397 | 398 |

5 - Function Calls with or without Parentheses

399 |

In AutoHotkey, function calls can be specified with or without parentheses. The parentheses are usually only necessary if the return value of the function is needed or the function name is not written at the start of the line.

400 |

A list of all built-in functions can be found here.

401 |

A typical function call looks like this:

402 |
Function(Parameter1, Parameter2, Parameter3) ; with parentheses
403 | Function Parameter1, Parameter2, Parameter3  ; without parentheses
404 |

The parameters support any kind of expression; this means for example:

405 |
    406 |
  1. You can do math in them: 407 |
    SubStr(37 * 12, 1, 2)
    408 | SubStr(A_Hour - 12, 2)
    409 |
  2. 410 |
  3. You can call another functions inside them (note that these function calls must be specified with parentheses as they are not at the start of the line): 411 |
    SubStr(A_AhkPath, InStr(A_AhkPath, "AutoHotkey"))
    412 |
  4. 413 |
  5. Text needs to be wrapped in quotes: 414 |
    SubStr("I'm scripting, awesome!", 16)
    415 |
  6. 416 |
417 | 418 |

The most common way assigning the return value of a function to a variable is like so:

419 |
MyVar := SubStr("I'm scripting, awesome!", 16)
420 |

This isn't the only way, but the most common. You are using MyVar to store the return value of the function that is to the right of the := operator. See Functions for more details.

421 |

In short:

422 |
; These are function calls without parentheses:
423 | MsgBox "This is some text."
424 | StrReplace Input, "AutoHotKey", "AutoHotkey"
425 | SendInput "This is awesome{!}{!}{!}"
426 | 
427 | ; These are function calls with parentheses:
428 | SubStr("I'm scripting, awesome!", 16)
429 | FileExist(VariableContainingPath)
430 | Output := SubStr("I'm scripting, awesome!", 16)
431 | 432 |

a. Code blocks

433 |

Code blocks are lines of code surrounded by little curly brackets ({ and }). They group a section of code together so that AutoHotkey knows it's one big family and that it needs to stay together. They are most often used with functions and control flow statements such as If and Loop. Without them, only the first line in the block is called.

434 |

In the following code, both lines are run only if MyVar equals 5:

435 |
if (MyVar = 5)
436 | {
437 |     MsgBox "MyVar equals " MyVar "!!"
438 |     ExitApp
439 | }
440 |

In the following code, the message box is only shown if MyVar equals 5. The script will always exit, even if MyVar is not 5:

441 |
if (MyVar = 5)
442 |     MsgBox "MyVar equals " MyVar "!!"
443 |     ExitApp
444 |

This is perfectly fine since the if-statement only had one line of code associated with it. It's exactly the same as above, but I outdented the second line so we know it's separated from the if-statement:

445 |
if (MyVar = 5)
446 |     MsgBox "MyVar equals " MyVar "!!"
447 | MsgBox "We are now 'outside' of the if-statement. We did not need curly brackets since there was only one line below it."
448 | 449 |

6 - Variables

450 |

Variables are like little post-it notes that hold some information. They can be used to store text, numbers, data from functions or even mathematical equations. Without them, programming and scripting would be much more tedious.

451 |

Variables can be assigned a few ways. We'll cover the most common forms. Please pay attention to the colon-equal operator (:=).

452 |
453 |
Text assignment
454 |
455 |
MyVar := "Text"
456 |

This is the simplest form for a variable. Simply type in your text and done. Any text needs to be in quotes.

457 |
458 |
Variable assignment
459 |
460 |
MyVar := MyVar2
461 |

Same as above, but you are assigning a value of a variable to another variable.

462 |
463 |
Number assignment
464 |
465 |
MyVar := 6 + 8 / 3 * 2 - Sqrt(9)
466 |

Thanks to expressions, you can do math!

467 |
468 |
Mixed assignment
469 |
470 |
MyVar := "The value of 5 + " MyVar2 " is: " 5 + MyVar2
471 |

A combination of the three assignments above.

472 |
473 |
474 |

Equal signs (=) with a symbol in front of it such as := += -= .= etc. are called assignment operators.

475 | 476 |

a. Getting user input

477 |

Sometimes you want to have the user to choose the value of stuff. There are several ways of doing this, but the simplest way is InputBox. Here is a simple example on how to ask the user a couple of questions and doing some stuff with what was entered:

478 |
IB1 := InputBox("What is your first name?", "Question 1")
479 | if IB1.Value = "Bill"
480 |     MsgBox "That's an awesome name, " IB1.Value "."
481 | 
482 | IB2 := InputBox("Do you like AutoHotkey?", "Question 2")
483 | if IB2.Value = "yes"
484 |     MsgBox "Thank you for answering " IB2.Value ", " IB1.Value "! We will become great friends."
485 | else
486 |     MsgBox IB1.Value ", That makes me sad."
487 | 488 |

b. Other Examples?

489 |
Result := MsgBox("Would you like to continue?",, 4)
490 | if Result = "No"
491 |     return  ; If No, stop the code from going further.
492 | MsgBox "You pressed YES."  ; Otherwise, the user picked yes.
493 |
Var := "text"  ; Assign some text to a variable.
494 | Num := 6  ; Assign a number to a variable.
495 | Var2 := Var  ; Assign a variable to another.
496 | Var3 .= Var  ; Append a variable to the end of another.
497 | Var4 += Num  ; Add the value of a variable to another.
498 | Var4 -= Num  ; Subtract the value of a variable from another.
499 | Var5 := SubStr(Var, 2, 2)  ; Variable inside a function.
500 | Var6 := Var "Text"  ; Assigns a variable to another with some extra text.
501 | MsgBox(Var)  ; Variable inside a function.
502 | MsgBox Var  ; Same as above.
503 | Var := StrSplit(Var, "x")  ; Variable inside a function that uses InputVar and OutputVar.
504 | if (Num = 6)  ; Check if a variable is equal to a number.
505 | if Num = 6  ; Same as above.
506 | if (Var != Num)  ; Check if a variable is not equal to another.
507 | if Var1 < Var2  ; Check if a variable is lesser than another.
508 |

7 - Objects

509 |

Objects are a way of organizing your data for more efficient usage. An object is basically a collection of variables. A variable that belongs to an object is known as a "property". An object might also contain items, such as array elements.

510 |

There are a number of reasons you might want to use an object for something. Some examples:

511 | 516 | 517 |

a. Creating Objects

518 |

There are a few ways to create an object, and the most common ones are listed below:

519 |
520 |
Bracket syntax (Array)
521 |
522 |
MyArray := ["one", "two", "three", 17]
523 |

This creates an Array, which represents a list of items, numbered 1 and up. In this example, the value "one" is stored at index 1, and the value 17 is stored at index 4.

524 |
525 |
Brace syntax
526 |
527 |
Banana := {Color: "Yellow", Taste: "Delicious", Price: 3}
528 |

This creates an ad hoc Object. It is a quick way to create an object with a short set of known properties. In this example, the value "Yellow" is stored in the Color property and the value 3 is stored in the Price property.

529 |
530 |
Array constructor
531 |
532 |
MyArray := Array("one", "two", "three", 17)
533 |

This is equivalent to the bracket syntax. It is actually calling the Array class, not a function.

534 |
535 |
Map constructor
536 |
537 |
MyMap := Map("^", "Ctrl", "!", "Alt")
538 |

This creates a Map, or associative array. In this example, the value "Ctrl" is associated with the key "^", and the value "Alt" is associated with the key "!". Maps are often created empty with Map() and later filled with items.

539 |
540 |
Other constructor
541 |
542 |
Banana := Fruit()
543 |

Creates an object of the given class (Fruit in this case).

544 |
545 |
546 | 547 |

b. Using Objects

548 |

There are many ways to use objects, including retrieving values, setting values, adding more values, and more.

549 | 550 |

To set values

551 |
552 |
Bracket notation
553 |
554 |
MyArray[2] := "TWO"
555 | MyMap["#"] := "Win"
556 |

Setting array elements or items in a map or collection is similar to assigning a value to a variable. Simply append bracket notation to the variable which contains the object (array, map or whatever). The index or key between the brackets is an expression, so quote marks must be used for any non-numeric literal value.

557 |
558 |
Dot notation
559 |
560 |
Banana.Consistency := "Mushy"
561 |

This example assigns a new value to a property of the object contained by Banana. If the property doesn't already exist, it is created.

562 |
563 |
564 | 565 |

To retrieve values

566 |
567 |
Bracket notation
568 |
569 |
Value := MyMap["^"]
570 |

This example retrieves the value previously associated with (mapped to) the key "^". Often the key would be contained by a variable, such as MyMap[modifierChar].

571 |
572 |
Dot notation
573 |
574 |
Value := Banana.Color
575 |

This example retrieves the Color property of the Banana object.

576 |
577 |
578 | 579 |

To add new keys and values

580 |
581 |
Bracket notation
582 |
583 |
MyMap["NewerKey"] := 3.1415
584 |

To directly add a key and value, just set a key that doesn't exist yet. However, note that when assigning to an Array, the index must be within the range of 1 to the array's current length. Different objects may have different requirements.

585 |
586 |
Dot notation
587 |
588 |
MyObject.NewProperty := "Shiny"
589 |

As mentioned above, assigning to a property that hasn't already been defined will create a new property.

590 |
591 |
InsertAt method
592 |
593 |
MyArray.InsertAt(Index, Value1, Value2, Value3...)
594 |

InsertAt is a method used to insert new values at a specific position within an Array, but other kinds of objects may also define a method by this name.

595 |
596 |
Push method
597 |
598 |
MyArray.Push(Value1, Value2, Value3...)
599 |

Push "appends" the values to the end of the Array MyArray. It is the preferred way to add new elements to an array, since the bracket notation can't be used to assign outside the current range of values.

600 |
601 |
602 | 603 |

To remove properties and items

604 |
605 |
Delete method
606 |
607 |
RemovedValue := MyObject.Delete(AnyKey)
608 |

Array and Map have a Delete method, which removes the value from the array or map. The previous value of MyObject[AnyKey] will be stored in RemovedValue. For an Array, this leaves the array element without a value and doesn't affect other elements in the array.

609 |
610 |
Pop method
611 |
612 |
MyArray.Pop()
613 |

This Array method removes the last element from an array and returns its value. The array's length is reduced by 1.

614 |
615 |
RemoveAt method
616 |
617 |
RemovedValue := MyArray.RemoveAt(Index)
618 |
MyArray.RemoveAt(Index, Length)
619 |

Array has the RemoveAt method, which removes an array element or range of array elements. Elements (if any) to the right of the removed elements are shifted to the left to fill the vacated space.

620 |
621 |
622 | 623 |

8 - Other Helpful Goodies

624 |

We have reached the end of our journey, my good friend. I hope you have learned something. But before we go, here are some other things that I think you should know. Enjoy!

625 | 626 |

a. The mysterious square brackets

627 |

Throughout the documentation, you will see these two symbols ([ and ]) surrounding code in the yellow syntax box at the top of almost all pages. Anything inside of these brackets are optional. Meaning the stuff inside can be left out if you don't need them. When writing your code, it is very important to not type the square brackets in your code.

628 |

On the ControlGetText page you will see this:

629 |
Text := ControlGetText(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
630 |

So you could simply do this if you wanted:

631 |
Text := ControlGetText(Control)
632 |

Or add in some more details:

633 |
Text := ControlGetText(Control, WinTitle)
634 |

What if you wanted to use ExcludeTitle but not fill in WinText or WinTitle? Simple!

635 |
Text := ControlGetText(Control,,, ExcludeTitle)
636 |

Please note that you cannot IGNORE parameters, but you can leave them blank. If you were to ignore WinTitle, WinText, it would look like this and cause issues:

637 |
Text := ControlGetText(Control, ExcludeTitle)
638 | 639 |

b. Finding your AHK version

640 |

Run this code to see your AHK version:

641 |
MsgBox A_AhkVersion
642 |

Or look for "AutoHotkey Help File" or "AutoHotkey.chm" in the start menu or your installation directory.

643 | 644 |

c. Trial and Error

645 |

Trial and Error is a very common and effective way of learning. Instead of asking for help on every little thing, sometimes spending some time alone (sometimes hours or days) and trying to get something to work will help you learn faster.

646 |

If you try something and it gives you an error, study that error. Then try to fix your code. Then try running it again. If you still get an error, modify your code some more. Keep trying and failing until your code fails no more. You will learn a lot this way by reading the documentation, reading errors and learning what works and what doesn't. Try, fail, try, fail, try, try, try, fail, fail, succeed!

647 |

This is how a lot of "pros" have learned. But don't be afraid to ask for help, we don't bite (hard). Learning takes time, the "pros" you encounter did not learn to be masters in just a few hours or days.

648 |

"If at first you don't succeed, try, try, try again." - Hickson, William E.

649 |

d. Indentation

650 |

This stuff (indentation) is very important! Your code will run perfectly fine without it, but it will be a major headache for you and other to read your code. Small code (25 lines or less) will probably be fine to read without indentation, but it'll soon get sloppy. It's best you learn to indent ASAP. Indentation has no set style, but it's best to keep everything consistent.

651 |

"What is indentation?" you ask? It's simply spacing to break up your code so you can see what belongs to what. People usually use 3 or 4 spaces or 1 tab per "level".

652 |

Not indented:

653 |
if (car = "old")
654 | {
655 | MsgBox "The car is really old."
656 | if (wheels = "flat")
657 | {
658 | MsgBox "This car is not safe to drive."
659 | return
660 | }
661 | else
662 | {
663 | MsgBox "Be careful! This old car will be dangerous to drive."
664 | }
665 | }
666 | else
667 | {
668 | MsgBox "My, what a shiny new vehicle you have there."
669 | }
670 |

Indented:

671 | 672 |
if (car = "old")
673 | {
674 |     MsgBox "The car is really old."
675 |     if (wheels = "flat")
676 |     {
677 |         MsgBox "This car is not safe to drive."
678 |         return
679 |     }
680 |     else
681 |     {
682 |         MsgBox "Be careful! This old car will be dangerous to drive."
683 |     }
684 | }
685 | else
686 | {
687 |     MsgBox "My, what a shiny new vehicle you have there."
688 | }
689 |

See Wikipedia's Indentation style page for various styles and examples. Choose what you like or learn to indent how you think it's easiest to read.

690 | 691 |

e. Asking for Help

692 |

Before you ask, try doing some research yourself or try to code it yourself. If that did not yield results that satisfy you, read below.

693 | 704 |

If you don't get an answer right away, wait at least 1 day (24 hours) before asking for more help. We love to help, but we also do this for free on our own time. We might be at work, sleeping, gaming, with family or just too busy to help.

705 |

And while you wait for help, you can try learning and doing it yourself. It's a good feeling, making something yourself without help.

706 | 707 |

f. Other links

708 |

Frequently Asked Questions (FAQ)

709 | 710 | 711 | -------------------------------------------------------------------------------- /docs/Variables.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Variables and Expressions - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Variables and Expressions

14 | 15 |

Table of Contents

16 | 23 |

Variables

24 |

See Variables for general explanation and details about how variables work.

25 |

Storing values in variables: To store a string or number in a variable, use the colon-equal operator (:=) followed by a number, quoted string or any other type of expression. For example:

26 |
MyNumber := 123
  27 | MyString := "This is a literal string."
  28 | CopyOfVar := Var
29 |

A variable cannot be explicitly deleted, but its previous value can be released by assigning a new value, such as an empty string:

30 |
MyVar := ""
31 |

A variable can also be assigned a value indirectly, by taking its reference and using a double-deref or passing it to a function. For example:

32 |
MouseGetPos &x, &y
33 |

Reading the value of a variable which has not been assigned a value is considered an error. IsSet can be used to detect this condition.

34 |

Retrieving the contents of variables: To include the contents of a variable in a string, use concatenation or Format. For example:

35 |
MsgBox "The value of Var is " . Var . "."
  36 | MsgBox "The value in the variable named Var is " Var "."
  37 | MsgBox Format("Var has the value {1}.", Var)
  38 | 
39 |

Sub-expressions can be combined with strings in the same way. For example:

40 |
MsgBox("The sum of X and Y is " . (X + Y))
  41 | 
42 |

Comparing variables: Please read the expressions section below for important notes about the different kinds of comparisons.

43 |

Expressions

44 |

See Expressions for a structured overview and further explanation.

45 |

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

46 |

Plain words in expressions are interpreted as variable names. Consequently, literal strings must be enclosed in double quotes to distinguish them from variables. For example:

47 |
if (CurrentSetting > 100 or FoundColor != "Blue")
  48 |     MsgBox "The setting is too high or the wrong color is present."
49 |

In the example above, "Blue" appears in quotes because it is a literal string. Single-quote marks (') and double-quote marks (") function identically, except that a string enclosed in single-quote marks can contain literal double-quote marks and vice versa. Therefore, to include an actual quote mark inside a literal string, escape the quote mark or enclose the string in the opposite type of quote mark. For example:

50 |
MsgBox "She said, `"An apple a day.`""
  51 | MsgBox 'She said, "An apple a day."'
52 |

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.

53 |

Storing the result of an expression: To assign a result to a variable, use the colon-equal operator (:=). For example:

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

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.

56 |

Operators such as NOT/>/=/< automatically produce a true or false value: they yield 1 for true and 0 for false. However, the AND/OR operators always produce one of the input values. For example, in the following expression, the variable Done is assigned 1 if A_Index is greater than 5 or the value of FoundIt in all other cases:

57 |
Done := A_Index > 5 or FoundIt
58 |

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.

59 |

In an expression, the keywords true and false resolve to 1 and 0. They can be used to make a script more readable as in these examples:

60 |
CaseSensitive := false
  61 | ContinueSearch := true
62 |

Integers and floating point: Within an expression, numbers are considered to be floating point if they contain a decimal point or scientific notation; 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.

63 |

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. Floating point numbers can optionally be written in scientific notation, with or without a decimal point (e.g. 1e4 or -2.1E-4).

64 |

Within expressions, unquoted literal numbers such as 128, 0x7F and 1.0 are converted to pure numbers before the script begins executing, so converting the number to a string may produce a value different to the original literal value. For example:

65 |
MsgBox(0x7F)  ; Shows 128
  66 | MsgBox(1.00)  ; Shows 1.0
67 | 68 |

Operators in Expressions

69 |

See Operators for general information about operators.

70 |

Except where noted below, any blank value (empty string) or non-numeric value involved in a math operation is not assumed to be zero. Instead, a TypeError is thrown. If Try is not used, the unhandled exception causes an error dialog by default.

71 | 72 |

Expression Operators (in descending precedence order)

73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 103 | 104 | 105 | 107 | 111 | 112 | 113 | 114 | 119 | 120 | 121 | 125 | 133 | 134 | 135 | 139 | 145 | 146 | 147 | 149 | 152 | 153 | 154 | 157 | 168 | 169 | 170 | 174 | 183 | 184 | 185 | 186 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 204 | 207 | 208 | 209 | 213 | 218 | 219 | 220 | 221 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 233 | 242 | 243 | 244 | 246 | 255 | 256 | 257 | 258 | 264 | 265 | 266 | 267 | 272 | 273 | 274 | 288 | 295 | 296 | 297 | 298 | 313 | 314 | 315 | 316 | 317 | 321 | 322 |
OperatorDescription
%Expr% 81 |

Dereference or name substitution.

82 |

When Expr evaluates to a VarRef, %Expr% accesses the corresponding variable. For example, x := &y takes a reference to y and assigns it to x, then %x% := 1 assigns to the variable y and %x% reads its value.

83 |

Otherwise, the value of the sub-expression Expr is used as the name or partial name of a variable or property. This allows the script to refer to a variable or property whose name is determined by evaluating Expr, which is typically another variable. Variables cannot be created dynamically, but a variable can be assigned dynamically if it has been declared or referenced non-dynamically somewhere in the script.

84 |

Note: The result of the sub-expression Expr must be the name or partial name of the variable or property to be accessed.

85 |

Percent signs cannot be used directly within Expr due to ambiguity, but can be nested within parentheses. Otherwise, Expr can be any expression.

86 |

If there are any adjoining %Expr% sequences and partial names (without any spaces or other characters between them), they are combined to form a single name.

87 |

An Error is typically thrown if the variable does not already exist, or if it is uninitialized and its value is being read. The or-maybe operator (??) can be used to avoid that case by providing a default value. For example: %'novar'% ?? 42.

88 |

Although this is historically known as a "double-deref", this term is inaccurate when Expr does not contain a variable (first deref), and also when the resulting variable is the target of an assignment, not being dereferenced (second deref).

89 |
x.y
x.%z%
Member access. Get or set a value or call a method of object x, where y is a literal name and z is an expression which evaluates to a name. See object syntax.
var? 98 |

Maybe. Permits the variable to be unset. This is valid only when passing a variable to an optional parameter, array element or object literal; or on the right-hand side of a direct assignment. The question mark must be followed by one of the following symbols (ignoring whitespace): )]},:. The variable may be passed conditionally via the ternary operator or on the right-hand side of AND/OR.

99 |

The variable is typically an optional parameter, but can be any variable. For variables that are not function parameters, a VarUnset warning may still be shown at load-time if there are other references to the variable but no assignments.

100 |

This operator is currently supported only for variables. To explicitly or conditionally omit a parameter in more general cases, use the unset keyword.

101 |

See also: unset (Optional Parameters)

102 |
++
106 | --
108 |

Pre- and post-increment/decrement. Adds or subtracts 1 from a variable. The operator may appear either before or after the variable's name. If it appears before the name, the operation is performed and its result is used by the next operation (the result is a variable reference in this case). For example, Var := ++X increments X and then assigns its value to Var. Conversely, if the operator appears after the variable's name, the result is the value of X prior to performing the operation. For example, Var := X++ increments X but Var receives the value X had before it was incremented.

109 |

These operators can also be used with a property of an object, such as myArray.Length++ or --myArray[i]. In these cases, the result of the sub-expression is always a number, not a variable reference.

110 |
** 115 |

Power. Example usage: Base**Exponent. Both Base and Exponent may contain a decimal point. If Exponent is negative, the result will be formatted as a floating point number even if 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.

116 |

The power operator is right-associative. For example, x ** y ** z is evaluated as x ** (y ** z).

117 |

Note: A negative Base combined with a fractional Exponent such as (-2)**0.5 is not supported; attempting it will cause an exception to be thrown. But both (-2)**2 and (-2)**2.0 are supported. If both Base and Exponent are 0, the result is undefined and an exception is thrown.

118 |
-
122 | !
123 | ~
124 | &
126 |

Unary minus (-): Inverts the sign of its operand.

127 |

Unary plus (+): +N is equivalent to -(-N). This has no effect when applied to a pure number, but can be used to convert numeric strings to pure numbers.

128 |

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. Consecutive unary operators such as !!Var are allowed because they are evaluated in right-to-left order.

129 |

Bitwise-not (~): This inverts each bit of its operand. As 64-bit signed integers are used, a positive input value will always give a negative result and vice versa. For example, ~0xf0f evaluates to -0xf10 (-3856), which is binary equivalent to 0xfffffffffffff0f0. If an unsigned 32-bit value is intended, the result can be truncated with result & 0xffffffff. If the operand is a floating point value, a TypeError is thrown.

130 |

Reference (&): Creates a VarRef, which is a value representing a reference to a variable. A VarRef can then be used to indirectly access the target variable. For example, ref := &target followed by %ref% := 1 would assign the value 1 to target. The VarRef would typically be passed to a function, but could be stored in an array or property. See also: Dereference, ByRef.

131 |

Taking a reference to a built-in variable such as A_Clipboard is currently not supported, except when being passed directly to an OutputVar parameter of a built-in function.

132 |
*
136 | /
137 | // 138 |

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

140 |

Other uses: The asterisk (*) symbol is also used in variadic function calls.

141 |

True divide (/): 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.

142 |

Integer divide (//): The double-slash operator uses high-performance integer division. For example, 5//3 is 1 and 5//-3 is -1. If either of the inputs is in floating point format, a TypeError is thrown. For modulo, see Mod.

143 |

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).

144 |

Division by zero causes a ZeroDivisionError to be thrown.

+
148 | -

Add (+) and subtract (-). On a related note, 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.

150 |

Other uses: If the + or - symbol is not preceded by a value (or a sub-expression which yields a value), it is interpreted as a unary operator instead.

151 |
<<
155 | >>
156 | >>>
158 |

Bit shift left (<<). Example usage: Value1 << Value2. This is equivalent to multiplying Value1 by "2 to the Value2th power".

159 |

Arithmetic bit shift right (>>). Example usage: Value1 >> Value2. This is equivalent to dividing Value1 by "2 to the Value2th power" and rounding the result to the nearest integer leftward on the number line; for example, -3>>1 is -2.

160 |

Logical bit shift right (>>>). Example usage: Value1 >>> Value2. Unlike arithmetic bit shift right, this does not preserve the sign of the number. For example, -1 has the same bit representation as the unsigned 64-bit integer 0xffffffffffffffff, therefore -1 >>> 1 is 0x7fffffffffffffff.

161 |

The following applies to all three operators:

162 |
    163 |
  • If either of the inputs is a floating-point number, a TypeError is thrown.
  • 164 |
  • A 64-bit operation is performed and the result is a 64-bit signed integer.
  • 165 |
  • If Value2 is less than 0 or greater than 63, an exception is thrown.
  • 166 |
167 |
&
171 | ^
172 | | 173 |
175 |

Bitwise-and (&), bitwise-exclusive-or (^), and bitwise-or (|). Of the three, & has the highest precedence and | has the lowest.

176 |

The following applies to all three operators:

177 |
    178 |
  • If either of the inputs is a floating-point number, a TypeError is thrown.
  • 179 |
  • A 64-bit operation is performed and the result is a 64-bit signed integer.
  • 180 |
181 |

Related: Bitwise-not (~)

182 |
. 187 |

Concatenate. A period (dot) with at least one space or tab on each side is used to combine two items into a single string. You may also omit the period to achieve the same result (except where ambiguous such as x -y, or when the item on the right side has a leading ++ or --). When the dot is omitted, there must be at least one space or tab between the items to be merged.

188 |
Var := "The color is " . FoundColor  ; Explicit concat
 189 | Var := "The color is " FoundColor    ; Auto-concat
 190 | 
191 |

Sub-expressions can also be concatenated. For example: Var := "The net price is " . Price * (1 - Discount/100).

192 |

A line that begins with a period (or any other operator) is automatically appended to the line above it.

193 |

The entire length of each input is used, even if it includes binary zero. For example, Chr(0x2010) Chr(0x0000) Chr(0x4030) produces the following string of bytes (due to UTF-16-LE encoding): 0x10, 0x20, 0, 0, 0x30, 0x40. The result has an additional null-terminator (binary zero) which is not included in the length.

194 |

Other uses: If there is no space or tab to the right of a period (dot), it is interpreted as either a literal floating-point number or member access. For example, 1.1 and (.5) are numbers, A_Args.Has(3) is a method call and A_Args.Length is a property access.

195 |
~=Shorthand for RegExMatch. For example, the result of "abc123" ~= "\d" is 4 (the position of the first numeric character).
>   <
203 | >= <=
205 |

Greater (>), less (<), greater-or-equal (>=), and less-or-equal (<=). The inputs are compared numerically. A TypeError is thrown if either of the inputs is not a number or a numeric string.

206 |
=
210 | ==
211 | !=
212 | !==
214 |

Case-insensitive equal (=) / not-equal (!=) and case-sensitive equal (==) / not-equal (!==). The == operator behaves identically to = except when either of the inputs is not numeric (or both are strings), in which case == is always case-sensitive and = is always case-insensitive. The != and !== behave identically to their counterparts without !, except that the result is inverted.

215 |

The == and !== operators can be used to compare strings which contain binary zero. All other comparison operators except ~= compare only up to the first binary zero.

216 |

For case-insensitive comparisons, only the ASCII letters A-Z are considered equivalent to their lowercase counterparts. To instead compare according to the rules of the current user's locale, use StrCompare and specify "Locale" for the CaseSense parameter.

217 |
IS
IN
CONTAINS
222 |

Value is Class yields 1 (true) if Value is an instance of Class, otherwise 0 (false). Class must be an Object with an own Prototype property, but typically the property is defined implicitly by a class definition. This operation is generally equivalent to HasBase(Value, Class.Prototype).

223 |

in and contains are reserved for future use.

224 |
NOTLogical-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
232 | &&

Both of these are logical-AND. For example: x > 3 and x < 10.

234 |

In an expression where all operands are true, the last operand is returned. Otherwise, the first operand that is false is returned. In other words, the result is true only if all operands are true. Boolean expressions are subject to short-circuit evaluation (from left to right) to improve performance.

235 |

In the following example, all operands are true and will be evaluated:

236 |
A := 1, B := {}, C := 20, D := true, E := "str"
 237 | MsgBox(A && B && C && D && E) ; Shows "str" (E).
238 |

In the following example, only the first two operands will be evaluated because B is false. The rest is ignored, i.e. C is not incremented either:

239 |
A := 1, B := "", C := 0, D := false, E := "str"
 240 | MsgBox(A && B && ++C && D && E) ; Shows "" (B).
241 |

A line that begins with AND or && (or any other operator) is automatically appended to the line above it.

OR
245 | ||

Both of these are logical-OR. For example: x <= 3 or x >= 10.

247 |

In an expression where at least one operand is true, the first operand that is true is returned. Otherwise, the last operand that is false is returned. In other words, if at least one operand is true, the result is true. Boolean expressions are subject to short-circuit evaluation (from left to right) to improve performance.

248 |

In the following example, at least one operand is true. All operands up to D will be evaluated. E is ignored and will never be incremented:

249 |
A := "", B := false, C := 0, D := "str", E := 20
 250 | MsgBox(A || B || C || D || ++E) ; Shows "str" (D).
251 |

In the following example, all operands are false and will be evaluated:

252 |
A := "", B := false, C := 0
 253 | MsgBox(A || B || C) ; Shows "0" (C).
254 |

A line that begins with OR or || (or any other operator) is automatically appended to the line above it.

?? 259 |

Or maybe, otherwise known as the coalescing operator. If the left operand (which must be a variable) has a value, it becomes the result and the right branch is skipped. Otherwise, the right operand becomes the result. In other words, A ?? B behaves like A || B (logical-OR) except that the condition is IsSet(A).

260 |

This is typically used to provide a default value when it is known that a variable or optional parameter might not already have a value. For example:

261 |
MsgBox MyVar ?? "Default value"
262 |

Since the variable is expected to sometimes be uninitialized, no error is thrown in that case. Unlike IsSet(A) ? A : B, a VarUnset warning may still be shown at load-time if there are other references to the variable but no assignments.

263 |
?: 268 |

Ternary operator. This operator is a shorthand replacement for the if-else statement. It evaluates the condition on its left side to determine which of its two branches should become its final result. For example, var := x>y ? 2 : 3 stores 2 in Var if x is greater than y; otherwise it stores 3. To enhance performance, only the winning branch is evaluated (see short-circuit evaluation).

269 |

See also: maybe (var?), or-maybe (??)

270 |

Note: When used at the beginning of a line, the ternary condition should usually be enclosed in parentheses to reduce ambiguity with other types of statements. For details, see Expression Statements.

271 |
:=
275 | +=
276 | -=
277 | *=
278 | /=
279 | //=
280 | .=
281 | |=
282 | &=
283 | ^=
284 | >>=
285 | <<=
286 | >>>= 287 |

Assign. Performs an operation on the contents of a variable and stores the result back in the same variable. The simplest assignment operator is colon-equal (:=), which stores the result of an expression in a variable. For a description of what the other operators do, see their related entries in this table. For example, Var //= 2 performs integer division to divide Var by 2, then stores the result back in Var. Similarly, Var .= "abc" is a shorthand way of writing Var := Var . "abc".

289 |

Unlike most other operators, assignments are evaluated from right to left. Consequently, a line such as Var1 := Var2 := 0 first assigns 0 to Var2 then assigns Var2 to Var1.

290 |

If an assignment is used as the input for some other operator, its value is the variable itself. For example, the expression (Var+=2) > 50 is true if the newly-increased value in Var is greater than 50. It is also valid to combine an assignment with the reference operator, as in &(Var := "initial value").

291 |

The precedence of the assignment operators is automatically raised when it would avoid a syntax error or provide more intuitive behavior. For example: not x:=y is evaluated as not (x:=y). Also, x==y && z:=1 is evaluated as x==y && (z:=1), which short-circuits when x doesn't equal y. Similarly, ++Var := X is evaluated as ++(Var := X); and Z>0 ? X:=2 : Y:=2 is evaluated as Z>0 ? (X:=2) : (Y:=2).

292 |

The target variable can be un-set by combining a direct assignment (:=) with the unset keyword or the maybe (var?) operator. For example: Var := unset, Var1 := (Var2?).

293 |

An assignment can also target a property of an object, such as myArray.Length += n or myArray[i] .= t. When assigning to a property, the result of the sub-expression is the value being assigned, not a variable reference.

294 |
() => expr 299 |

Fat arrow function. Defines a simple function and returns a Func or Closure object. Write the function's parameter list (optionally preceded by a function name) to the left of the operator. When the function is called (via the returned reference), it evaluates the sub-expression expr and returns the result.

300 |

The following two examples are equivalent:

301 |
sumfn := Sum(a, b) => a + b
302 |
Sum(a, b) {
 303 |     return a + b
 304 | }
 305 | sumfn := Sum
306 |

In both cases, the function is defined unconditionally at the moment the script launches, but the function reference is stored in sumfn only if and when the assignment is evaluated.

307 |

If the function name is omitted and the parameter list consists of only a single parameter name, the parentheses can be omitted. The example below defines an anonymous function with one parameter a and stores its reference in the variable double:

308 |
double := a => a * 2
309 |

Variable references in expr are resolved in the same way as in the equivalent full function definition. For instance, expr may refer to an outer function's local variables (as in any nested function), in which case a new closure is created and returned each time the fat arrow expression is evaluated. The function is always assume-local, since declarations cannot be used.

310 |

Specifying a name for the function allows it to be called recursively or by other nested functions without storing a reference to the closure within itself (thereby creating a problematic circular reference). It can also be helpful for debugging, such as with Func.Name or when displayed on the debugger's call stack.

311 |

Fat arrow syntax can also be used to define shorthand properties and methods.

312 |
,

Comma (multi-statement). Commas may be used to write multiple sub-expressions on a single line. This is most commonly used to group together multiple assignments or function calls. For example: x:=1, y+=2, ++index, MyFunc(). Such statements are executed in order from left to right.

318 |

Note: A line that begins with a comma (or any other operator) is automatically appended to the line above it.

319 |

Comma is also used to delimit the parameters of a function call or control flow statement. To include a multi-statement expression in a parameter list, enclose it in an extra set of parentheses. For example, MyFn((x, y)) evaluates both x and y but passes y as the first and only parameter of MyFn.

320 |
323 |

The following types of sub-expressions override precedence/order of evaluation:

324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 335 | 336 | 337 | 340 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 358 | 359 | 360 | 361 | 365 | 366 |
ExpressionDescription
(expression) 332 |

Any sub-expression enclosed in parentheses. For example, (3 + 2) * 2 forces 3 + 2 to be evaluated first.

333 |

For a multi-statement expression, the result of the last statement is returned. For example, (a := 1, b := 2, c := 3) returns 3.

334 |

Mod()
338 | Round()
339 | Abs()

Function call. There must be no space between the function name or expression and the open parenthesis which begins the parameter list. For details, see Function Calls.

341 |

(expression) is not necessarily required to be enclosed in parentheses, but doing so may eliminate ambiguity. For example, (x.y)() retrieves a function from a property and then calls it with no parameters, whereas x.y() would implicitly pass x as the first parameter.

342 |

(expression)()

Fn(Params*)

Variadic function call. Params is an enumerable object (an object with an __Enum method), such as an Array containing parameter values.

x[y]
[a, b, c]
354 |

Item access. Get or set the __Item property (or default property) of object x with the parameter y (or multiple parameters in place of y). This typically corresponds to an array element or item within a collection, where y is the item's index or key. The item can be assigned a value by using any assignment operator immediately after the closing bracket. For example, x[y] := z.

355 |

Array literal. If the open-bracket is not preceded by a value (or a sub-expression which yields a value), it is interpreted as the beginning of an array literal. For example, [a, b, c] is equivalent to Array(a, b, c) (a, b and c are variables).

356 |

See Arrays and Maps for common usage.

357 |
{a: b, c: d} 362 |

Object literal. Create an Object. Each pair consists of a literal property name a and a property value expression b. For example, x := {a: b} is equivalent to x := Object(), x.a := b. Base may be set within the object literal, but all other properties are set as own value properties, potentially overriding properties inherited from the base object.

363 |

To use a dynamic property name, enclose the sub-expression in percent signs. For example: {%nameVar%: valueVar}.

364 |
367 | 368 |

Built-in Variables

369 |

The variables below are built into the program and can be referenced by any script.

370 |

See Built-in Variables for general information.

371 |

Table of Contents

372 | 383 |

Special Characters

384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 |
VariableDescription
A_SpaceContains a single space character.
A_TabContains a single tab character.
398 |

Script Properties

399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 423 | 424 | 425 | 426 | 431 | 432 | 433 | 434 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 448 | 449 | 450 | 451 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 474 | 475 | 476 | 477 | 478 | 479 |
VariableDescription
A_ArgsContains an array of command line parameters. For details, see Passing Command Line Parameters to a Script.
A_WorkingDir

Can be used to get or set 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.

411 |

SetWorkingDir can also be used to change the working directory.

412 |

The script's working directory defaults to A_ScriptDir, regardless of how the script was launched.

A_InitialWorkingDirThe script's initial working directory, which is determined by how it was launched. For example, if it was run via shortcut -- such as on the Start Menu -- its initial working directory is determined by the "Start in" field within the shortcut's properties.
A_ScriptDir 421 |

The full path of the directory where the current script is located. The final backslash is omitted (even for root directories).

422 |

If the script text is read from stdin rather than from file, this variable contains the initial working directory.

A_ScriptName 427 |

Can be used to get or set the default title for MsgBox, InputBox, FileSelect, DirSelect and Gui. If not set by the script, it defaults to the file name of the current script, without its path, e.g. MyScript.ahk.

428 |

If the script text is read from stdin rather than from file, this variable contains an asterisk (*).

429 |

If the script is compiled or embedded, this is the name of the current executable file.

430 |
A_ScriptFullPath 435 |

The full path of the current script, e.g. C:\Scripts\My Script.ahk

436 |

If the script text is read from stdin rather than from file, this variable contains an asterisk (*).

437 |

If the script is compiled or embedded, this is the full path of the current executable file.

438 |
A_ScriptHwndThe unique ID (HWND/handle) of the script's hidden main window.
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 ")".

447 |

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 452 |

The full path and name of the file to which A_LineNumber belongs. If the script was loaded from an external file, this is the same as A_ScriptFullPath unless the line belongs to one of the script's #Include files.

453 |

If the script was compiled based on a .bin file, this is the full path and name of the current executable file, the same as A_ScriptFullPath.

454 |

If the script is embedded, A_LineFile contains an asterisk (*) followed by the resource name; e.g. *#1

455 |
A_ThisFuncThe name of the user-defined function that is currently executing (blank if none); for example: MyFunction. See also: Name property (Func)
A_AhkVersionContains 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"). See also: #Requires and VerCompare
A_AhkPath 468 |

For non-compiled or embedded 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

469 |

For compiled scripts based on a .bin file, the value is determined by reading the installation directory from the registry and appending "\AutoHotkey.exe". If AutoHotkey is not installed, the value is blank. The example below is equivalent:

470 |
InstallDir := RegRead("HKLM\SOFTWARE\AutoHotkey", "InstallDir", "")
 471 | AhkPath := InstallDir ? InstallDir "\AutoHotkey.exe" : ""
472 |

For compiled scripts based on an .exe file, A_AhkPath contains the full path of the compiled script. This can be used in combination with /script to execute external scripts. To instead locate the installed copy of AutoHotkey, read the registry as shown above.

473 |
A_IsCompiledContains 1 if the script is running as a compiled EXE and 0 (which is considered false) if it is not.
480 |

Date and Time

481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 565 | 566 |
VariableDescription
A_YYYY 489 |

Current 4-digit year (e.g. 2004). Synonymous with A_Year.

490 |

Note: To retrieve a formatted time or date appropriate for your locale and language, use FormatTime() (time and long date) or FormatTime(, "LongDate") (retrieves long-format date).

491 |
A_MMCurrent 2-digit month (01-12). Synonymous with A_Mon.
A_DDCurrent 2-digit day of the month (01-31). Synonymous with A_MDay.
A_MMMMCurrent month's full name in the current user's language, e.g. July
A_MMMCurrent month's abbreviation in the current user's language, e.g. Jul
A_DDDDCurrent day of the week's full name in the current user's language, e.g. Sunday
A_DDDCurrent day of the week's abbreviation in the current user's language, e.g. Sun
A_WDayCurrent 1-digit day of the week (1-7). 1 is Sunday in all locales.
A_YDayCurrent 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(, "YDay0").
A_YWeekCurrent year and week number (e.g. 200453) according to ISO 8601. To separate the year from the week, use Year := SubStr(A_YWeek, 1, 4) and Week := SubStr(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_HourCurrent 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(, "h:mm:ss tt")
A_Min

Current 2-digit minute (00-59).

A_SecCurrent 2-digit second (00-59).
A_MSecCurrent 3-digit millisecond (000-999). To remove the leading zeros, follow this example: Milliseconds := A_MSec + 0.
A_Now 548 |

The current local time in YYYYMMDDHH24MISS format.

549 |

Note: Date and time math can be performed with DateAdd and DateDiff. Also, FormatTime can format the date and/or time according to your locale or preferences.

550 |
A_NowUTCThe current Coordinated Universal Time (UTC) in YYYYMMDDHH24MISS format. UTC is essentially the same as Greenwich Mean Time (GMT).
A_TickCount

The number of milliseconds that have elapsed since the system was started, up to 49.7 days. 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:

559 |
StartTime := A_TickCount
 560 | Sleep 1000
 561 | ElapsedTime := A_TickCount - StartTime
 562 | MsgBox ElapsedTime " milliseconds have elapsed."
563 |

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

564 |
567 |

Script Settings

568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 624 | 625 | 626 | 627 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 |
VariableDescription
A_IsSuspendedContains 1 if the script is suspended, otherwise 0.
A_IsPausedContains 1 if the thread immediately underneath the current thread is paused, otherwise 0.
A_IsCriticalContains 0 if Critical is off for the current thread. Otherwise it contains an integer greater than zero, namely the message-check interval being used by Critical. The current state of Critical can be saved and restored via Old_IsCritical := A_IsCritical followed later by Critical Old_IsCritical.
A_ListLinesCan be used to get or set whether to log lines. Possible values are 0 (disabled) and 1 (enabled). For details, see ListLines.
A_TitleMatchModeCan be used to get or set the title match mode. Possible values are 1, 2, 3, and RegEx. For details, see SetTitleMatchMode.
A_TitleMatchModeSpeedCan be used to get or set the title match speed. Possible values are Fast and Slow. For details, see SetTitleMatchMode.
A_DetectHiddenWindowsCan be used to get or set whether to detect hidden windows. Possible values are 0 (disabled) and 1 (enabled). For details, see DetectHiddenWindows.
A_DetectHiddenTextCan be used to get or set whether to detect hidden text in a window. Possible values are 0 (disabled) and 1 (enabled). For details, see DetectHiddenText.
A_FileEncodingCan be used to get or set the default encoding for various built-in functions. For details, see FileEncoding.
A_SendModeCan be used to get or set the send mode. Possible values are Event, Input, Play, and InputThenPlay. For details, see SendMode.
A_SendLevelCan be used to get or set the send level, an integer from 0 to 100. For details, see SendLevel.
A_StoreCapsLockModeCan be used to get or set whether to restore the state of CapsLock after a Send. Possible values are 0 (disabled) and 1 (enabled). For details, see SetStoreCapsLockMode.
A_KeyDelay
623 | A_KeyDuration
Can be used to get or set the delay or duration for keystrokes, in milliseconds. For details, see SetKeyDelay.
A_KeyDelayPlay
628 | A_KeyDurationPlay
Can be used to get or set the delay or duration for keystrokes sent via SendPlay mode, in milliseconds. For details, see SetKeyDelay.
A_WinDelayCan be used to get or set the delay for windowing functions, in milliseconds. For details, see SetWinDelay.
A_ControlDelayCan be used to get or set the delay for control-modifying functions, in milliseconds. For details, see SetControlDelay.
A_MouseDelay
645 | A_MouseDelayPlay
Can be used to get or set the mouse delay, in milliseconds. A_MouseDelay is for the traditional SendEvent mode, whereas A_MouseDelayPlay is for SendPlay. For details, see SetMouseDelay.
A_DefaultMouseSpeedCan be used to get or set the default mouse speed, an integer from 0 (fastest) to 100 (slowest). For details, see SetDefaultMouseSpeed.
A_CoordModeToolTip
654 | A_CoordModePixel
655 | A_CoordModeMouse
656 | A_CoordModeCaret
657 | A_CoordModeMenu
Can be used to get or set the area to which coordinates are to be relative. Possible values are Screen, Window, and Client. For details, see CoordMode.
A_RegViewCan be used to get or set the registry view. Possible values are 32, 64 and Default. For details, see SetRegView.
A_TrayMenu

Returns a Menu object which can be used to modify or display the tray menu.

A_AllowMainWindow

Can be used to get or set whether the script's main window is allowed to be opened via the tray icon. Possible values are 0 (forbidden) and 1 (allowed).

671 |

If the script is neither compiled nor embedded, this variable defaults to 1, otherwise this variable defaults to 0 but can be overridden by assigning it a value. Setting it to 1 also restores the "Open" menu item to the tray menu and enables the items in the main window's View menu such as "Lines most recently executed", which allows viewing of the script's source code and other info.

672 |

The following functions are always able to show the main window and select the corresponding View options when they are encountered in the script at runtime: ListLines, ListVars, ListHotkeys, and KeyHistory.

673 |

Setting it to 1 does not prevent the main window from being shown by WinShow or inspected by ControlGetText or similar methods, but it does prevent the script's source code and other info from being exposed via the main window, except when one of the functions listed above is called by the script.

A_IconHiddenCan be used to get or set whether to hide the tray icon. Possible values are 0 (visible) and 1 (hidden). For details, see #NoTrayIcon.
A_IconTip

Can be used to get or set the tray icon's tooltip text, which is displayed when the mouse hovers over it. If blank, the script's name is used instead.

682 |

To create a multi-line tooltip, use the linefeed character (`n) in between each line, e.g. "Line1`nLine2". Only the first 127 characters are displayed, and the text is truncated at the first tab character, if present.

683 |

On Windows 10 and earlier, to display tooltip text containing ampersands (&), escape each ampersand with two additional ampersands. For example, assigning "A &&& B" would display "A & B" in the tooltip.

A_IconFileBlank unless a custom tray icon has been specified via TraySetIcon -- in which case it is the full path and name of the icon's file.
A_IconNumberBlank if A_IconFile is blank. Otherwise, it's the number of the icon in A_IconFile (typically 1).
694 |

User Idle Time

695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 |
VariableDescription
A_TimeIdle 703 |

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. Physical input from the user as well as artificial input generated by any program or script (such as the Send or MouseMove functions) 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:

704 |
if A_TimeIdle > 600000
 705 |     MsgBox "Last activity was 10 minutes ago"
706 |
A_TimeIdlePhysicalSimilar to above but ignores artificial keystrokes and/or mouse clicks whenever the corresponding hook (keyboard or mouse) is installed; that is, it responds only to physical events. (This prevents simulated keystrokes and mouse clicks from falsely indicating that a user is present.) If neither hook is installed, this variable is equivalent to A_TimeIdle. If only one hook is installed, only its type of physical input affects A_TimeIdlePhysical (the other/non-installed hook's input, both physical and artificial, has no effect).
A_TimeIdleKeyboardIf the keyboard hook is installed, this is the number of milliseconds that have elapsed since the system last received physical keyboard input. Otherwise, this variable is equivalent to A_TimeIdle.
A_TimeIdleMouseIf the mouse hook is installed, this is the number of milliseconds that have elapsed since the system last received physical mouse input. Otherwise, this variable is equivalent to A_TimeIdle.
721 |

Hotkeys, Hotstrings, and Custom Menu Items

722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 |
VariableDescription
A_ThisHotkey

The most recently executed hotkey or non-auto-replace hotstring (blank if none), e.g. #z. This value will change if the current thread is interrupted by another hotkey or hotstring, so it is generally better to use the parameter ThisHotkey when available.

730 |

When a hotkey is first created -- either by the Hotkey function or the double-colon syntax in the script -- its key name and the ordering of its modifier symbols becomes the permanent name of that hotkey, shared by all variants of the hotkey.

731 |

When a hotstring is first created -- either by the Hotstring function or a double-colon label in the script -- its trigger string and sequence of option characters becomes the permanent name of that hotstring.

732 |
A_PriorHotkeySame as above except for the previous hotkey. It will be blank if none.
A_PriorKeyThe name of the last key which was pressed prior to the most recent key-press or key-release, or blank if no applicable key-press can be found in the key history. All input generated by AutoHotkey scripts is excluded. For this variable to be of use, the keyboard or mouse hook must be installed and key history must be enabled.
A_TimeSinceThisHotkeyThe number of milliseconds that have elapsed since A_ThisHotkey was pressed. It will be blank whenever A_ThisHotkey is blank.
A_TimeSincePriorHotkeyThe number of milliseconds that have elapsed since A_PriorHotkey was pressed. It will be blank whenever A_PriorHotkey is blank.
A_EndCharThe 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.
A_MaxHotkeysPerIntervalCan be used to get or set the maximum number of hotkeys that can be pressed within the interval defined by A_HotkeyInterval without triggering a warning dialog. For details, see A_MaxHotkeysPerInterval.
A_HotkeyIntervalCan be used to get or set the length of the interval used by A_MaxHotkeysPerInterval, in milliseconds.
A_HotkeyModifierTimeoutCan be used to get or set the timeout affecting the behavior of Send with hotkey modifiers Ctrl, Alt, Win, and Shift. For details, see A_HotkeyModifierTimeout.
767 |

Operating System and User Info

768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 778 | 779 | 780 | 781 | 784 | 785 | 786 | 787 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 827 | 828 | 829 | 830 | 834 | 835 | 836 | 837 | 841 | 842 | 843 | 844 | 848 | 849 | 850 | 851 | 855 | 856 | 857 | 858 | 862 | 863 | 864 | 865 | 869 | 870 | 871 | 872 | 876 | 877 | 878 | 879 | 883 | 884 | 885 | 886 | 890 | 891 | 892 | 893 | 897 | 898 | 899 | 900 | 904 | 905 | 906 | 907 | 910 | 911 | 912 | 914 | 922 | 923 | 924 | 925 | 927 | 928 |
VariableDescription
A_ComSpec

Contains the same string as the ComSpec environment variable, which is usually the full path to the command prompt executable (cmd.exe). Often used with Run/RunWait. For example:

776 |
C:\Windows\system32\cmd.exe
777 |
A_Temp

The full path and name of the folder designated to hold temporary files. It is retrieved from one of the following locations (in order): 1) the environment variables TMP, TEMP, or USERPROFILE; 2) the Windows directory. For example:

782 |
C:\Users\<UserName>\AppData\Local\Temp
783 |
A_OSVersion 788 |

The version number of the operating system, in the format "major.minor.build". For example, Windows 7 SP1 is 6.1.7601.

789 |

Applying compatibility settings in the AutoHotkey executable or compiled script's properties causes the OS to report a different version number, which is reflected by A_OSVersion.

790 |
A_Is64bitOSContains 1 (true) if the OS is 64-bit or 0 (false) if it is 32-bit.
A_PtrSizeContains the size of a pointer, in bytes. This is either 4 (32-bit) or 8 (64-bit), depending on what type of executable (EXE) is running the script.
A_LanguageThe system's default language, which is one of these 4-digit codes.
A_ComputerNameThe name of the computer as seen on the network.
A_UserNameThe logon name of the user who launched this script.
A_WinDirThe Windows directory. For example: C:\Windows
A_ProgramFiles 819 |

The Program Files directory (e.g. C:\Program Files or C:\Program Files (x86)). This is usually the same as the ProgramFiles environment variable.

820 |

On 64-bit systems (and not 32-bit systems), the following applies:

821 |
    822 |
  • If the executable (EXE) that is running the script is 32-bit, A_ProgramFiles returns the path of the "Program Files (x86)" directory.
  • 823 |
  • For 32-bit processes, the ProgramW6432 environment variable contains the path of the 64-bit Program Files directory. On Windows 7 and later, it is also set for 64-bit processes.
  • 824 |
  • The ProgramFiles(x86) environment variable contains the path of the 32-bit Program Files directory.
  • 825 |
826 |
A_AppData 831 |

The full path and name of the folder containing the current user's application-specific data. For example:

832 |
C:\Users\<UserName>\AppData\Roaming
833 |
A_AppDataCommon 838 |

The full path and name of the folder containing the all-users application-specific data. For example:

839 |
C:\ProgramData
840 |
A_Desktop 845 |

The full path and name of the folder containing the current user's desktop files. For example:

846 |
C:\Users\<UserName>\Desktop
847 |
A_DesktopCommon 852 |

The full path and name of the folder containing the all-users desktop files. For example:

853 |
C:\Users\Public\Desktop
854 |
A_StartMenu 859 |

The full path and name of the current user's Start Menu folder. For example:

860 |
C:\Users\<UserName>\AppData\Roaming\Microsoft\Windows\Start Menu
861 |
A_StartMenuCommon 866 |

The full path and name of the all-users Start Menu folder. For example:

867 |
C:\ProgramData\Microsoft\Windows\Start Menu
868 |
A_Programs 873 |

The full path and name of the Programs folder in the current user's Start Menu. For example:

874 |
C:\Users\<UserName>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
875 |
A_ProgramsCommon 880 |

The full path and name of the Programs folder in the all-users Start Menu. For example:

881 |
C:\ProgramData\Microsoft\Windows\Start Menu\Programs
882 |
A_Startup 887 |

The full path and name of the Startup folder in the current user's Start Menu. For example:

888 |
C:\Users\<UserName>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
889 |
A_StartupCommon 894 |

The full path and name of the Startup folder in the all-users Start Menu. For example:

895 |
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
896 |
A_MyDocuments 901 |

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 (e.g. it would contain M: rather than M:\). For example:

902 |
C:\Users\<UserName>\Documents
903 |
A_IsAdmin

Contains 1 if the current user has admin rights, otherwise 0.

908 |

To have the script restart itself as admin (or show a prompt to the user requesting admin), use Run *RunAs. However, note that running the script as admin causes all programs launched by the script to also run as admin. For a possible alternative, see the FAQ.

909 |

A_ScreenWidth
913 | A_ScreenHeight

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

915 |

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

916 |

To instead discover the width and height of the entire desktop (even if it spans multiple monitors), use the following example:

917 |
 918 | VirtualWidth := SysGet(78)
 919 | VirtualHeight := SysGet(79)
 920 | 
921 |

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_ScreenDPI

Number of pixels per logical inch along the screen width. This is typically 96 if the display scale is set to 100 %. In a system with multiple displays, this value corresponds to the primary display at the time the program started.

926 |

See also DPI Scaling and the GUI's -DPIScale option.

929 |

Misc.

930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 953 | 954 | 955 | 956 | 958 | 959 | 960 | 961 | 964 | 965 |
VariableDescription
A_ClipboardCan be used to get or set the contents of the OS's clipboard. For details, see A_Clipboard.
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 classified as Unknown.

A_EventInfo

Contains additional information about the following events:

946 | 951 |

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

952 |

A_EventInfo can also be set by the script, but can only accept unsigned integers within the range available to pointers (32-bit or 64-bit depending on the version of AutoHotkey).

A_LastError

This is usually the result from the OS's GetLastError() function after the script calls certain functions, including DllCall, Run/RunWait, File/Ini/Reg functions (where documented) and possibly others. A_LastError is a number between 0 and 4294967295 (always formatted as decimal, not hexadecimal). Zero (0) means success, but any other number means the call failed. Each number corresponds to a specific error condition. See OSError for how to get the localized error description text, or search www.microsoft.com for "system error codes" to get a list. A_LastError is a per-thread setting; that is, interruptions by other threads cannot change it.

957 |

Assigning a value to A_LastError also causes the OS's SetLastError() function to be called.

True
False

Contain 1 and 0. They can be used to make a script more readable. For details, see Boolean Values.

962 |

These are actually keywords, not variables.

963 |
966 |

Loop

967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 |
VariableDescription
A_IndexCan be used to get or set the number of the current loop iteration (a 64-bit integer). It contains 1 the first time the loop's body is executed. For the second time, it contains 2; and so on. If an inner loop is enclosed by an outer loop, the inner loop takes precedence. A_Index works inside all types of loops, but contains 0 outside of a loop. For counted loops such as Loop, changing A_Index affects the number of iterations that will be performed.
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_LoopReadLineSee file-reading loop.
A_LoopFieldSee parsing loop.
993 | 994 |

Variable Capacity and Memory

995 | 1001 | 1002 | 1003 | -------------------------------------------------------------------------------- /docs/howto/Install.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | How to Install AutoHotkey | AutoHotkey v2 9 | 10 | 11 | 12 | 13 |

How to Install AutoHotkey

14 | 15 |

If you have not already downloaded AutoHotkey, you can get it from one of the following locations:

16 | 20 |

Note: This tutorial is for AutoHotkey v2.

21 |

The main download has a filename like AutoHotkey_2.0_setup.exe. Run this file to begin installing AutoHotkey.

22 |

If you are not the administrator of your computer, you may need to select the Current user option.

23 |

Otherwise, the recommended options are already filled in, so just click Install.

24 |

For users of v1: AutoHotkey v2 includes a launcher which allows multiple versions of AutoHotkey to co-exist while sharing one file extension (.ahk). Installing AutoHotkey v1 and v2 into different directories is not necessary and is currently not supported.

25 |

If you are installing for all users, you will need to provide administrator consent in the standard UAC prompt that appears (in other words, click Yes).

26 |

If there were no complications, AutoHotkey is now installed!

27 |

Once installation completes, the Dash is shown automatically.

28 | 29 |

Next Steps

30 |

Using the Program covers the basics of how to use AutoHotkey.

31 |

Consider installing an editor with AutoHotkey support to make editing and testing scripts much easier.

32 |

The documentation contains many examples, which you can test out as described in How to Run Example Code.

33 |

These tutorials focus on specific common tasks:

34 | 39 |

AutoHotkey Beginner Tutorial by tidbit covers a range of topics.

40 | 41 |

Problems?

42 |

If you have problems installing AutoHotkey, please try searching for your issue on the forum or start a new topic to get help or report the issue.

43 | 44 |

Zip Installer

45 |

AutoHotkey can also be installed from the zip download.

46 |
    47 |
  1. Open the zip file using File Explorer (no extraction necessary), or extract the contents of the zip file to a temporary directory.
  2. 48 |
  3. Run Install.cmd.
  4. 49 |
  5. If you receive a prompt like "The publisher could not be verified. Are you sure...?", click Run.
  6. 50 |
  7. Continue installation as described above.
  8. 51 |
52 | 53 |

Security Prompts

54 |

You may receive one or more security prompts, depending on several factors.

55 | 56 |

Web Browsers

57 |

Common web browsers may show a warning like "AutoHotkey_2.0_setup.exe was blocked because it could harm your device." This is a generic warning that applies to any executable file type that isn't "commonly downloaded". In other words, it often happens for new releases of software, until more users have downloaded that particular version.

58 |

To keep the download, methods vary between browsers. Look for a menu button near where downloads are shown, or try right clicking on the blocked download.

59 |

Sometimes the download might be blocked due to an antivirus false-positive; in that case, see Antivirus below.

60 |

The Google Safe Browsing service (also used by other browsers) has been known to show false warnings about AutoHotkey. For details, see Safe Browsing.

61 | 62 |

SmartScreen

63 |

Microsoft Defender SmartScreen may show a prompt like "Windows protected your PC". This is common for software from open source developers and Independent Software Vendors (ISV), especially soon after the release of each new version. The following blog article by Louis Kessler describes the problem well: That’s not very Smart of you, Microsoft

64 |

To continue installation, select More info and then Run anyway.

65 | 66 |

Antivirus

67 |

If your antivirus flags the download as malicious, please refer to the following:

68 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /docs/howto/ManageWindows.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | How to Manage Windows | AutoHotkey v2 9 | 10 | 11 | 12 | 13 |

How to Manage Windows

14 |

One of the easiest and most useful things AutoHotkey can do is allow you to create keyboard shortcuts (hotkeys) that manipulate windows. A script can activate, close, minimize, maximize, restore, hide, show or move almost any window. This is done by calling the appropriate Win function, specifying the window by title or some other criteria:

15 |
Run "notepad.exe"
 16 | WinWait "Untitled - Notepad"
 17 | WinActivate "Untitled - Notepad"
 18 | WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, "Untitled - Notepad"
19 |

This example should open a new Notepad window and then move it to fill a portion of the primary screen (¼ of its width and ½ its height). To learn how to try it out, refer to How to Run Example Code.

20 | 21 |

We won't go into detail about many of the functions for manipulating windows, since there's not much to it. For instance, to minimize a window instead of activating it, replace WinActivate with WinMinimize. See Win functions for a list of functions which can manipulate windows or retrieve information.

22 |

Most of this tutorial is about ways to identify which window you want to operate on, since that is often the most troublesome part. For instance, there are a number of problems with the example above:

23 | 29 |

We'll address these issues one at a time, after covering a few basics.

30 |

Tip: AutoHotkey comes with a script called Window Spy, which can be used to confirm the title, class and process name of a window. The class and process name are often used when identifying a window by title alone is not feasible. You can find Window Spy in the script's tray menu or the AutoHotkey Dash.

31 | 32 |

Title Matching

33 |

There are a few things to know when specifying a window by title:

34 | 39 |

See Matching Behaviour for more details.

40 | 41 |

Active Window

42 |

To refer to the active window, use the letter "A" in place of a window title. For example, this minimizes the active window:

43 |
WinMinimize "A"
44 | 45 |

Last Found Window

46 |

When WinWait, WinExist, WinActive, WinWaitActive or WinWaitNotActive find a matching window, they set it as the last found window. Most window functions allow the window title (and related parameters) to be omitted, and will in that case default to the last found window. For example:

47 |
Run "notepad.exe"
 48 | WinWait "Untitled - Notepad"
 49 | WinActivate
 50 | WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2
51 |

This saves repeating the window title, which saves a little of your time, makes the script easier to update if the window title needs to be changed, and might make the code easier to read. It makes the script more reliable by ensuring that it operates on the same window each time, even when there are multiple matching windows, or if the window title changes after the window is "found". It also makes the script execute more efficiently, but not by much.

52 | 53 |

Window Class

54 |

A window class is a set of attributes that is used as a template to create a window. Often the name of a window's class is related to the app or the purpose of the window. A window's class never changes while the window exists, so we can often use it to identify a window when identifying by title is impractical or impossible.

55 |

For example, instead of the window title "Untitled - Notepad", we can use the window's class, which in this case happens to be "Notepad" regardless of the system language:

56 |
Run "notepad.exe"
 57 | WinWait "ahk_class Notepad"
 58 | WinActivate
 59 | WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2
60 |

A window class is distinguished from a title by using the word "ahk_class" as shown above. To combine multiple criteria, list the window title first. For example: "Untitled ahk_class Notepad".

61 |

Related: ahk_class

62 | 63 |

Process Name/Path

64 |

Windows can be identified by the process which created them by using the word "ahk_exe" followed by the name or path of the process. For example:

65 |
Run "notepad.exe"
 66 | WinWait "ahk_exe notepad.exe"
 67 | WinActivate
 68 | WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2
69 |

Related: ahk_exe

70 | 71 |

Process ID (PID)

72 |

Each process has an ID number which remains unique until the process exits. We can use this to make our Notepad example more reliable by ensuring that it ignores any Notepad window except the one that is created by the new process:

73 |
Run "notepad.exe",,, &notepad_pid
 74 | WinWait "ahk_pid " notepad_pid
 75 | WinActivate
 76 | WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2
77 |

We need three commas in a row; two of them are just to skip the unused WorkingDir and Options parameters of the Run function, since the one we want (OutputVarPID) is the fourth parameter.

78 |

Ampersand (&) is the reference operator. This is used to pass the notepad_pid variable to the Run function by reference (in other words, to pass the variable itself instead of its value), allowing the function to assign a new value to the variable. Then notepad_pid becomes a placeholder for the actual process ID.

79 |

The string "ahk_pid " is concatenated with the process ID contained by the notepad_pid variable by simply writing them in sequence, separated by whitespace. The result is a string like "ahk_pid 1040", but the number isn't predictable.

80 |

If the new process might create multiple windows, a window title and other criteria can be combined by delimiting them with spaces. The window title must always come first. For example: "Untitled ahk_class Notepad ahk_pid " notepad_pid.

81 |

Related: ahk_pid

82 | 83 |

Window ID (HWND)

84 |

Each window has an ID number which remains unique until the window is destroyed. In programming parlance, this is known as a "window handle" or HWND. Although not as convenient as using the last found window, the window's ID can be stored in a variable so that the script can refer to it by a name of your choice, even if the title changes. There can be only one last found window at a time, but you can use as many window IDs as you can make up variable names for (or you can use an array).

85 |

A window ID is returned by WinWait, WinExist or WinActive, or can come from some other sources. The Notepad example can be rewritten to take advantage of this:

86 |
Run "notepad.exe"
 87 | notepad_id := WinWait("Untitled - Notepad")
 88 | WinActivate notepad_id
 89 | WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, notepad_id
90 |

This assigns the return value of WinWait to the variable "notepad_id". In other words, when WinWait finds the window, it produces the window's ID as its result, and the script then stores this result in the variable. "notepad_id" is just a name that I've made up for this example; you can use whatever variable names make sense to you (within certain constraints).

91 |

Notice that I added parentheses around the window title, immediately following the function name. Parentheses can be omitted in function call statements (that is, function calls at the very beginning of the line), but in that case you cannot get the function's return value.

92 |

The script can also retain the variable notepad_id for later use, such as to close or reactivate the window or move it somewhere else.

93 |

Related: ahk_id

94 | 95 |

Timeout

96 |

By default, WinWait will wait indefinitely for a matching window to appear. You can determine whether this has happened by opening the script's main window via the tray icon (unless you've disabled it). The window normally opens on ListLines view by default. If WinWait is still waiting, it will appear at the very bottom of the list of lines, followed by the number of seconds since it began waiting. The number doesn't update unless you select "Refresh" from the View menu.

97 |

Try running this example and opening the main window as described above:

98 |
WinWait "Untitled - Notpad"  ; (intentional typo)
99 |

If the script is stuck waiting for a window, you will usually need to exit or reload the script to get it unstuck. To prevent that from happening in the first place (or happening again), you can use the Timeout parameter of WinWait. For example, this will wait at most 5 seconds for the window to appear:

100 |
Run "notepad.exe",,, &notepad_pid
101 | if WinWait("ahk_pid " notepad_pid,, 5)
102 | {
103 |     WinActivate
104 |     WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2
105 | }
106 |

The block below the if statement is executed only if WinWait finds a matching window. If it times out, the block is skipped and execution continues after the closing brace (if there is any code after it).

107 |

Note that the parentheses after "WinWait" are required when we want to use the function's result in an expression (such as the condition of an if statement). You can think of the function call itself as a substitute for the result of the function. For instance, if WinWait finds a match before timing out, the result is non-zero. if 1 would execute the block below the if statement, whereas if 0 would skip it.

108 |

Another way to write it is to return early (in other words, abort) if the wait times out. For example:

109 |
Run "notepad.exe",,, &notepad_pid
110 | if !WinWait("ahk_pid " notepad_pid,, 5)
111 |     return
112 | WinActivate
113 | WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2
114 |

The result is inverted by applying the logical-not operator (! or not). If WinWait times out, its result is 0. The result of !0 is 1, so when WinWait times out, the if statement executes the return.

115 |

WinWait's result is actually the ID of the window (as described above) or zero if it timed out. If you also want to refer to the window by ID, you can assign the result to a variable instead of using it directly in the if statement:

116 |
Run "notepad.exe",,, &notepad_pid
117 | notepad_id := WinWait("ahk_pid " notepad_pid,, 5)
118 | if notepad_id
119 | {
120 |     WinActivate notepad_id
121 |     WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, notepad_id
122 | }
123 |

To avoid repeating the variable name, you can both assign the result to a variable and check that it is non-zero (true) at the same time:

124 |
Run "notepad.exe",,, &notepad_pid
125 | if notepad_id := WinWait("ahk_pid " notepad_pid,, 2)
126 | {
127 |     WinActivate notepad_id
128 |     WinMove 0, 0, A_ScreenWidth/4, A_ScreenHeight/2, notepad_id
129 | }
130 |

In that case, be careful not to confuse := (assignment) with = or == (comparison). For example, if myvar := 0 assigns a new value and gives the same result every time (false), whereas if myvar = 0 compares a previously-assigned value with 0.

131 | 132 |

Expressions (Math etc.)

133 |

When you want to move a window, it is often useful to move or size it relative to its previous position or size, which can be retrieved by using the WinGetPos function. For example, the following set of hotkeys can be used to move the active window by 10 pixels in each direction, by holding RCtrl and pressing the arrow keys:

134 |
>^Left::    MoveActiveWindowBy(-10,   0)
135 | >^Right::   MoveActiveWindowBy(+10,   0)
136 | >^Up::      MoveActiveWindowBy(  0, -10)
137 | >^Down::    MoveActiveWindowBy(  0, +10)
138 | 
139 | MoveActiveWindowBy(x, y) {
140 |     WinExist "A"  ; Make the active window the Last Found Window  
141 |     WinGetPos &current_x, &current_y
142 |     WinMove current_x + x, current_y + y
143 | }
144 |

The example defines a function to avoid repeating code several times. x and y become placeholders for the two numbers specified in each hotkey. WinGetPos stores the current position in current_x and current_y, which we then add to x and y.

145 |

Simple expressions such as this should look fairly familiar. For more details, see Expressions; but be aware there is a lot of detail that you probably won't need to learn immediately.

146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/howto/RunExamples.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | How to Run Example Code | AutoHotkey v2 9 | 10 | 11 | 12 | 13 |

How to Run Example Code

14 |

The easiest way to get started quickly with AutoHotkey is to take example code, try it out and adapt it to your needs.

15 |

Within this documentation, there are many examples in code blocks such as the one below.

16 |
MsgBox "Hello, world!"
17 |

Most (but not all) examples can be executed as-is to demonstrate their effect. There are generally two ways to do this:

18 |
    19 |
  1. Download the code as a file. If your browser supports it, you can download any code block (such as the one above) as a script file by clicking the button which appears in the top-right of the code block when you hover your mouse over it.
  2. 20 |
  3. Copy the code into a file. It's usually best to create a new file, so existing code won't interfere with the example code. Once the file has been created, open it for editing and copy-paste the code.
  4. 21 |
22 |

Run the file: Once you have the code in a script (.ahk) file, running it is usually just a case of double-clicking the file; but there are other methods.

23 | 24 |

Assigning Hotkeys

25 |

Sometimes testing code is easier if you assign it to a hotkey first. For example, consider this code for maximizing the active window:

26 |
WinMaximize "A"
27 |

If you save this into a file and run the file by double-clicking it, it will likely maximize the File Explorer window which contains the file. You can instead assign it to a hotkey to test its effect on whatever window you want. For example:

28 |
^1::WinMaximize "A"
29 |

Now you can activate your test subject and press Ctrl+1 to maximize it.

30 |

For more about hotkeys, see How to Write Hotkeys.

31 | 32 |

Bailing Out

33 |

If you make a mistake in a script, sometimes it can make the computer harder to use. For example, the hotkey n:: would activate whenever you press N and would prevent you from typing that character. To undo this, all you need to do is exit the script. You can do that by right clicking on the script's tray icon and selecting Exit.

34 |

Keys can get "stuck down" if you send a key-down and don't send a key-up. In that case, exiting the script won't necessarily be enough, as the operating system still thinks the key is being held down. Generally you can "unstick" the key by physically pressing it.

35 |

If a script gets into a runaway loop or is otherwise difficult to stop, you can log off or shut down the computer as a last resort. When you log off, all apps running under your session are terminated, including AutoHotkey. In some cases you might need to click "log off anyway" or "shut down anyway" if a script or program is preventing shutdown.

36 | 37 |

Reloading

38 |

After you've started the script, changes to the script's file do not take effect automatically. In order to make them take effect, you must reload the script. This can be done via the script's tray icon or the Reload function, which you can call from a hotkey. In many cases it can also be done by simply running the script again, but that depends on the script's #SingleInstance setting.

39 | 40 |

The Right Tools

41 |

Learning to code is often a repetitious process; take some code, make a small change, test the code, rinse and repeat. This process is quicker and more productive if you use a text editor with support for AutoHotkey. Support varies between editors, but the most important features are (in my opinion):

42 | 46 |

For recommendations, try Editors with AutoHotkey Support or the Editors subforum.

47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /docs/howto/RunPrograms.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | How to Run Programs | AutoHotkey v2 9 | 10 | 11 | 12 | 13 |

How to Run Programs

14 |

One of the easiest and most useful things AutoHotkey can do is allow you to create keyboard shortcuts (hotkeys) that launch programs.

15 |

Programs are launched by calling the Run function, passing the command line of the program as a parameter:

16 |
Run "C:\Windows\notepad.exe"
17 |

This example launches Notepad. To learn how to try it out, refer to How to Run Example Code.

18 |

At this stage, we haven't defined a hotkey (in other words, assigned a keyboard shortcut), so the instructions are carried out immediately. In this case, the script has nothing else to do, so it automatically exits. If you prefer to make useful hotkeys while learning, check out How to Write Hotkeys first.

19 |

Note: Run can also be used to open documents, folders and URLs.

20 |

To launch other programs, simply replace the path in the example above with the path of the program you wish to launch. Some programs have their paths registered with the system, in which case you can get away with just passing the filename of the program, with or (sometimes) without the ".exe" extension. For example:

21 |
Run "notepad"
22 | 23 |

Command-line Parameters

24 |

If the program accepts command-line parameters, they can be passed as part of the Run function's first parameter. The following example should open license.txt in Notepad:

25 |
 26 | Run "notepad C:\Program Files\AutoHotkey\license.txt"
 27 | 
28 |

Note: This example assumes AutoHotkey is installed in the default location, and will show an error otherwise.

29 |

Simple, right? Now suppose that we want to open the file in WordPad instead of Notepad.

30 |
Run "wordpad C:\Program Files\AutoHotkey\license.txt"
31 |

Run this code and see what you can learn from the result.

32 |

Okay, so the new code doesn't work. Hopefully you didn't dismiss the error dialog immediately; error dialogs are a normal part of the process of coding, and often contain very useful information. This one should tell us a few things:

33 | 38 |

But why did Notepad work? Running either "notepad" or "wordpad" on its own works, but for different reasons. Unlike notepad.exe, wordpad.exe cannot be found by checking each directory listed in the PATH environment variable. It can be located by a different method, which requires the Run function to separate the program name and parameters.

39 |

So in this case, the Run function needs a bit of help, in any or all of the following forms:

40 | 45 |

For now, go with the easiest option:

46 |
Run "wordpad.exe C:\Program Files\AutoHotkey\license.txt"
47 |

Now WordPad launches, but it shows an error: "C:\Program" wasn't found.

48 | 49 |

Quote Marks and Spaces

50 |

Often when passing command-line parameters to a program, it is necessary to enclose each parameter in quote marks if the parameter contains a space. This wasn't necessary with Notepad, but Notepad is an exception to the general rule. A naive attempt at a solution might be to simply add more quote marks:

51 |
Run "wordpad.exe "C:\Program Files\AutoHotkey\license.txt""
52 |

But this won't work, because by default, quote marks are used to denote the start and end of literal text. So how do we include a literal quote mark within the command line, rather than having it end the command line?

53 |

Method 1: Precede each literal quote mark with ` (back-tick, back-quote or grave accent). This is known as an escape sequence. The quote mark is then included in the command line (i.e. the string that is passed to the Run function), whereas the back-tick, having fulfilled its purpose, is left out.

54 |
Run "wordpad.exe `"C:\Program Files\AutoHotkey\license.txt`""
55 |

Method 2: Enclose the command line in single quotes instead of double quotes.

56 |
Run 'wordpad.exe "C:\Program Files\AutoHotkey\license.txt"'
57 |

Of course, in that case any literal single quotes (or apostrophes) in the text would need to be escaped (`').

58 |

How you write the code affects which quote marks actually make it through to the Run function. In the two examples above, the Run function receives the string wordpad.exe "C:\Program Files\AutoHotkey\license.txt". The Run function either splits this into a program name and parameters (everything else) or leaves that up to the system. In either case, how the remaining quote marks are interpreted depends entirely on the target program.

59 |

Many programs treat a quote mark as part of the parameter if it is preceded by a backslash. For example, Run 'my.exe "A\" B' might produce a parameter with the value A" B instead of two parameters. This is up to the program, and can usually be avoided by doubling the backslash, as in Run 'my.exe "A\\" B', which usually produces two parameters (A\ and B).

60 |

Most programs interpret quote marks as a sort of toggle, switching modes between "space ends the parameter" and "space is included in the parameter". In other words, Run 'my.exe "A B"' is generally equivalent to Run 'my.exe A" "B'. So another way to avoid issues with slashes is to quote the spaces instead of the entire parameter, or end the quote before the slash, as in Run 'my.exe "A"\ B'.

61 | 62 |

Including Variables

63 |

Often a command line needs to include some variables. For example, the location of the "Program Files" directory can vary between systems, and a script can take this into account by using the A_ProgramFiles variable. If the variable contains the entire command line, simply pass the variable to the Run function to execute it.

64 |
Run A_ComSpec  ; Start a command prompt (almost always cmd.exe).
 65 | Run A_MyDocuments  ; Open the user's Documents folder.
66 |

Including a variable inside a quoted string won't work; instead, we use concatenation to join literal strings together with variables. For example:

67 |
Run 'notepad.exe "' A_MyDocuments '\AutoHotkey.ahk"'
68 |

Another method is to use Format to perform substitution. For example:

69 |
Run Format('notepad.exe "{1}\AutoHotkey.ahk"', A_MyDocuments)
70 |

Note: Format can perform additional formatting at the same time, such as padding with 0s or spaces, or formatting numbers as hexadecimal instead of decimal.

71 | 72 |

Run's Parameters

73 |

Aside from the command line to execute, the Run function accepts a few other parameters that affect its behaviour.

74 |

WorkingDir specifies the working directory for the new process. If you specify a relative path for the program, it is relative to this directory. Relative paths in command line parameters are often also relative to this directory, but that depends on the program.

75 |
Run "cmd", "C:\"  ; Open a command prompt at C:\
76 |

Options can often be used to run a program minimized or hidden, instead of having it pop up on screen, but some programs ignore it.

77 |

OutputVarPID gives you the process ID, which is often used with WinWait or WinWaitActive and ahk_pid to wait until the program shows a window on screen, or to identify one of its windows. For example:

78 |
Run "mspaint",,, &pid
 79 | WinWaitActive "ahk_pid " pid
 80 | Send "^e"  ; Ctrl+E opens the Image Properties dialog.
81 | 82 |

System Verbs

83 |

System verbs are actions that the system or applications register for specific file types. They are normally available in the file's right-click menu in Explorer, but their actual names don't always match the text displayed in the menu. For example, AutoHotkey scripts have an "edit" verb which opens the script in an editor, and (if Ahk2Exe is installed) a "compile" verb which compiles the script.

84 |

"Edit" is one of a list of common verbs that Run recognizes by default, so can be used by just writing the word followed by a space and the filename, as follows:

85 |
Run 'edit ' A_ScriptFullPath  ; Generally equivalent to Edit
86 |

Any verb registered with the system can be executed by using the * prefix as shown below:

87 |
Run '*Compile-Gui ' A_ScriptFullPath
88 |

If Ahk2Exe is installed, this opens the Ahk2Exe Gui with the current script pre-selected.

89 | 90 |

Environment

91 |

Whenever a new process starts, it generally inherits the environment of the process which launched it (the parent process). This basically means that all of the script's environment variables are inherited by any program that you launch with Run.

92 |

In some cases, environment variables can be set with EnvSet before launching the program to affect its behaviour, or pass information to it. A script can also use EnvGet to read environment variables that it might have inherited from its parent process.

93 |

On 64-bit systems, the script's own environment heavily depends on whether the EXE running it is 32-bit or 64-bit. 32-bit processes not only have different environment variables, but also have file system redirection in place for compatibility reasons.

94 |
Run "cmd /k set pro"
95 |

The example above shows a command prompt which prints all environment variables beginning with "pro". If you run it from a 32-bit script, you will likely see PROCESSOR_ARCHITECTURE=x86 and ProgramFiles=C:\Program Files (x86). Although the title shows something like "C:\Windows\System32\cmd.exe", this is a lie; it is actually the 32-bit version, which really resides in "C:\Windows\SysWow64\cmd.exe".

96 |

In simple cases like this, the easiest way to bypass the redirection of "System32" is to use "SysNative" instead. However, this only works from a 32-bit process on a 64-bit system, so must be done conditionally. When the following example is executed on a 64-bit system, it shows a 64-bit command prompt even if the script is 32-bit:

97 |
if FileExist(A_WinDir "\SysNative")
 98 |     Run A_WinDir "\SysNative\cmd.exe /k set pro"
 99 | else
100 |     Run "cmd /k set pro"
101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /docs/howto/SendKeys.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | How to Send Keystrokes | AutoHotkey v2 9 | 10 | 11 | 12 | 13 |

How to Send Keystrokes

14 |
Send "Hello, world{!}{Left}^+{Left}"
15 |

Sending keystrokes (or keys for short) is the most common method of automating programs, because it is the one that works most generally. More direct methods tend to work only in particular types of app.

16 |

There are broadly two parts to learning how to send keys:

17 |
    18 |
  1. How to write the code so that the program knows which keys you want to send.
  2. 19 |
  3. How to use the available modes and options to get the right end result.
  4. 20 |
21 |

It is important to understand that sending a key does not perfectly replicate the act of physically pressing the key, even if you slow it down to human speeds. But before we go into that, we'll cover some basics.

22 | 23 |

Trying the examples

24 |

If you run an example like SendText "Hi!", the text will be immediately sent to the active (focused) window, which might be less than useful depending on how you ran the example. It's usually better to define a hotkey, run the example to load it up, and press the hotkey when you want to test its effect. Some of the examples below will use numbered hotkeys like ^1:: (Ctrl and a number, so you can try multiple examples at once if there are no duplicates), but you can change that to whatever suits you.

25 |

To learn how to customize the hotkeys or create your own, see How to Write Hotkeys.

26 |

If you're not sure how to try out the examples, see How to Run Example Code.

27 | 28 |

How to write the code

29 |

When sending keys, you generally want to either send a key or key combination for its effect (like Ctrl+C to copy to the clipboard), or type some text. Typing text is simpler, so we'll start there: just call the SendText function, passing it the exact text you want to send.

30 |
^1::SendText "To Whom It May Concern"
31 |

Technically SendText actually sends Unicode character packets and not keystrokes, and that makes it much more reliable for characters that are normally typed with a key-combination like Shift+2 or AltGr+a.

32 | 33 |

Rules of quoted strings

34 |

SendText sends the text verbatim, but keep in mind the rules of the language. For instance, literal text must be enclosed in quote marks (double " or single '), and the quote marks themselves aren't "seen" by the SendText function. To send a literal quote mark, you can enclose it in the opposite type of quote mark. For example:

35 |
^2::SendText 'Quote marks are also known as "quotes".'
36 |

Alternatively, use an escape sequence. Inside a quoted string, `" translates to a literal " and `' translates to a literal '. For example:

37 |
^3::{
 38 |     SendText "Double quote (`")"
 39 |     SendText 'Single quote (`')'
 40 | }
41 |

You can also alternate the quote marks:

42 |
^4::SendText 'Double (") and' . " single (') quote"
43 |

The two strings are joined together (concatenated) before being passed to the SendText function. The dot (.) can be omitted, but that makes it harder to see where one ends and the other begins.

44 |

As you've seen above, the escape character ` (known by backquote, backtick, grave accent and other names) has special meaning, so if you want to send that character literally (or send the corresponding key), you need to double it up, as in Send "``". Other common escape sequences include `n for linefeed (Enter) and `t for tab. See Escape Sequences for more.

45 | 46 |

Sending keys and key combinations

47 |

SendText is best for sending text verbatim, but it can't send keys that don't produce text, like Left or Home. Send, SendInput, SendPlay, SendEvent and ControlSend can send both text and key combinations, or keys which don't produce text. To do all of this, they add special meaning to the following symbols: ^!+#{}

48 |

The first four symbols correspond to the standard modifier keys, Ctrl (^), Alt (!), Shift (+) and Win (#). They can be used in combination, but otherwise affect only the next key.

49 |

To send a key by name, or to send any one of the above symbols literally, enclose it in braces. For example:

50 | 55 |

When you press Ctrl+Shift+", the following example sends two quote marks and then moves the insertion point to the left, ready to type inside the quote marks:

56 |
^+"::Send '""{Left}'
57 |

For any single character other than ^!+#{}, Send translates it to the corresponding key combination and presses and releases that combination. For example, Send "aB" presses and releases A and then presses and releases Shift+B. Similarly, any key name enclosed in braces is pressed and released by default. For example, Send "{Ctrl}a" would press and release Ctrl, then press and release A; probably not what you want.

58 |

To only press (hold down) or release a key, enclose the key name in braces, followed by a space and then the word "down" or "up". The following example causes Ctrl+CapsLock to act as a toggle for Shift:

59 |
*^CapsLock::{
 60 |     if GetKeyState("Shift")
 61 |         Send "{Shift up}"
 62 |     else
 63 |         Send "{Shift down}"
 64 | }
65 | 66 |

Hotkeys vs. Send

67 |

Warning: Hotkeys and Send have some differences that you should be aware of.

68 |

Although hotkeys also use the symbols ^!+# and the same key names, there are several important differences:

69 | 74 |

This is because Send serves multiple purposes, whereas hotkeys are optimized for key combinations.

75 |

On a related note, hotstrings are exclusively for detecting text entry, so the symbols ^!+#{} have no special meaning within the hotstring trigger text. However, a hotstring's replacement text uses the same syntax as Send (except when the T option is used). Whenever you type "{" with the following hotstring active, it sends "}" and then Left to move the insertion point back between the braces:

76 |
:*?B0:{::{}}{Left}
77 | 78 |

Blind mode

79 |

Normally, Send assumes that any modifier keys you are physically holding down should not be combined with the keys you are asking it to send. For instance, if you are holding Ctrl and you call Send "Hi", Send will automatically release Ctrl before sending "Hi" and press it back down afterward.

80 |

Sometimes what you want is to send some keys in combination with other modifiers that were previously pressed or sent. To do this, you can use the {Blind} prefix. While running the following example, try focusing a non-empty text editor or input field and pressing 1 or 2 while holding Ctrl or Ctrl+Shift:

81 |
*^1::Send "{Blind}{Home}"
 82 | *^2::Send "{Blind}{End}"
83 |

For more about {Blind}, see Blind mode.

84 | 85 |

Others

86 |

Send supports a few other special constructs, such as:

87 | 92 |

For a full list, see Key names.

93 | 94 |

Modes and options

95 |

Sending a key does not perfectly replicate the act of physically pressing the key. The operating system provides several different ways to send keys, with different caveats for each. Sometimes to get the result you want, you will need to not only try different methods but also tweak the timing.

96 |

The main methods are SendInput, SendEvent and SendPlay. SendInput is generally the most reliable, so by default, Send is synonymous with SendInput. SendMode can be used to make Send synonymous with SendEvent or SendPlay instead. The documentation describes other pros and cons of SendInput and SendPlay at length, but I would suggest just trying SendEvent or SendPlay when you have issues with SendInput.

97 |

Warning: SendPlay doesn't tend to work on modern systems unless you run with UI access. On Windows 11 and later, SendPlay may have no effect at all.

98 |

Another option worth trying is ControlSend. This doesn't use an official method of sending keystrokes, but instead sends messages directly to the window that you specify. The main advantage is that the window usually doesn't need to be active to receive these messages. But since it bypasses the normal processing of keyboard input by the system, sometimes it doesn't work.

99 | 100 |

Timing and delays

101 |

Sometimes you can get away with sending a flood of keystrokes faster than humanly possible, and sometimes you can't. There are generally two situations where you might need a delay:

102 | 106 |

For the first case, you can simply call Send, then Sleep, then Send, and so on.

107 |

SetKeyDelay exists for the second case. This function can set a delay to be performed between each keystroke, and the duration of the keystroke (i.e. the delay between pressing and releasing the key).

108 |
^1::{
109 |     SetKeyDelay 75, 25  ; 75ms between keys, 25ms between down/up.
110 |     SendEvent "You should see the keys{bs 4}text appear gradually."
111 | }
112 |

Warning: SendInput does not support key delays, nor does Send by default.

113 |

In order to make SetKeyDelay effective, you must generally either use SendMode "Event" or call SendEvent, SendPlay or ControlSend instead of Send or SendText.

114 | 115 |

Sending a lot of text

116 |

One way to send multiple lines of text is to use a continuation section:

117 |
SendText "
118 | (
119 |     Leading indentation is stripped out,
120 |     based on the first line.
121 |     Line breaks are kept
122 |     unless you use the "Join" option.
123 | )"
124 |

Although it is generally quite fast, SendText still has to send each character one at a time, while Send generally needs to send at least twice as many messages (key-down and key-up). This adds up to a noticeable delay when sending a large amount of text. It can also become unreliable, as a longer delay means higher risk of conflict with input by the user, the keyboard focus shifting, or other conditions changing.

125 |

Generally it is faster and more reliable to instead place the text on the clipboard and paste it. For example:

126 |
^1::{
127 |     old_clip := ClipboardAll()  ; Save all clipboard content
128 |     A_Clipboard := "
129 |     (Join`s
130 |         This text is placed on the clipboard,
131 |         and will be pasted below by sending Ctrl+V.
132 |     )"
133 |     Send "^v"
134 |     Sleep 500  ; Wait a bit for Ctrl+V to be processed
135 |     A_Clipboard := old_clip  ; Restore previous clipboard content
136 | }
137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /docs/howto/WriteHotkeys.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | How to Write Hotkeys | AutoHotkey v2 9 | 10 | 11 | 12 | 13 |

How to Write Hotkeys

14 |

A hotkey is a key or key combination that triggers an action. For example, Win+E normally launches File Explorer, and F1 often activates an app-specific help function. AutoHotkey has the power to define hotkeys that can be used anywhere or only within specific apps, performing any action that you are able to express with code.

15 |

The most common way to define a hotkey is to write the hotkey name followed by double-colon, then the action:

16 |
#n::Run "notepad"
17 |

This example defines a hotkey that runs Notepad whenever you press Win+N. To learn how to try it out, refer to How to Run Example Code.

18 |

For more about running programs, see How to Run Programs.

19 |

If multiple lines are required, use braces to mark the start and end of the hotkey's action. This is called a block.

20 |
#n::
 21 | {
 22 |     if WinExist("ahk_class Notepad")
 23 |         WinActivate  ; Activate the window found above
 24 |     else
 25 |         Run "notepad"  ; Open a new Notepad window
 26 | }
27 |

The opening brace can also be written on the same line as the hotkey, after ::.

28 |

The block following a double-colon hotkey is implicitly the body of a function, but that is only important when you define your own variables. For now, just know that blocks are used to group multiple lines as a single action or statement (see Control Flow if you want to know more about this).

29 | 30 |

Basic Hotkeys

31 |

For most hotkeys, the hotkey name consists of optional modifier symbols immediately followed by a single letter or symbol, or a key name. Try making the following changes to the example above:

32 | 39 |

Note: The last character before :: is never interpreted as a modifier symbol.

40 |

With this form of hotkey, only the final key in the combination can be written literally as a single character or have its name spelled out in full. For example:

41 | 46 |

The most common modifiers are Ctrl (^), Alt (!), Shift (+) and Win (#).

47 |

The symbols < and > can be prefixed to any one of the above four modifiers to specify the left or right variant of that key. The modifier combination <^>! corresponds to the AltGr key (if present on your keyboard layout), since the operating system implements it as a combination of LCtrl and RAlt.

48 |

The other modifiers are:

49 | 54 |

To make a hotkey fire only when you release the key instead of when you press it, use the UP suffix.

55 |

Related: Hotkey Modifier Symbols, List of Keys

56 | 57 |

Context-sensitive Hotkeys

58 |

The #HotIf directive can be used to specify a condition that must be met for the hotkey to activate, such as:

59 | 64 |

For example:

65 |
#HotIf WinActive("ahk_class Notepad")
 66 | ^a::MsgBox "You pressed Ctrl-A while Notepad is active. Pressing Ctrl-A in any other window will pass the Ctrl-A keystroke to that window."
 67 | #c::MsgBox "You pressed Win-C while Notepad is active."
 68 | 
 69 | #HotIf
 70 | #c::MsgBox "You pressed Win-C while any window except Notepad is active."
71 |

You define the condition by writing an expression which is evaluated whenever you press the hotkey. If the expression evaluates to true, the hotkey's action is executed.

72 |

The same hotkey can be used multiple times by specifying a different condition for each occurrence of the hotkey, or each hotkey variant. When you press the hotkey, the program executes the first hotkey variant whose condition is met, or the one without a condition (such as the final #c:: in the example above).

73 |

If the hotkey's condition isn't met and there is no unconditional variant of the hotkey, the keypress is passed on to the active window as though the hotkey wasn't defined in the first place. For instance, if Notepad isn't active while running the example above, Ctrl+A will perform its normal function (probably Select All).

74 |

Try making the following changes to the example:

75 | 80 |

Correctly identifying which window you want the hotkey to affect sometimes requires using criteria other than the window title. To learn more, see How to Manage Windows.

81 |

Related: #HotIf, Expressions, WinActive

82 | 83 |

Custom Combinations

84 |

A custom combination is a hotkey that combines two keys which aren't normally meant to be used in combination. For example, Numpad0 & Numpad1:: defines a hotkey which activates when you hold Numpad0 and press Numpad1.

85 |

When you use a key as a prefix in a custom combination, AutoHotkey assumes that you don't want the normal function of the key to activate, since that would interfere with its use as a modifier key. There are two ways to restore the key's normal function:

86 |
    87 |
  1. Use another hotkey such as Numpad0::Send "{Numpad0}" to replicate the key's original function. By default, the hotkey will only activate when you release Numpad0, and only if you didn't press Numpad0 and Numpad1 in combination.
  2. 88 |
  3. Prefix the combination with tilde (~), as in ~Numpad0 & Numpad1::. This prevents AutoHotkey from suppressing the normal function of Numpad0, unless you have also defined Numpad0::, in which case the tilde allows the latter hotkey to activate immediately instead of when you release Numpad0.
  4. 89 |
90 |

Note: Custom combinations only support combinations of exactly two keys/mouse buttons, and cannot be combined with other modifiers, such as !#^+ for Alt, Win, Ctrl and Shift.

91 |

Although AutoHotkey does not directly support custom combinations of more than two keys, a similar end result can be achieved by using #HotIf. If you run the example below, pressing Ctrl+CapsLock+Space or Ctrl+Space+CapsLock should show a message:

92 |
#HotIf GetKeyState("Ctrl")
 93 | Space & CapsLock::
 94 | CapsLock & Space::MsgBox "Success!"
95 |

It is necessary to press Ctrl first in this example. This has the advantage that Space and CapsLock perform their normal function if you are not holding Ctrl.

96 |

Related: Custom Combinations

97 | 98 |

Other Features

99 |

AutoHotkey's hotkeys have some other features that are worth exploring. While most applications are limited to combinations of Ctrl, Alt, Shift and sometimes Win with one other key (and often not all keys on the keyboard are supported), AutoHotkey isn't so limited. For further reading, see Hotkeys.

100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /docs/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Quick Reference | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

Version 2.0.19

16 |

https://www.autohotkey.com

17 |

© 2014 Steve Gray, Chris Mallett, portions © AutoIt Team and various others

18 |

Software License: GNU General Public License

19 | 20 |

Quick Reference

21 |

Getting started:

22 | 37 |

Scripts:

38 | 48 |

Keyboard and mouse:

49 | 55 |

Other:

56 | 60 | 61 |

Acknowledgements

62 |

A special thanks to Jonathan Bennett, whose generosity in releasing AutoIt v2 as free software in 1999 served as an inspiration and time-saver for myself and many others worldwide. In addition, many of AutoHotkey's enhancements to the AutoIt v2 command set, as well as the Window Spy and the old script compiler, were adapted directly from the AutoIt v3 source code. So thanks to Jon and the other AutoIt authors for those as well.

63 |

Finally, AutoHotkey would not be what it is today without these other individuals.

64 |

~ Chris Mallett

65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/lib/A_Clipboard.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A_Clipboard - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

A_Clipboard

15 | 16 |

A_Clipboard is a built-in variable that reflects the current contents of the Windows clipboard if those contents can be expressed as text.

17 | 18 |

Each line of text on A_Clipboard typically ends with carriage return and linefeed (CR+LF), which can be expressed in the script as `r`n. Files (such as those copied from an open Explorer window via Ctrl+C) are considered to be text: They are automatically converted to their filenames (with full path) whenever A_Clipboard is referenced in the script. To extract the files one by one, follow this example:

19 |
Loop Parse A_Clipboard, "`n", "`r"
20 | {
21 |     Result := MsgBox("File number " A_Index " is " A_LoopField ".`n`nContinue?",, 4)
22 |     if Result = "No"
23 |         break
24 | }
25 |

To arrange the filenames in alphabetical order, use the Sort function. To write the filenames on the clipboard to a file, use FileAppend A_Clipboard "`r`n", "C:\My File.txt". To change how long the script will keep trying to open the clipboard -- such as when it is in use by another application -- use #ClipboardTimeout.

26 | 27 |

ClipWait may be used to detect when the clipboard contains data (optionally including non-text data):

28 |
A_Clipboard := ""  ; Start off empty to allow ClipWait to detect when the text has arrived.
29 | Send "^c"
30 | ClipWait  ; Wait for the clipboard to contain text.
31 | MsgBox "Control-C copied the following contents to the clipboard:`n`n" A_Clipboard
32 | 33 | 34 | 35 | 39 | 40 |

Examples

41 |
42 |

Gives the clipboard entirely new contents.

43 |
A_Clipboard := "my text"
44 |
45 | 46 |
47 |

Empties the clipboard.

48 |
A_Clipboard := ""
49 |
50 | 51 |
52 |

Converts any copied files, HTML, or other formatted text to plain text.

53 |
A_Clipboard := A_Clipboard
54 |
55 | 56 |
57 |

Appends some text to the clipboard.

58 |
A_Clipboard .= " Text to append."
59 |
60 | 61 |
62 |

Replaces all occurrences of ABC with DEF (also converts the clipboard to plain text).

63 |
A_Clipboard := StrReplace(A_Clipboard, "ABC", "DEF")
64 |
65 | 66 |

Clipboard utilities written in AutoHotkey v1:

67 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/lib/A_HotkeyModifierTimeout.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A_HotkeyModifierTimeout - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

A_HotkeyModifierTimeout

15 | 16 |

A_HotkeyModifierTimeout is a built-in variable that affects the behavior of Send with hotkey modifiers Ctrl, Alt, Win, and Shift. Specifically, it defines how long after a hotkey is pressed that its modifier keys are assumed to still be held down. This is used by Send to determine whether to push the modifier keys back down after having temporarily released them.

17 |

A_HotkeyModifierTimeout can be used to get or set an integer representing the length of the interval in milliseconds. If -1, it never times out (modifier keys are always pushed back down after the Send). If 0, it always times out (modifier keys are never pushed back down).

18 |

The default setting is 50 (ms).

19 | 20 |

Remarks

21 |

This variable has no effect when:

22 | 26 |

To illustrate the effect of this variable, consider this example: ^!a::Send "abc".

27 |

When the Send function executes, the first thing it does is release Ctrl and Alt so that the characters get sent properly. After sending all the keys, the function doesn't know whether it can safely push back down Ctrl and Alt (to match whether the user is still holding them down). But if less than the specified number of milliseconds have elapsed, it will assume that the user hasn't had a chance to release the keys yet and it will thus push them back down to match their physical state. Otherwise, the modifier keys will not be pushed back down and the user will have to release and press them again to get them to modify the same or another key.

28 |

The timeout should be set to a value less than the amount of time that the user typically holds down a hotkey's modifiers before releasing them. Otherwise, the modifiers may be restored to the down position (get stuck down) even when the user isn't physically holding them down.

29 |

You can reduce or eliminate the need for this variable with one of the following:

30 | 35 | 36 | 37 |

GetKeyState

38 | 39 |

Examples

40 |
41 |

Sets the hotkey modifier timeout to 100 ms instead of 50 ms.

42 |
A_HotkeyModifierTimeout := 100
43 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /docs/lib/A_MaxHotkeysPerInterval.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A_MaxHotkeysPerInterval / A_HotkeyInterval - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

A_MaxHotkeysPerInterval / A_HotkeyInterval

15 | 16 |

A_MaxHotkeysPerInterval and A_HotkeyInterval are built-in variables that control the rate of hotkey activations beyond which a warning dialog will be displayed.

17 |

A_MaxHotkeysPerInterval can be used to get or set an integer representing the maximum number of hotkeys that can be pressed within the interval without triggering a warning dialog.

18 |

A_HotkeyInterval can be used to get or set an integer representing the length of the interval in milliseconds.

19 |

The default settings are 70 (ms) for A_MaxHotkeysPerInterval and 2000 (ms) for A_HotkeyInterval.

20 | 21 |

Remarks

22 |

These built-in variables should usually be assigned values when the script starts (if the default settings are not suitable), but the script can get or set their values at any time.

23 |

Care should be taken not to make the setting too lenient because if you ever inadvertently introduce an infinite loop of keystrokes (via a Send function that accidentally triggers other hotkeys), your computer could become unresponsive due to the rapid flood of keyboard events.

24 |

As an oversimplified example, the hotkey ^c::Send "^c" would produce an infinite loop of keystrokes. To avoid this, add the $ prefix to the hotkey definition (e.g. $^c::) so that the hotkey cannot be triggered by the Send function.

25 |

The limit might be reached by means other than an infinite loop, such as:

26 | 30 |

To disable the warning dialog entirely, use A_HotkeyInterval := 0.

31 | 32 |

Examples

33 |
34 |

Allows a maximum of 200 hotkeys to be pressed within 2000 ms without triggering a warning dialog.

35 |
A_HotkeyInterval := 2000  ; This is the default value (milliseconds).
36 | A_MaxHotkeysPerInterval := 200
37 |
38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /docs/lib/A_MenuMaskKey.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A_MenuMaskKey - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

A_MenuMaskKey

15 | 16 |

A_MenuMaskKey is a built-in variable that controls which key is used to mask Win or Alt keyup events.

17 |

A_MenuMaskKey can be used to get or set a string representing a vkNNscNNN sequence identifying the virtual key code (NN) and scan code (NNN), in hexadecimal. If blank, masking is disabled.

18 |

The script can also assign a key name, vkNN sequence or scNNN sequence, in which case generally either the VK or SC code is left as zero until the key is sent, then determined automatically. Assigning "vk00sc000" disables masking and is equivalent to assigning "".

19 |

The returned string is always a vkNNscNNN sequence if enabled or blank if disabled, regardless of how it was assigned. All vkNNscNNN sequences and all non-zero vkNN or scNNN sequences are permitted, but some combinations may fail to suppress the menu. Any other invalid keys cause a ValueError to be thrown.

20 |

The default setting is vk11sc01D (the left Ctrl key).

21 | 22 |

Remarks

23 |

The mask key is sent automatically to prevent the Start menu or the active window's menu bar from activating at unexpected times.

24 |

This variable can be used to change the mask key to a key with fewer side effects. Good candidates are virtual key codes which generally have no effect, such as vkE8, which Microsoft documents as "unassigned", or vkFF, which is reserved to mean "no mapping" (a key which has no function). Some values, such as zero VK with non-zero SC, may fail to suppress the Start menu. Key codes are not required to match an existing key.

25 |

Note: Microsoft can assign an effect to an unassigned key code at any time. For example, vk07 was once undefined and safe to use, but since Windows 10 1909 it is reserved for opening the game bar.

26 |

This setting is global, meaning that it needs to be specified only once to affect the behavior of the entire script.

27 |

Hotkeys: If a hotkey is implemented using the keyboard hook or mouse hook, the final keypress may be invisible to the active window and the system. If the system was to detect only a Win or Alt keydown and keyup with no intervening keypress, it would usually activate a menu. To prevent this, the keyboard or mouse hook may automatically send the mask key.

28 |

Pressing a hook hotkey causes the next Alt or Win keyup to be masked if all of the following conditions are met:

29 | 37 |

Mouse hotkeys may send the mask key immediately if the keyboard hook is not installed.

38 |

Hotkeys with the tilde modifier are not intended to block the native function of the key, so they do not cause masking. Hotkeys like ~#a:: still suppress the menu, since the system detects that Win has been used in combination with another key. However, mouse hotkeys and both Win themselves (~LWin:: and ~RWin::) do not suppress the Start Menu.

39 |

The Start Menu (or the active window's menu bar) can be suppressed by sending any keystroke. The following example disables the ability for the left Win to activate the Start Menu, while still allowing its use as a modifier:

40 |
~LWin::Send "{Blind}{vkE8}"
41 |

Send: Send, ControlSend and related often release modifier keys as part of their normal operation. For example, the hotkey <#a::SendText Address usually must release the left Win prior to sending the contents of Address, and press the left Win back down afterward (so that other Win key combinations continue working). The mask key may be sent in such cases to prevent a Win or Alt keyup from activating a menu.

42 | 43 | 44 |

See this archived forum thread for background information.

45 | 46 |

Examples

47 |
48 |

Basic usage.

49 |
A_MenuMaskKey := "vkE8"  ; Change the masking key to something unassigned such as vkE8.
50 | #Space::Run A_ScriptDir  ; An additional Ctrl keystroke is not triggered.
51 |
52 | 53 |
54 |

Shows in detail how this variable causes vkFF to be sent instead of LControl.

55 |
A_MenuMaskKey := "vkFF"  ; vkFF is no mapping.
56 | #UseHook
57 | #Space::
58 | !Space::
59 | {
60 |     KeyWait "LWin"
61 |     KeyWait "RWin"
62 |     KeyWait "Alt"
63 |     KeyHistory
64 | }
65 |
66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /docs/lib/Any.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Any - Methods & Properties | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Any

15 | 16 |

Any is the class at the root of AutoHotkey's type hierarchy. All other types are a sub-type of Any.

17 |

Any.Prototype defines methods and properties that are applicable to all values and objects (currently excluding ComValue and derived types) unless overridden. The prototype object itself is natively an Object, but has no base and therefore does not identify as an instance of Object.

18 | 19 |

Table of Contents

20 | 40 | 41 |

Methods

42 | 43 |

GetMethod

44 |

Retrieves the implementation function of a method.

45 |
Value.GetMethod(Name, ParamCount)
46 |

This method is exactly equivalent to GetMethod(Value, Name, ParamCount), unless overridden.

47 |
48 | 49 |

HasBase

50 |

Returns true if the specified base object is in the value's chain of base objects, otherwise false.

51 |
Value.HasBase(BaseObj)
52 |

This method is exactly equivalent to HasBase(Value, BaseObj), unless overridden.

53 |
54 | 55 |

HasMethod

56 |

Returns true if the value has a method by this name, otherwise false.

57 |
Value.HasMethod(Name, ParamCount)
58 |

This method is exactly equivalent to HasMethod(Value, Name, ParamCount), unless overridden.

59 |
60 | 61 |

HasProp

62 |

Returns true if the value has a property by this name, otherwise false.

63 |
Value.HasProp(Name)
64 |

This method is exactly equivalent to HasProp(Value, Name), unless overridden.

65 |
66 | 67 |

Properties

68 | 69 |

Base

70 |

Retrieves the value's base object.

71 |
BaseObj := Value.Base
72 |

For primitive values, the return value is the pre-defined prototype object corresponding to Type(Value).

73 |

See also: ObjGetBase, ObjSetBase, Obj.Base

74 |
75 | 76 |

Functions

77 |

ObjGetBase

78 |

Returns the value's base object.

79 |
BaseObj := ObjGetBase(Value)
80 |

No meta-functions or property functions are called. Overriding the Base property does not affect the behaviour of this function.

81 |

If there is no base, the return value is an empty string. Only the Any prototype itself has no base.

82 |

See also: Base, ObjSetBase, Obj.Base

83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/lib/Array.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Array Object - Methods & Properties | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Array Object

15 |
class Array extends Object
16 | 17 |

An Array object contains a list or sequence of values.

18 |

Values are addressed by their position within the array (known as an array index), where position 1 is the first element.

19 |

Arrays are often created by enclosing a list of values in brackets. For example:

20 |
veg := ["Asparagus", "Broccoli", "Cucumber"]
 21 | Loop veg.Length
 22 |     MsgBox veg[A_Index]
23 |

A negative index can be used to address elements in reverse, so -1 is the last element, -2 is the second last element, and so on.

24 |

Attempting to use an array index which is out of bounds (such as zero, or if its absolute value is greater than the Length of the array) is considered an error and will cause an IndexError to be thrown. The best way to add new elements to the array is to call InsertAt or Push. For example:

25 |
users := Array()
 26 | users.Push(A_UserName)
 27 | MsgBox users[1]
28 |

An array can also be extended by assigning a larger value to Length. This changes which indices are valid, but Has will show that the new elements have no value. Elements without a value are typically used for variadic calls or by variadic functions, but can be used for any purpose.

29 |

"ArrayObj" is used below as a placeholder for any Array object, as "Array" is the class itself.

30 |

In addition to the methods and property inherited from Object, Array objects have the following predefined methods and properties.

31 | 32 |

Table of Contents

33 | 62 | 63 |

Static Methods

64 | 65 |

Call

66 |

Creates a new Array containing the specified values.

67 |
ArrayObj := Array(Value, Value2, ..., ValueN)
 68 | ArrayObj := Array.Call(Value, Value2, ..., ValueN)
69 |

Parameters are defined by __New.

70 |
71 | 72 |

Methods

73 | 74 |

Clone

75 |

Returns a shallow copy of an array.

76 |
Clone := ArrayObj.Clone()
77 |

All array elements are copied to the new array. Object references are copied (like with a normal assignment), not the objects themselves.

78 |

Own properties, own methods and base are copied as per Obj.Clone.

79 |
80 | 81 |

Delete

82 |

Removes the value of an array element, leaving the index without a value.

83 |
RemovedValue := ArrayObj.Delete(Index)
84 |

Parameters

85 |
86 |
Index
87 |
88 |

Type: Integer

89 |

A valid array index.

90 |
91 |
92 |

Return Value

93 |

Type: Any

94 |

This method returns the removed value (blank if none).

95 |

Remarks

96 |

This method does not affect the Length of the array.

97 |

A ValueError is thrown if Index is out of range.

98 |
99 | 100 |

Get

101 |

Returns the value at a given index, or a default value.

102 |
Value := ArrayObj.Get(Index , Default)
103 |

This method does the following:

104 | 111 |

When Default is omitted, this is equivalent to ArrayObj[Index], except that __Item is not called.

112 |
113 | 114 |

Has

115 |

Returns a non-zero number if the index is valid and there is a value at that position.

116 |
HasIndex := ArrayObj.Has(Index)
117 |
118 | 119 |

InsertAt

120 |

Inserts one or more values at a given position.

121 |
ArrayObj.InsertAt(Index, Value1 , Value2, ... ValueN)
122 |

Parameters

123 |
124 |
Index
125 |
126 |

Type: Integer

127 |

The position to insert Value1 at. Subsequent values are inserted at Index+1, Index+2, etc. Specifying an index of 0 is the same as specifying Length + 1.

128 |
129 |
Value1 ...
130 |
131 |

Type: Any

132 |

One or more values to insert. To insert an array of values, pass theArray* as the last parameter.

133 |
134 |
135 |

Remarks

136 |

InsertAt is the counterpart of RemoveAt.

137 |

Any items previously at or to the right of Index are shifted to the right. Missing parameters are also inserted, but without a value. For example:

138 |
x := []
139 | x.InsertAt(1, "A", "B") ; =>  ["A", "B"]
140 | x.InsertAt(2, "C")      ; =>  ["A", "C", "B"]
141 | 
142 | ; Missing elements are preserved:
143 | x := ["A", , "C"]
144 | x.InsertAt(2, "B")      ; =>  ["A", "B",    , "C"]
145 | 
146 | x := ["C"]
147 | x.InsertAt(1, , "B")    ; =>  [   , "B", "C"]
148 |

A ValueError is thrown if Index is less than -ArrayObj.Length or greater than ArrayObj.Length + 1. For example, with an array of 3 items, Index must be between -3 and 4, inclusive.

149 |
150 | 151 |

Pop

152 |

Removes and returns the last array element.

153 |
RemovedValue := ArrayObj.Pop()
154 |

All of the following are equivalent:

155 |
RemovedValue := ArrayObj.Pop()
156 | RemovedValue := ArrayObj.RemoveAt(ArrayObj.Length)
157 | RemovedValue := ArrayObj.RemoveAt(-1)
158 |

If the array is empty (Length is 0), an Error is thrown.

159 |
160 | 161 |

Push

162 |

Appends values to the end of an array.

163 |
ArrayObj.Push(Value, Value2, ..., ValueN)
164 |

Parameters

165 |
166 |
Value ...
167 |
168 |

Type: Any

169 |

One or more values to insert. To insert an array of values, pass theArray* as the last parameter.

170 |
171 |
172 |
173 | 174 |

RemoveAt

175 |

Removes items from an array.

176 |
RemovedValue := ArrayObj.RemoveAt(Index)
177 | ArrayObj.RemoveAt(Index, Length)
178 |

Parameters

179 |
180 |
Index
181 |
182 |

Type: Integer

183 |

The index of the value or values to remove.

184 |
185 | 186 |
Length
187 |
188 |

Type: Integer

189 |

If omitted, one item is removed. Otherwise, specify the length of the range of values to remove.

190 |
191 |
192 |

Return Value

193 |

Type: Any

194 |

If Length is omitted, the removed value is returned (blank if none). Otherwise there is no return value.

195 |

Remarks

196 |

RemoveAt is the counterpart of InsertAt.

197 |

A ValueError is thrown if the range indicated by Index and Length is not entirely within the array's current bounds.

198 |

The remaining items to the right of Pos are shifted to the left by Length (or 1 if omitted). For example:

199 |
x := ["A", "B"]
200 | MsgBox x.RemoveAt(1)  ; A
201 | MsgBox x[1]           ; B
202 | 
203 | x := ["A", , "C"]
204 | MsgBox x.RemoveAt(1, 2)  ; 1
205 | MsgBox x[1]              ; C
206 |
207 | 208 |

__New

209 |

Appends items. Equivalent to Push.

210 |
ArrayObj.__New(Value, Value2, ..., ValueN)
211 |

This method exists to support Call, and is not intended to be called directly. See Construction and Destruction.

212 |
213 | 214 |

__Enum

215 |

Enumerates array elements.

216 |
For Value in ArrayObj
217 |
For Index, Value in ArrayObj
218 |

Returns a new enumerator. This method is typically not called directly. Instead, the array object is passed directly to a for-loop, which calls __Enum once and then calls the enumerator once for each iteration of the loop. Each call to the enumerator returns the next array element. The for-loop's variables correspond to the enumerator's parameters, which are:

219 |
220 |
Index
221 |
222 |

Type: Integer

223 |

The array index, typically the same as A_Index. This is present only in the two-parameter mode.

224 |
225 |
Value
226 |
227 |

Type: Any

228 |

The value (if there is no value, Value becomes uninitialized).

229 |
230 |
231 |
232 | 233 |

Properties

234 | 235 |

Length

236 |

Retrieves or sets the length of an array.

237 |
Length := ArrayObj.Length
238 |
ArrayObj.Length := Length
239 |

The length includes elements which have no value. Increasing the length changes which indices are considered valid, but the new elements have no value (as indicated by Has). Decreasing the length truncates the array.

240 |
241 | MsgBox ["A", "B", "C"].Length  ;  3
242 | MsgBox ["A",    , "C"].Length  ;  3
243 | 
244 |
245 | 246 |

Capacity

247 |

Retrieves or sets the current capacity of an array.

248 |
MaxItems := ArrayObj.Capacity
249 |
ArrayObj.Capacity := MaxItems
250 |

MaxItems is an integer representing the maximum number of elements the array should be able to contain before it must be automatically expanded. If setting a value less than Length, elements are removed.

251 |
252 | 253 |

Default

254 |

Defines the default value returned when an element with no value is requested.

255 |
ArrayObj.Default := Value
256 |

This property actually doesn't exist by default, but can be defined by the script. If defined, its value is returned by __Item or Get if the requested element has no value, instead of throwing an UnsetItemError. It can be implemented by any of the normal means, including a dynamic property or meta-function, but determining which key was queried would require overriding __Item or Get instead.

257 |

Setting a default value does not prevent an error from being thrown when the index is out of range.

258 |
259 | 260 |

__Item

261 |

Retrieves or sets the value of an array element.

262 |
Value := ArrayObj[Index]
263 | Value := ArrayObj.__Item[Index]
264 |
ArrayObj[Index] := Value
265 | ArrayObj.__Item[Index] := Value
266 |

Index is an integer representing a valid array index; that is, an integer with absolute value between 1 and Length (inclusive). A negative index can be used to address elements in reverse, so that -1 is the last element, -2 is the second last element, and so on. Attempting to use an index which is out of bounds (such as zero, or if its absolute value is greater than the Length of the array) is considered an error and will cause an IndexError to be thrown.

267 |

The property name __Item is typically omitted, as shown above, but is used when overriding the property.

268 |
269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/lib/Block.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {...} (block) - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

{...} (block)

14 |

Blocks are one or more statements enclosed in braces. Typically used with function definitions and control flow statements.

15 |
16 | {
17 |     Statements
18 | }
19 | 20 |

Remarks

21 |

A block is used to bind two or more statements together. It can also be used to change which If statement an Else statement belongs to, as in this example where the block forces the Else statement to belong to the first If statement rather than the second:

22 |
if (Var1 = 1)
23 | {
24 |     if (Var2 = "abc")
25 |         Sleep 1
26 | }
27 | else
28 |     return
29 |

Although blocks can be used anywhere, currently they are only meaningful when used with function definitions, If, Else, Loop statements, Try, Catch or Finally.

30 |

If any of the control flow statements mentioned above has only a single statement, that statement need not be enclosed in a block (this does not work for function definitions). However, there may be cases where doing so enhances the readability or maintainability of the script.

31 |

A block may be empty (contain zero statements), which may be useful in cases where you want to comment out the contents of the block without removing the block itself.

32 |

One True Brace (OTB, K&R style): The OTB style may optionally be used in the following places: function definitions, If, Else, Loop, While, For, Try, Catch, and Finally. This style puts the block's opening brace on the same line as the block's controlling statement rather than underneath on a line by itself. For example:

33 |
MyFunction(x, y) {
34 |     ...
35 | }
36 | if (x < y) {
37 |     ...
38 | } else {
39 |     ...
40 | }
41 | Loop RepeatCount {
42 |     ...
43 | }
44 | While x < y {
45 |     ...
46 | }
47 | For k, v in obj {
48 |     ...
49 | }
50 | Try {
51 |     ...
52 | } Catch Error {
53 |     ...
54 | } Finally {
55 |     ....
56 | }
57 |

Similarly, a statement may exist to the right of a brace (except the open-brace of the One True Brace style). For example:

58 |
if (x = 1)
59 | { MsgBox "This line appears to the right of an opening brace. It executes whenever the IF-statement is true."
60 |     MsgBox "This is the next line."
61 | } MsgBox "This line appears to the right of a closing brace. It executes unconditionally."
62 | 63 | 64 |

Function Definitions, Control Flow Statements, If, Else, Loop Statements, Try, Catch, Finally

65 | 66 |

Examples

67 |
68 |

By enclosing the two statements MsgBox "test1" and Sleep 5 with braces, the If statement knows that it should execute both if x is equal to 1.

69 |
if (x = 1)
70 | {
71 |     MsgBox "test1"
72 |     Sleep 5
73 | }
74 | else
75 |     MsgBox "test2"
76 |
77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /docs/lib/BlockInput.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BlockInput - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

BlockInput

14 | 15 |

Disables or enables the user's ability to interact with the computer via keyboard and mouse.

16 | 17 |
BlockInput OnOff
18 | BlockInput SendMouse
19 | BlockInput MouseMove
20 |

Parameters

21 |
22 | 23 |
OnOff
24 |
25 |

Type: String or Integer

26 |

This mode blocks all user inputs unconditionally. Specify one of the following values:

27 |

On or 1 (true): The user is prevented from interacting with the computer (mouse and keyboard input has no effect).

28 |

Off or 0 (false): Input is re-enabled.

29 |
30 |
SendMouse
31 |
32 |

Type: String

33 |

This mode only blocks user inputs while specific send and/or mouse functions are in progress. Specify one of the following words:

34 |

Send: The user's keyboard and mouse input is ignored while a SendEvent is in progress (including Send and SendText if SendMode "Event" has been used). This prevents the user's keystrokes from disrupting the flow of simulated keystrokes. When the Send finishes, input is re-enabled (unless still blocked by a previous use of BlockInput "On").

35 |

Mouse: The user's keyboard and mouse input is ignored while a Click, MouseMove, MouseClick, or MouseClickDrag is in progress (the traditional SendEvent mode only). This prevents the user's mouse movements and clicks from disrupting the simulated mouse events. When the mouse action finishes, input is re-enabled (unless still blocked by a previous use of BlockInput "On").

36 |

SendAndMouse: A combination of the above two modes.

37 |

Default: Turns off both the Send and the Mouse modes, but does not change the current state of input blocking. For example, if BlockInput "On" is currently in effect, using BlockInput "Default" will not turn it off.

38 |
39 |
MouseMove
40 |
41 |

Type: String

42 |

This mode only blocks the mouse cursor movement. Specify one of the following words:

43 |

MouseMove: The mouse cursor will not move in response to the user's physical movement of the mouse (DirectInput applications are a possible exception). When a script first uses this function, the mouse hook is installed (if it is not already). The mouse hook will stay installed until the next use of the Suspend or Hotkey function, at which time it is removed if not required by any hotkeys or hotstrings (see #Hotstring NoMouse).

44 |

MouseMoveOff: Allows the user to move the mouse cursor.

45 |
46 | 47 |
48 | 49 |

Remarks

50 |

All three BlockInput modes (OnOff, SendMouse and MouseMove) operate independently of each other. For example, BlockInput "On" will continue to block input until BlockInput "Off" is used, even if one of the words from SendMouse is also in effect. Another example is, if BlockInput "On" and BlockInput "MouseMove" are both in effect, mouse movement will be blocked until both are turned off.

51 |

Note: The OnOff and SendMouse modes might have no effect if UAC is enabled or the script has not been run as administrator. For more information, refer to the FAQ.

52 |

In preference to BlockInput, it is often better to use the sending modes SendInput or SendPlay so that keystrokes and mouse clicks become uninterruptible. This is because unlike BlockInput, those modes do not discard what the user types during the send; instead, those keystrokes are buffered and sent afterward. Avoiding BlockInput also avoids the need to work around sticking keys as described in the next paragraph.

53 |

If BlockInput becomes active while the user is holding down keys, it might cause those keys to become "stuck down". This can be avoided by waiting for the keys to be released prior to turning BlockInput on, as in this example:

54 |
^!p::
55 | {
56 |     KeyWait "Control"  ; Wait for the key to be released.  Use one KeyWait for each of the hotkey's modifiers.
57 |     KeyWait "Alt"
58 |     BlockInput true
59 |     ; ... send keystrokes and mouse clicks ...
60 |     BlockInput false
61 | }
62 |

When BlockInput is in effect, user input is blocked but AutoHotkey can simulate keystrokes and mouse clicks. However, pressing Ctrl+Alt+Del will re-enable input due to a Windows API feature.

63 |

Certain types of hook hotkeys can still be triggered when BlockInput is on. Examples include MButton (mouse hook) and LWin & Space (keyboard hook with explicit prefix rather than modifiers $#).

64 |

Input is automatically re-enabled when the script closes.

65 | 66 |

SendMode, Send, Click, MouseMove, MouseClick, MouseClickDrag

67 |

Examples

68 |
69 |

Opens Notepad and pastes time/date by sending F5 while BlockInput is turned on. Note that BlockInput may only work if the script has been run as administrator.

70 |
BlockInput true
71 | Run "notepad"
72 | WinWaitActive "ahk_class Notepad"
73 | Send "{F5}" ; pastes time and date
74 | BlockInput false
75 |
76 | 77 | 78 | -------------------------------------------------------------------------------- /docs/lib/Break.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Break - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Break

14 |

Exits (terminates) any type of loop statement.

15 |
Break LoopLabel
16 | 17 |

Parameters

18 |
19 |
LoopLabel
20 |
21 |

If omitted or 1, this statement applies to the innermost loop in which it is enclosed. Otherwise, specify which loop this statement should apply to; either by label name or numeric nesting level. If a label is specified, it must point directly at a loop statement.

22 |

LoopLabel must be a constant value - variables and expressions are not supported, with the exception of a single literal number or quoted string enclosed in parentheses. For example: break("outer")

23 |
24 |
25 | 26 |

Remarks

27 |

The use of Break and Continue are encouraged over Goto since they usually make scripts more readable and maintainable.

28 | 29 |

Continue, Loop, While-loop, For-loop, Blocks, Labels

30 | 31 |

Examples

32 |
33 |

Breaks the loop if var is greater than 25.

34 |
Loop
35 | {
36 |     ; ...
37 |     if (var > 25)
38 |         break
39 |     ; ...
40 |     if (var <= 5)
41 |         continue
42 | }
43 |
44 | 45 |
46 |

Breaks the outer loop from within a nested loop.

47 |
outer:
48 | Loop 3
49 | {
50 |     x := A_Index
51 |     Loop 3
52 |     {
53 |         if (x*A_Index = 6)
54 |             break outer  ; Equivalent to break 2 or goto break_outer.
55 |         MsgBox x "," A_Index
56 |     }
57 | }
58 | break_outer: ; For goto.
59 | 
60 |
61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /docs/lib/Buffer.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Buffer Object - Definition & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Buffer Object

15 |
class Buffer extends Object
16 | 17 |

Encapsulates a block of memory for use with advanced techniques such as DllCall, structures, StrPut and raw file I/O.

18 |

Buffer objects are typically created by calling Buffer(), but can also be returned by FileRead with the "RAW" option.

19 |
BufferObj := Buffer(ByteCount)
20 |

ClipboardAll returns a sub-type of Buffer, also named ClipboardAll.

21 |
class ClipboardAll extends Buffer
22 | 23 |

"BufferObj" is used below as a placeholder for any Buffer object, as "Buffer" is the class itself.

24 |

In addition to the methods and property inherited from Object, Buffer objects have the following predefined properties.

25 | 26 |

Table of Contents

27 | 48 | 49 |

Buffer-like Objects

50 |

Some built-in functions accept a Buffer object in place of an address - see the Related section for links. These functions also accept any other object which has Ptr and Size properties, but are optimized for the native Buffer object.

51 |

In most cases, passing a Buffer object is safer than passing an address, as the function can read the buffer size to ensure that it does not attempt to access any memory location outside of the buffer. One exception is that DllCall calls functions outside of the program; in those cases, it may be necessary to explicitly pass the buffer size to the function.

52 | 53 |

Static Methods

54 |

Call

55 |

Creates a new Buffer object.

56 |
BufferObj := Buffer(ByteCount, FillByte)
 57 | BufferObj := Buffer.Call(ByteCount, FillByte)
58 |

Parameters

59 |
60 |
ByteCount
61 |
62 |

Type: Integer

63 |

The number of bytes to allocate. Corresponds to Buffer.Size.

64 |

If omitted, the Buffer is created with a null (zero) Ptr and zero Size.

65 |
66 |
FillByte
67 |
68 |

Type: Integer

69 |

Specify a number between 0 and 255 to set each byte in the buffer to that number.

70 |

This should generally be omitted in cases where the buffer will be written into without first being read, as it has a time-cost proportionate to the number of bytes. If omitted, the memory of the buffer is not initialized; the value of each byte is arbitrary.

71 |
72 |
73 |

Return Value

74 |

Type: Object

75 |

This method or function returns a Buffer object.

76 |

Remarks

77 |

A MemoryError is thrown if the memory could not be allocated, such as if ByteCount is unexpectedly large or the system is low on virtual memory.

78 |

Parameters are defined by __New.

79 |
80 | 81 |

Methods

82 |

__New

83 |

Allocates or reallocates the buffer and optionally fills it.

84 |
BufferObj.__New(ByteCount, FillByte)
85 |

This method exists to support Call, and is not usually called directly. See Construction and Destruction.

86 |

Specify ByteCount to allocate, reallocate or free the buffer. This is equivalent to assigning Size.

87 |

Specify FillByte to fill the buffer with the given numeric byte value, overwriting any existing content.

88 |

If both parameters are omitted, this method has no effect.

89 |
90 | 91 |

Properties

92 |

Ptr

93 |

Retrieves the buffer's current memory address.

94 |
CurrentPtr := BufferObj.Ptr
95 |

CurrentPtr is an integer representing the buffer's current memory address. This address becomes invalid when the buffer is freed or reallocated. Invalid addresses must not be used. The buffer is not freed until the Buffer object's reference count reaches zero, but it is reallocated when its Size is changed.

96 |
97 | 98 |

Size

99 |

Retrieves or sets the buffer's size, in bytes.

100 |
CurrentByteCount := BufferObj.Size
101 |
BufferObj.Size := NewByteCount
102 |

CurrentByteCount and NewByteCount are an integer representing the buffer's size, in bytes. The buffer's address typically changes whenever its size is changed. If the size is decreased, the data within the buffer is truncated, but the remaining bytes are preserved. If the size is increased, all data is preserved and the values of any new bytes are arbitrary (they are not initialized, for performance reasons).

103 |

A MemoryError is thrown if the memory could not be allocated, such as if NewByteCount is unexpectedly large or the system is low on virtual memory.

104 |

CurrentByteCount is always the exact value it was given either by __New or by a previous assignment.

105 |
106 | 107 | 108 |

DllCall, NumPut, NumGet, StrPut, StrGet, File.RawRead, File.RawWrite, ClipboardAll

109 | 110 |

Examples

111 |
112 |

Uses a Buffer to receive a string from an external function via DllCall.

113 |
114 | max_chars := 11
115 | 
116 | ; Allocate a buffer for use with the Unicode version of wsprintf.
117 | bufW := Buffer(max_chars*2)
118 | 
119 | ; Print a UTF-16 string into the buffer with wsprintfW().
120 | DllCall("wsprintfW", "Ptr", bufW, "Str", "0x%08x", "UInt", 4919, "CDecl")
121 | 
122 | ; Retrieve the string from bufW and show it.
123 | MsgBox StrGet(bufW, "UTF-16")  ; Or just StrGet(bufW).
124 | 
125 | ; Allocate a buffer for use with the ANSI version of wsprintf.
126 | bufA := Buffer(max_chars)
127 | 
128 | ; Print an ANSI string into the buffer with wsprintfA().
129 | DllCall("wsprintfA", "Ptr", bufA, "AStr", "0x%08x", "UInt", 4919, "CDecl")
130 | 
131 | ; Retrieve the string from bufA (converted to the native format), and show it.
132 | MsgBox StrGet(bufA, "CP0")
133 | 
134 |
135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/lib/CallbackCreate.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CallbackCreate - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

CallbackCreate

15 | 16 |

Creates a machine-code address that when called, redirects the call to a function in the script.

17 | 18 |
Address := CallbackCreate(Function , Options, ParamCount)
19 |

Parameters

20 |
21 | 22 |
Function
23 |
24 |

Type: Function Object

25 |

A function object to call automatically whenever Address is called. The function also receives the parameters that were passed to Address.

26 |

A closure or bound function can be used to differentiate between multiple callbacks which all call the same script function.

27 |

The callback retains a reference to the function object, and releases it when the script calls CallbackFree.

28 |
29 | 30 |
Options
31 |
32 |

Type: String

33 |

If blank or omitted, a new thread will be started each time Function is called, the standard calling convention will be used, and the parameters will be passed individually to Function. Otherwise, specify one or more of the following options. Separate each option from the next with a space (e.g. "C Fast").

34 |

Fast or F: Avoids starting a new thread each time Function is called. Although this performs better, it must be avoided whenever the thread from which Address is called varies (e.g. when the callback is triggered by an incoming message). This is because Function will be able to change global settings such as A_LastError and the last-found window for whichever thread happens to be running at the time it is called. For more information, see Remarks.

35 |

CDecl or C: Makes Address conform to the "C" calling convention. This is typically omitted because the standard calling convention is much more common for callbacks. This option is ignored by 64-bit versions of AutoHotkey, which use the x64 calling convention.

36 |

&: Causes the address of the parameter list (a single integer) to be passed to Function instead of the individual parameters. Parameter values can be retrieved by using NumGet. When using the standard 32-bit calling convention, ParamCount must specify the size of the parameter list in DWORDs (the number of bytes divided by 4).

37 |
38 | 39 |
ParamCount
40 |
41 |

Type: Integer

42 |

If omitted, it defaults to Function.MinParams, which is usually the number of mandatory parameters in the definition of Function. Otherwise, specify the number of parameters that Address's caller will pass to it. In either case, ensure that the caller passes exactly this number of parameters.

43 |
44 | 45 |
46 | 47 |

Return Value

48 |

Type: Integer

49 |

CallbackCreate returns a machine-code address. This address is typically passed to an external function via DllCall or placed in a struct using NumPut, but can also be called directly by DllCall. Passing the address to CallbackFree will delete the callback.

50 | 51 |

Error Handling

52 |

This function fails and throws an exception under any of the following conditions:

53 | 59 | 60 | 61 |

The Function's Parameters

62 |

A function assigned to a callback address may accept up to 31 parameters. Optional parameters are permitted, which is useful when Function is called by more than one caller.

63 |

Interpreting the parameters correctly requires some understanding of how the x86 calling conventions work. Since AutoHotkey does not have typed parameters, the callback's parameter list is assumed to consist of integers, and some reinterpretation may be required.

64 | 65 |

AutoHotkey 32-bit: All incoming parameters are unsigned 32-bit integers. Smaller types are padded out to 32 bits, while larger types are split into a series of 32-bit parameters.

66 |

If an incoming parameter is intended to be a signed integer, any negative numbers can be revealed by following either of the following methods:

67 |
; Method #1
 68 | if (wParam > 0x7FFFFFFF)
 69 |     wParam := -(~wParam) - 1
 70 | 
 71 | ; Method #2: Relies on the fact that AutoHotkey natively uses signed 64-bit integers.
 72 | wParam := wParam << 32 >> 32
73 | 74 |

AutoHotkey 64-bit: All incoming parameters are signed 64-bit integers. AutoHotkey does not natively support unsigned 64-bit integers. Smaller types are padded out to 64 bits, while larger types are always passed by address.

75 | 76 |

AutoHotkey 32-bit/64-bit: If an incoming parameter is intended to be 8-bit or 16-bit (or 32-bit on x64), the upper bits of the value might contain "garbage" which can be filtered out by using bitwise-and, as in the following examples:

77 |
Callback(UCharParam, UShortParam, UIntParam) {
 78 |     UCharParam &= 0xFF
 79 |     UShortParam &= 0xFFFF
 80 |     UIntParam &= 0xFFFFFFFF
 81 |     ;...
 82 | }
83 |

If an incoming parameter is intended by its caller to be a string, what it actually receives is the address of the string. To retrieve the string itself, use StrGet:

84 |
MyString := StrGet(MyParameter)
85 |

If an incoming parameter is the address of a structure, the individual members may be extracted by following the steps at DllCall structures.

86 | 87 |

Receiving parameters by address: If the & option is used, Function receives the address of the first callback parameter. For example:

88 |
 89 | callback := CallbackCreate(TheFunc, "F&", 3)  ; Parameter list size must be specified for 32-bit.
 90 | DllCall(callback, "float", 10.5, "int64", 42)
 91 | TheFunc(params) {
 92 |     MsgBox NumGet(params, 0, "float") ", " NumGet(params, A_PtrSize, "int64")
 93 | }
94 |

Most callbacks in 32-bit programs use the stdcall calling convention, which requires a fixed number of parameters. In those cases, ParamCount must be set to the size of the parameter list, where Int64 and Double count as two 32-bit parameters. With Cdecl or the 64-bit calling convention, ParamCount has no effect.

95 | 96 | 97 |

What Function Should Return

98 |

If Function uses Return without any parameters, or it specifies a blank value such as "" (or it never uses Return at all), 0 is returned to the caller of the callback. Otherwise, Function should return an integer, which is then returned to the caller. AutoHotkey 32-bit truncates return values to 32-bit, while AutoHotkey 64-bit supports 64-bit return values. Returning structs larger than this (by value) is not supported.

99 | 100 |

Fast vs. Slow

101 |

The default/slow mode causes Function to start off fresh with the default values for settings such as SendMode and DetectHiddenWindows. These defaults can be changed during script startup.

102 |

By contrast, the fast mode inherits global settings from whichever thread happens to be running at the time Function is called. Furthermore, any changes Function makes to global settings (including the last-found window) will go into effect for the current thread. Consequently, the fast mode should be used only when it is known exactly which thread(s) Function will be called from.

103 |

To avoid being interrupted by itself (or any other thread), a callback may use Critical as its first line. However, this is not completely effective when Function is called indirectly via the arrival of a message less than 0x0312 (increasing Critical's interval may help). Furthermore, Critical does not prevent Function from doing something that might indirectly result in a call to itself, such as calling SendMessage or DllCall.

104 | 105 |

CallbackFree

106 |

Deletes a callback and releases its reference to the function object.

107 |
CallbackFree(Address)
108 |

Each use of CallbackCreate allocates a small amount of memory (32 or 48 bytes plus system overhead). Since the OS frees this memory automatically when the script exits, any script that allocates a small, fixed number of callbacks can get away with not explicitly freeing the memory.

109 |

However, if the function object held by the callback is of a dynamic nature (such as a closure or bound function), it can be especially important to free the callback when it is no longer needed; otherwise, the function object will not be released.

110 | 111 | 112 |

DllCall, OnMessage, OnExit, OnClipboardChange, Sort's callback, Critical, PostMessage, SendMessage, Functions, Windows Messages, Threads

113 | 114 |

Examples

115 |
116 |

Displays a summary of all top-level windows.

117 |
EnumAddress := CallbackCreate(EnumWindowsProc, "Fast")  ; Fast-mode is okay because it will be called only from this thread.
118 | 
119 | DetectHiddenWindows True  ; Due to fast-mode, this setting will go into effect for the callback too.
120 | 
121 | ; Pass control to EnumWindows(), which calls the callback repeatedly:
122 | DllCall("EnumWindows", "Ptr", EnumAddress, "Ptr", 0)
123 | MsgBox Output  ; Display the information accumulated by the callback.
124 |     
125 | EnumWindowsProc(hwnd, lParam)
126 | {
127 |     global Output
128 |     win_title := WinGetTitle(hwnd)
129 |     win_class := WinGetClass(hwnd)
130 |     if win_title
131 |         Output .= "HWND: " hwnd "`tTitle: " win_title "`tClass: " win_class "`n"
132 |     return true  ; Tell EnumWindows() to continue until all windows have been enumerated.
133 | }
134 |
135 | 136 |
137 |

Demonstrates how to subclass a GUI window by redirecting its WindowProc to a new WindowProc in the script. In this case, the background color of a text control is changed to a custom color.

138 |
TextBackgroundColor := 0xFFBBBB  ; A custom color in BGR format.
139 | TextBackgroundBrush := DllCall("CreateSolidBrush", "UInt", TextBackgroundColor)
140 | 
141 | MyGui := Gui()
142 | Text := MyGui.Add("Text",, "Here is some text that is given`na custom background color.")
143 | 
144 | ; 64-bit scripts must call SetWindowLongPtr instead of SetWindowLong:
145 | SetWindowLong := A_PtrSize=8 ? "SetWindowLongPtr" : "SetWindowLong"
146 | 
147 | WindowProcNew := CallbackCreate(WindowProc)  ; Avoid fast-mode for subclassing.
148 | WindowProcOld := DllCall(SetWindowLong, "Ptr", MyGui.Hwnd, "Int", -4  ; -4 is GWL_WNDPROC
149 |     , "Ptr", WindowProcNew, "Ptr") ; Return value must be set to "Ptr" or "UPtr" vs. "Int".
150 | 
151 | MyGui.Show()
152 | 
153 | WindowProc(hwnd, uMsg, wParam, lParam)
154 | {
155 |     Critical
156 |     if (uMsg = 0x0138 && lParam = Text.Hwnd)  ; 0x0138 is WM_CTLCOLORSTATIC.
157 |     {
158 |         DllCall("SetBkColor", "Ptr", wParam, "UInt", TextBackgroundColor)
159 |         return TextBackgroundBrush  ; Return the HBRUSH to notify the OS that we altered the HDC.
160 |     }
161 |     ; Otherwise (since above didn't return), pass all unhandled events to the original WindowProc.
162 |     return DllCall("CallWindowProc", "Ptr", WindowProcOld, "Ptr", hwnd, "UInt", uMsg, "Ptr", wParam, "Ptr", lParam)
163 | }
164 | 165 |
166 | 167 | 168 | -------------------------------------------------------------------------------- /docs/lib/CaretGetPos.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CaretGetPos - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

CaretGetPos

15 | 16 |

Retrieves the current position of the caret (text insertion point).

17 | 18 |
CaretFound := CaretGetPos(&OutputVarX, &OutputVarY)
19 |

Parameters

20 |
21 |
&OutputVarX, &OutputVarY
22 |
23 |

Type: VarRef

24 |

If omitted, the corresponding value will not be stored. Otherwise, specify references to the output variables in which to store the X and Y coordinates. The retrieved coordinates are relative to the active window's client area unless overridden by using CoordMode or A_CoordModeCaret.

25 |
26 |
27 | 28 |

Return Value

29 |

Type: Integer (boolean)

30 |

If there is no active window or the caret position cannot be determined, the function returns 0 (false) and the output variables are made blank. The function returns 1 (true) if the system returned a caret position, but this does not necessarily mean a caret is visible.

31 | 32 |

Remarks

33 |

Any of the output variables may be omitted if the corresponding information is not needed.

34 |

Note that some windows (e.g. certain versions of MS Word) report the same caret position regardless of its actual position.

35 | 36 | 37 |

CoordMode, A_CoordModeCaret

38 | 39 |

Examples

40 |
41 |

Allows the user to move the caret around to see its current position displayed in an auto-update tooltip.

42 |
SetTimer WatchCaret, 100
43 | WatchCaret() {
44 |     if CaretGetPos(&x, &y)
45 |         ToolTip "X" x " Y" y, x, y - 20
46 |     else
47 |         ToolTip "No caret"
48 | }
49 |
50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /docs/lib/Catch.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Catch - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Catch

14 | 15 |

Specifies one or more statements to execute if a value or error is thrown during execution of a Try statement.

16 | 17 |
Catch ErrorClass as OutputVar
18 | {
19 |     Statements
20 | }
21 |

Parameters

22 |
23 | 24 |
ErrorClass
25 |
26 |

Type: Class

27 |

The class of value that should be caught, such as Error, TimeoutError or MyCustomError. This can also be a comma-delimited list of classes. Classes must be specified by their exact full name and not an arbitrary expression, as the Prototype of each class is resolved at load time. Any built-in or user-defined class can be used, even if it does not derive from Error.

28 |

If no classes are specified, the default is Error.

29 |

To catch anything at all, use catch Any.

30 |

A load-time error is displayed if an invalid class name is used, or if a class is inaccessible due to the presence of a local variable with the same name.

31 |
32 | 33 |
OutputVar
34 |
35 |

Type: Variable

36 |

The output variable in which to store the thrown value, which is typically an Error object. This cannot be a dynamic variable.

37 |

If omitted, the thrown value cannot be accessed directly, but can still be re-thrown by using Throw with no parameter.

38 |
39 | 40 |
Statements
41 |
42 |

The statements to execute if a value or error is thrown.

43 |

Braces are generally not required if only a single statement is used. For details, see {...} (block).

44 |
45 | 46 |
47 | 48 |

Remarks

49 |

Multiple Catch statements can be used one after the other, with each one specifying a different class (or multiple classes). If the value is not an instance of any of the listed classes, it is not caught by this Try-Catch, but might be caught by one further up the call stack.

50 |

Every use of Catch must belong to (be associated with) a Try statement above it. A Catch always belongs to the nearest unclaimed Try statement above it unless a block is used to change that behavior.

51 |

The parameter list may optionally be enclosed in parentheses, in which case the space or tab after catch is optional.

52 |

Catch may optionally be followed by Else, which is executed if no exception was thrown within the associated Try block.

53 |

The One True Brace (OTB) style may optionally be used. For example:

54 |
try {
55 |     ...
56 | } catch Error {
57 |     ...
58 | }
59 |

Load-time errors cannot be caught, since they occur before the try statement is executed.

60 | 61 | 62 |

Try, Throw, Error Object, Else, Finally, Blocks, OnError

63 | 64 |

Examples

65 |

See Try.

66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /docs/lib/Chr.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Chr - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Chr

14 | 15 |

Returns the string (usually a single character) corresponding to the character code indicated by the specified number.

16 | 17 |
String := Chr(Number)
18 |

Parameters

19 |
20 | 21 |
Number
22 |
23 |

Type: Integer

24 |

A Unicode character code between 0 and 0x10FFFF.

25 |
26 | 27 |
28 | 29 |

Return Value

30 |

Type: String

31 |

The string corresponding to Number. This is always a single Unicode character, but for practical reasons, Unicode supplementary characters (where Number is in the range 0x10000 to 0x10FFFF) are counted as two characters. That is, the length of the return value as reported by StrLen may be 1 or 2. For further explanation, see String Encoding.

32 |

If Number is 0, the return value is a string containing a binary null character, not an empty (zero-length) string. This can be safely assigned to a variable, passed to a function or concatenated with another string. However, some built-in functions may "see" only the part of the string preceding the first null character.

33 | 34 |

Remarks

35 |

The range and meaning of character codes depends on which string encoding is in use. Currently all AutoHotkey v2 executables are built for Unicode, so this function always accepts a Unicode character code and returns a Unicode (UTF-16) string.

36 |

Common character codes include 9 (tab), 10 (linefeed), 13 (carriage return), 32 (space), 48-57 (the digits 0-9), 65-90 (uppercase A-Z), and 97-122 (lowercase a-z).

37 | 38 | 39 |

Ord

40 | 41 |

Examples

42 |
43 |

Reports the string corresponding to the character code 116.

44 |
MsgBox Chr(116) ; Reports "t".
45 |
46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/lib/Class.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Class Object - Methods & Properties | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Class Object

15 |
class Class extends Object
16 | 17 |

A Class object represents a class definition; it contains static methods and properties.

18 |

Each class object is based on whatever class it extends, or Object if not specified. The global class object Object is based on Class.Prototype, which is based on Object.Prototype, so classes can inherit methods and properties from any of these base objects.

19 |

"Static" methods and properties are any methods and properties which are owned by the class object itself (and therefore do not apply to a specific instance), while methods and properties for instances of the class are owned by the class's Prototype.

20 |

"ClassObj" is used below as a placeholder for any class object, as "Class" is the Class class itself. Ordinarily, one refers to a class object by the name given in its class definition.

21 | 22 |

Table of Contents

23 | 35 | 36 |

Methods

37 | 38 |

Call

39 |

Constructs a new instance of the class.

40 |
Obj := ClassObj(Params*)
41 | Obj := ClassObj.Call(Params*)
42 |

This static method is typically inherited from the Object, Array or Map class. It performs the following functions:

43 | 50 |

Call can be overridden within a class definition by defining a static method, such as static Call(). This allows classes to modify or prevent the construction of new instances.

51 |

Note that Class() (literally using "Class" in this case) can be used to construct a new Class object based on Class.Prototype. However, this new object initially has no Call method as it is not a subclass of Object. It can become a subclass of Object by assigning to Base, or the Call method can be reimplemented or copied from another class. A Prototype must also be created and assigned to the class before it can be instantiated with the standard Call method.

52 |
53 | 54 |

Properties

55 | 56 |

Prototype

57 |

Retrieves or sets the object on which all instances of the class are based.

58 |
Proto := ClassObj.Prototype
59 |
ClassObj.Prototype := Proto
60 |

By default, the class's Prototype contains all instance methods and dynamic properties defined within the class definition, and can be used to retrieve references to methods or property getters/setters or define new ones. The script can also define new value properties, which act as default property values for all instances.

61 |

A class's Prototype is normally based on the Prototype of its base class, so ClassObj.Prototype.base == ClassObj.base.Prototype.

62 |

Prototype is automatically defined as an own property of any class object created by a class definition.

63 |
64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/lib/Click.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Click - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Click

14 | 15 |

Clicks a mouse button at the specified coordinates. It can also hold down a mouse button, turn the mouse wheel, or move the mouse.

16 |
Click Options
17 | 18 |

Parameters

19 |
20 |
Options
21 |
22 |

Specify one or more of the following components: Coords, WhichButton, ClickCount, DownOrUp and/or Relative. If all components are omitted, a single left click is performed at the mouse cursor's current position.

23 |

The components may be spread across multiple parameters or combined into one or more strings. Each parameter may be either a single numeric component or a string containing zero or more components, where each component is separated from the next with at least one space, tab and/or comma (all within the string). For example, Click 100, 200, "R D" is equivalent to Click "100 200 R D" and both are valid. Parameters that are blank or omitted are ignored, as are extra commas.

24 |

Warning: Click 100 200 would be equivalent to Click "100200", as the two numbers would be concatenated before the function is called.

25 |

The components can appear in any order except ClickCount, which must occur somewhere to the right of Coords, if present.

26 |

Coords: If omitted, the cursor's current position is used. Otherwise, specify the X and Y coordinates to which the mouse cursor is moved prior to clicking. For example, Click "100 200" clicks the left mouse button at a specific position. Coordinates are relative to the active window's client area unless CoordMode was used to change that.

27 |

WhichButton: If omitted, it defaults to Left (the left mouse button). Otherwise, specify Left, Right, Middle (or just the first letter of each of these); or X1 (fourth button) or X2 (fifth button). For example, Click "Right" clicks the right mouse button at the mouse cursor's current position. Left and Right correspond to the primary button and secondary button. If the user swaps the buttons via system settings, the physical positions of the buttons are swapped but the effect stays the same.

28 |

WhichButton can also be WheelUp or WU to turn the wheel upward (away from you), or WheelDown or WD to turn the wheel downward (toward you). WheelLeft (or WL) or WheelRight (or WR) may also be specified. ClickCount is the number of notches to turn the wheel. However, some applications do not obey a ClickCount value higher than 1 for the mouse wheel. For them, use the Click function multiple times by means such as Loop.

29 |

ClickCount: If omitted, it defaults to 1. Otherwise, specify the number of times to click the mouse button or turn the mouse wheel. For example, Click 2 performs a double-click at the mouse cursor's current position. If Coords is specified, ClickCount must appear after it. Specify zero (0) to move the mouse without clicking; for example, Click "100 200 0".

30 |

DownOrUp: If omitted, each click consists of a down-event followed by an up-event. Otherwise, specify the word Down (or the letter D) to press the mouse button down without releasing it. Later, use the word Up (or the letter U) to release the mouse button. For example, Click "Down" presses down the left mouse button and holds it.

31 |

Relative: If omitted, the X and Y coordinates will be used for absolute positioning. Otherwise, specify the word Rel or Relative to treat the coordinates as offsets from the current mouse position. In other words, the cursor will be moved from its current position by X pixels to the right (left if negative) and Y pixels down (up if negative).

32 |
33 |
34 | 35 |

Remarks

36 |

The Click function uses the sending method set by SendMode. To override this mode for a particular click, use a specific Send function in combination with {Click}, as in this example: SendEvent "{Click 100 200}".

37 |

To perform a shift-click or control-click, clicking via Send is generally easiest. For example:

38 |
Send "+{Click 100 200}"  ; Shift+LeftClick
39 | Send "^{Click 100 200 Right}"  ; Control+RightClick
40 |

Unlike Send, the Click function does not automatically release the modifier keys (Ctrl, Alt, Shift, and Win). For example, if Ctrl is currently down, Click would produce a control-click but Send "{Click}" would produce a normal click.

41 |

The SendPlay mode is able to successfully generate mouse events in a broader variety of games than the other modes. In addition, some applications and games may have trouble tracking the mouse if it moves too quickly, in which case SetDefaultMouseSpeed can be used to reduce the speed (but only in SendEvent mode).

42 |

The BlockInput function can be used to prevent any physical mouse activity by the user from disrupting the simulated mouse events produced by the mouse functions. However, this is generally not needed for the SendInput and SendPlay modes because they automatically postpone the user's physical mouse activity until afterward.

43 |

There is an automatic delay after every click-down and click-up of the mouse (except for SendInput mode and for turning the mouse wheel). Use SetMouseDelay to change the length of the delay.

44 | 45 |

Send "{Click}", SendMode, CoordMode, SetDefaultMouseSpeed, SetMouseDelay, MouseClick, MouseClickDrag, MouseMove, ControlClick, BlockInput

46 |

Examples

47 |
48 |

Clicks the left mouse button at the mouse cursor's current position.

49 |
Click
50 |
51 | 52 |
53 |

Clicks the left mouse button at a specific position.

54 |
Click 100, 200
55 |
56 | 57 |
58 |

Moves the mouse cursor to a specific position without clicking.

59 |
Click 100, 200, 0
60 |
61 | 62 |
63 |

Clicks the right mouse button at a specific position.

64 |
Click 100, 200, "Right"
65 |
66 | 67 |
68 |

Performs a double-click at the mouse cursor's current position.

69 |
Click 2
70 |
71 | 72 |
73 |

Presses down the left mouse button and holds it.

74 |
Click "Down"
75 |
76 | 77 |
78 |

Releases the right mouse button.

79 |
Click "Up Right"
80 |
81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/lib/ClipWait.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ClipWait - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ClipWait

14 | 15 |

Waits until the clipboard contains data.

16 | 17 |
Boolean := ClipWait(Timeout, WaitFor)
18 |

Parameters

19 |
20 | 21 |
Timeout
22 |
23 |

Type: Integer or Float

24 |

If omitted, the function will wait indefinitely. Otherwise, it will wait no longer than this many seconds. To wait for a fraction of a second, specify a floating-point number, for example, 0.25 to wait for a maximum of 250 milliseconds.

25 |
26 | 27 |
WaitFor
28 |
29 |

Type: Integer

30 |

If omitted, it defaults to 0 (wait only for text or files). Otherwise, specify one of the following numbers to indicate what to wait for:

31 |

0: The function is more selective, waiting specifically for text or files to appear ("text" includes anything that would produce text when you paste into Notepad).

32 |

1: The function waits for data of any kind to appear on the clipboard.

33 |

Other values are reserved for future use.

34 |
35 | 36 |
37 | 38 |

Return Value

39 |

Type: Integer (boolean)

40 |

This function returns 0 (false) if the function timed out or 1 (true) otherwise (i.e. the clipboard contains data).

41 | 42 |

Remarks

43 |

It's better to use this function than a loop of your own that checks to see if this clipboard is blank. This is because the clipboard is never opened by this function, and thus it performs better and avoids any chance of interfering with another application that may be using the clipboard.

44 |

This function considers anything convertible to text (e.g. HTML) to be text. It also considers files, such as those copied in an Explorer window via Ctrl+C, to be text. Such files are automatically converted to their filenames (with full path) whenever the clipboard variable is referred to in the script. See A_Clipboard for details.

45 |

When 1 is present as the last parameter, the function will be satisfied when any data appears on the clipboard. This can be used in conjunction with ClipboardAll to save non-textual items such as pictures.

46 |

While the function is in a waiting state, new threads can be launched via hotkey, custom menu item, or timer.

47 | 48 | 49 |

A_Clipboard, WinWait, KeyWait

50 |

Examples

51 |
52 |

Empties the clipboard, copies the current selection into the clipboard and waits a maximum of 2 seconds until the clipboard contains data. If ClipWait times out, an error message is shown, otherwise the clipboard contents is shown.

53 |
A_Clipboard := "" ; Empty the clipboard
54 | Send "^c"
55 | if !ClipWait(2)
56 | {
57 |     MsgBox "The attempt to copy text onto the clipboard failed."
58 |     return
59 | }
60 | MsgBox "clipboard = " A_Clipboard
61 | return
62 |
63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/lib/ClipboardAll.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ClipboardAll - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ClipboardAll

15 | 16 |

Creates an object containing everything on the clipboard (such as pictures and formatting).

17 |
ClipSaved := ClipboardAll(Data, Size)
18 |

ClipboardAll itself is a class derived from Buffer.

19 | 20 |

Parameters

21 |

Omit both parameters to retrieve the current contents of the clipboard. Otherwise, specify one or both parameters to create an object containing the given binary clipboard data.

22 |
23 |
Data
24 |
25 |

Type: Object or Integer

26 |

A Buffer-like object or a pure integer which is the address of the binary data. The data must be in a specific format, so typically originates from a previous call to ClipboardAll. See example #2 below.

27 |
28 |
Size
29 |
30 |

Type: Integer

31 |

The number of bytes of data to use. This is optional when Data is an object.

32 |
33 |
34 | 35 |

Return Value

36 |

Type: Object

37 |

This function returns a ClipboardAll object, which has two properties (inherited from Buffer):

38 | 42 | 43 |

Remarks

44 |

The built-in variable A_Clipboard reflects the current contents of the Windows clipboard expressed as plain text, but can be assigned a ClipboardAll object to restore its content to the clipboard.

45 |

ClipboardAll is most commonly used to save the clipboard's contents so that the script can temporarily use the clipboard for an operation. When the operation is completed, the script restores the original clipboard contents as shown in example #1 and example #2.

46 |

If ClipboardAll cannot retrieve one or more of the data objects (formats) on the clipboard, they will be omitted but all the remaining objects will be stored.

47 |

ClipWait may be used to detect when the clipboard contains data (optionally including non-text data).

48 |

The binary data contained by the object consists of a four-byte format type, followed by a four-byte data-block size, followed by the data-block for that format. If the clipboard contained more than one format (which is almost always the case), these three items are repeated until all the formats are included. The data ends with a four-byte format type of 0.

49 | 50 | 51 |

A_Clipboard, ClipWait, OnClipboardChange, #ClipboardTimeout, Buffer

52 | 53 |

Examples

54 | 55 |
56 |

Saves and restores everything on the clipboard using a variable.

57 |
ClipSaved := ClipboardAll()   ; Save the entire clipboard to a variable of your choice.
58 | ; ... here make temporary use of the clipboard, such as for quickly pasting large amounts of text ...
59 | A_Clipboard := ClipSaved   ; Restore the original clipboard. Note the use of A_Clipboard (not ClipboardAll).
60 | ClipSaved := ""  ; Free the memory in case the clipboard was very large.
61 |
62 | 63 |
64 |

Saves and restores everything on the clipboard using a file.

65 |
; Option 1: Delete any existing file and then use FileAppend.
66 | FileDelete "Company Logo.clip"
67 | FileAppend ClipboardAll(), "Company Logo.clip" ; The file extension does not matter.
68 | 
69 | ; Option 2: Use FileOpen in overwrite mode and File.RawWrite.
70 | ClipData := ClipboardAll()
71 | FileOpen("Company Logo.clip", "w").RawWrite(ClipData)
72 |

To later load the file back onto the clipboard (or into a variable), follow this example:

73 |
ClipData := FileRead("Company Logo.clip", "RAW")  ; In this case, FileRead returns a Buffer.
74 | A_Clipboard := ClipboardAll(ClipData)  ; Convert the Buffer to a ClipboardAll and assign it.
75 |
76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /docs/lib/ComCall.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComCall - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ComCall

15 | 16 |

Calls a native COM interface method by index.

17 | 18 |
Result := ComCall(Index, ComObj , Type1, Arg1, Type2, Arg2, ReturnType)
19 |

Parameters

20 |
21 | 22 |
Index
23 |
24 |

Type: Integer

25 |

The zero-based index of the method within the virtual function table.

26 |

Index corresponds to the position of the method within the original interface definition. Microsoft documentation usually lists methods in alphabetical order, which is not relevant. In order to determine the correct index, locate the original interface definition. This may be in a header file or type library.

27 |

It is important to take into account methods which are inherited from parent interfaces. Since all COM interfaces ultimately derive from IUnknown, the first three methods are always QueryInterface (0), AddRef (1) and Release (2). For example, IShellItem2 is an extension of IShellItem, which starts at index 3 and contains 5 methods, so IShellItem2's first method (GetPropertyStore) is at index 8.

28 |

Tip: For COM interfaces defined by Microsoft, try searching the Internet or Windows SDK for "IInterfaceNameVtbl" - for example, "IUnknownVtbl". Microsoft's own interface definitions are accompanied by this plain-C definition of the interface's virtual function table, which lists all methods explicitly, in the correct order.

29 |

Passing an invalid index may cause undefined behaviour, including (but not limited to) program termination.

30 |
31 | 32 |
ComObj
33 |
34 |

Type: Integer or Object

35 |

The target COM object; that is, a COM interface pointer. The pointer value can be passed directly or encapsulated within an object with the Ptr property, such as a ComValue with variant type VT_UNKNOWN.

36 |

The interface pointer is used to locate the address of the virtual function which implements the interface method, and is also passed as a parameter. This parameter is generally not explicitly present in languages which natively support interfaces, but is shown in the C style "Vtbl" definition.

37 |

Passing an invalid pointer may cause undefined behaviour, including (but not limited to) program termination.

38 |
39 | 40 |
Type1, Arg1
41 |
42 |

Type: String

43 |

Each of these pairs represents a single parameter to be passed to the method. The number of pairs is unlimited. For Type, see the DllCall types table. For Arg, specify the value to be passed to the method.

44 |
45 | 46 |
ReturnType
47 |
48 |

Type: String

49 |

If omitted, the return type defaults to HRESULT, which is most the common return type for COM interface methods. Any result indicating failure causes an OSError to be thrown; therefore, the return type must not be omitted unless the actual return type is HRESULT.

50 |

If the method is of a type that does not return a value (the void return type in C), specify "Int" or any other numeric type without any suffix (except HRESULT), and ignore the return value. As the content of the return value register is arbitrary in such cases, an exception may or may not be thrown if ReturnType is omitted.

51 |

Otherwise, specify one of the argument types from the DllCall types table. The asterisk suffix is also supported.

52 |

Although ComCall supports the Cdecl keyword as per DllCall, it is generally not used by COM interface methods.

53 |
54 | 55 |
56 | 57 |

Return Value

58 |

Type: String or Integer

59 |

If ReturnType is HRESULT (or omitted) and the method returned an error value (as defined by the FAILED macro), an OSError is thrown.

60 |

Otherwise, ComCall returns the actual value returned by the method. If the method is of a type that does not return a value (with return type defined in C as void), the result is undefined and should be ignored.

61 | 62 |

Remarks

63 |

The following DllCall topics are also applicable to ComCall:

64 | 72 | 73 | 74 |

ComObject, ComObjQuery, ComValue, Buffer object, CallbackCreate

75 | 76 |

Examples

77 | 78 |
79 |

Removes the active window from the taskbar for 3 seconds. Compare this to the equivalent DllCall example.

80 |
/*
 81 |   Methods in ITaskbarList's VTable:
 82 |     IUnknown:
 83 |       0 QueryInterface  -- use ComObjQuery instead
 84 |       1 AddRef          -- use ObjAddRef instead
 85 |       2 Release         -- use ObjRelease instead
 86 |     ITaskbarList:
 87 |       3 HrInit
 88 |       4 AddTab
 89 |       5 DeleteTab
 90 |       6 ActivateTab
 91 |       7 SetActiveAlt
 92 | */
 93 | IID_ITaskbarList  := "{56FDF342-FD6D-11d0-958A-006097C9A090}"
 94 | CLSID_TaskbarList := "{56FDF344-FD6D-11d0-958A-006097C9A090}"
 95 | 
 96 | ; Create the TaskbarList object.
 97 | tbl := ComObject(CLSID_TaskbarList, IID_ITaskbarList)
 98 | 
 99 | activeHwnd := WinExist("A")
100 | 
101 | ComCall(3, tbl)                     ; tbl.HrInit()
102 | ComCall(5, tbl, "ptr", activeHwnd)  ; tbl.DeleteTab(activeHwnd)
103 | Sleep 3000
104 | ComCall(4, tbl, "ptr", activeHwnd)  ; tbl.AddTab(activeHwnd)
105 | 
106 | ; When finished with the object, simply replace any references with
107 | ; some other value (or if its a local variable, just return):
108 | tbl := ""
109 | 
110 |
111 | 112 |
113 |

Demonstrates some techniques for wrapping COM interfaces. Equivalent to the previous example.

114 |
115 | tbl := TaskbarList()
116 | 
117 | activeHwnd := WinExist("A")
118 | 
119 | tbl.DeleteTab(activeHwnd)
120 | Sleep 3000
121 | tbl.AddTab(activeHwnd)
122 | 
123 | tbl := ""
124 | 
125 | 
126 | class TaskbarList {
127 |     static IID := "{56FDF342-FD6D-11d0-958A-006097C9A090}"
128 |     static CLSID := "{56FDF344-FD6D-11d0-958A-006097C9A090}"
129 |     
130 |     ; Called on startup to initialize the class.
131 |     static __new() {
132 |         ; Get the base object for all instances of TaskbarList.
133 |         proto := this.Prototype
134 |         
135 |         ; Bound functions can be used to predefine parameters, making
136 |         ; the methods more usable without requiring wrapper functions.
137 |         ; HrInit itself has no parameters, so bind only the index,
138 |         ; and the caller will implicitly provide 'this'.
139 |         proto.HrInit := ComCall.Bind(3)
140 |         
141 |         ; Leave a parameter blank to let the caller provide a value.
142 |         ; In this case, the blank parameter is 'this' (normally hidden).
143 |         proto.AddTab := ComCall.Bind(4,, "ptr")
144 |         
145 |         ; An object or Map can be used to reduce repetition.
146 |         for name, args in Map(
147 |             "DeleteTab", [5,,"ptr"],
148 |             "ActivateTab", [6,,"ptr"],
149 |             "SetActiveAlt", [7,,"ptr"]) {
150 |             proto.%name% := ComCall.Bind(args*)
151 |         }
152 |     }
153 |     
154 |     ; Called by TaskbarList() on the new instance.
155 |     __new() {
156 |         this.comobj := ComObject(TaskbarList.CLSID, TaskbarList.IID)
157 |         this.ptr := this.comobj.ptr
158 |         ; Request initialization via ITaskbarList.
159 |         this.HrInit()
160 |     }
161 | }
162 | 
163 |
164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /docs/lib/ComObjActive.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjActive - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ComObjActive

14 | 15 |

Retrieves a registered COM object.

16 |
ComObj := ComObjActive(CLSID)
17 | 18 |

Parameters

19 |
20 | 21 |
CLSID
22 |
23 |

Type: String

24 |

CLSID or human-readable Prog ID of the COM object to retrieve.

25 |
26 | 27 |
28 | 29 |

Return Value

30 |

Type: ComObject

31 |

This function returns a new COM wrapper object with the variant type VT_DISPATCH (9).

32 | 33 |

Error Handling

34 |

An exception is thrown on failure.

35 | 36 | 37 |

ComValue, ComObject, ComObjGet, ComObjConnect, ComObjFlags, ObjAddRef/ObjRelease, ComObjQuery, GetActiveObject (Microsoft Docs)

38 | 39 |

Examples

40 |
41 |

Displays the active document in Microsoft Word, if it is running. For details about the COM object and its properties used below, see Word.Application object (Microsoft Docs).

42 |
43 | word := ComObjActive("Word.Application")
44 | if !word
45 |     MsgBox "Word isn't open."
46 | else
47 |     MsgBox word.ActiveDocument.FullName
48 |
49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /docs/lib/ComObjArray.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjArray - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ComObjArray

14 | 15 |

Creates a SafeArray for use with COM.

16 | 17 |
ArrayObj := ComObjArray(VarType, Count1 , Count2, ... Count8)
18 |

ComObjArray itself is a class derived from ComValue, but is used only to create or identify SafeArray wrapper objects.

19 | 20 |

Parameters

21 |
22 | 23 |
VarType
24 |
25 |

Type: Integer

26 | The base type of the array (the VARTYPE of each element of the array). The VARTYPE is restricted to a subset of the variant types. Neither the VT_ARRAY nor the VT_BYREF flag can be set. VT_EMPTY and VT_NULL are not valid base types for the array. All other types are legal. 27 |

See ComObjType for a list of possible values.

28 |
29 | 30 |
CountN
31 |
32 |

Type: Integer

33 |

The size of each dimension. Arrays containing up to 8 dimensions are supported.

34 |
35 | 36 |
37 | 38 |

Return Value

39 |

Type: ComObjArray

40 |

This function returns a wrapper object containing a new SafeArray.

41 | 42 |

Methods

43 |

ComObjArray objects support the following methods:

44 | 50 | 51 |

Remarks

52 |

ComObjArray objects may also be returned by COM methods and ComValue. Scripts may determine if a value is a ComObjArray as follows:

53 |
; Check class
 54 | if obj is ComObjArray
 55 |     MsgBox "Array subtype: " . ComObjType(obj) & 0xfff
 56 | else
 57 |     MsgBox "Not an array."
 58 | 
 59 | ; Check for VT_ARRAY
 60 | if ComObjType(obj) & 0x2000
 61 |     MsgBox "obj is a ComObjArray"
 62 | 
 63 | ; Check specific array type
 64 | if ComObjType(obj) = 0x2008
 65 |     MsgBox "obj is a ComObjArray of strings"
66 |

Arrays with up to 8 dimensions are supported.

67 |

Since SafeArrays are not designed to support multiple references, when one SafeArray is assigned to an element of another SafeArray, a separate copy is created. However, this only occurs if the wrapper object has the F_OWNVALUE flag, which indicates it is responsible for destroying the array. This flag can be removed by using ComObjFlags.

68 |

When a function or method called by a COM client returns a SafeArray with the F_OWNVALUE flag, a copy is created and returned instead, as the original SafeArray is automatically destroyed.

69 | 70 | 71 |

ComValue, ComObjType, ComObjValue, ComObjActive, ComObjFlags, Array Manipulation Functions (Microsoft Docs)

72 | 73 |

Examples

74 |
75 |

Simple usage.

76 |
arr := ComObjArray(VT_VARIANT:=12, 3)
 77 | arr[0] := "Auto"
 78 | arr[1] := "Hot"
 79 | arr[2] := "key"
 80 | t := ""
 81 | Loop arr.MaxIndex() + 1
 82 |     t .= arr[A_Index-1]
 83 | MsgBox t
 84 | 
85 |
86 | 87 |
88 |

Multiple dimensions.

89 |
arr := ComObjArray(VT_VARIANT:=12, 3, 4)
 90 | 
 91 | ; Get the number of dimensions:
 92 | dim := DllCall("oleaut32\SafeArrayGetDim", "ptr", ComObjValue(arr))
 93 | 
 94 | ; Get the bounds of each dimension:
 95 | dims := ""
 96 | Loop dim
 97 |     dims .= arr.MinIndex(A_Index) " .. " arr.MaxIndex(A_Index) "`n"
 98 | MsgBox dims
 99 | 
100 | ; Simple usage:
101 | Loop 3 {
102 |     x := A_Index-1
103 |     Loop 4 {
104 |         y := A_Index-1
105 |         arr[x, y] := x * y
106 |     }
107 | }
108 | MsgBox arr[2, 3]
109 | 
110 |
111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /docs/lib/ComObjConnect.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjConnect - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ComObjConnect

14 |

Connects a COM object's event source to the script, enabling events to be handled.

15 |
ComObjConnect ComObj , PrefixOrSink
16 | 17 |

Parameters

18 |
19 | 20 |
ComObj
21 |
22 |

Type: ComObject

23 |

An object which raises events.

24 |

If the object does not support the IConnectionPointContainer interface or type information about the object's class cannot be retrieved, an error message is shown. This can be suppressed or handled with try/catch.

25 |

The IProvideClassInfo interface is used to retrieve type information about the object's class if the object supports it. Otherwise, ComObjConnect attempts to retrieve type information via the object's IDispatch interface, which may be unreliable.

26 |
27 | 28 |
PrefixOrSink
29 |
30 |

Type: String or Object

31 |

If omitted, the object is "disconnected"; that is, the script will no longer receive notification of its events. Otherwise, specify a string to prefix to the event name to determine which global function to call when an event occurs, or an event sink object defining a static method for each event to be handled.

32 |

Note: Nested functions are not supported in this mode, as names may be resolved after the current function returns. To use nested functions or closures, attach them to an object and pass the object as described below.

33 |
34 | 35 |
36 | 37 |

Usage

38 |

To make effective use of ComObjConnect, you must first write functions in the script to handle any events of interest. Such functions, or "event-handlers," have the following structure:

39 |
PrefixEventName([Params..., ComObj])
40 | {
41 |     ... event-handling code ...
42 |     return ReturnValue
43 | }
44 |

Prefix should be the same as the PrefixOrSink parameter if it is a string; otherwise, it should be omitted. EventName should be replaced with the name of whatever event the function should handle.

45 |

Params corresponds to whatever parameters the event has. If the event has no parameters, Params should be omitted entirely. ComObj is an additional parameter containing a reference to the original wrapper object which was passed to ComObjConnect; it is never included in the COM event's documentation. "ComObj" should be replaced with a name more meaningful in the context of your script.

46 |

Note that event handlers may have return values. To return a COM-specific type of value, use ComValue. For example, return ComValue(0,0) returns a variant of type VT_EMPTY, which is equivalent to returning undefined (or not returning) from a JavaScript function.

47 |

Call ComObjConnect(yourObject, "Prefix") to enable event-handling.

48 |

Call ComObjConnect(yourObject) to disconnect the object (stop handling events).

49 |

If the number of parameters is not known, a variadic function can be used.

50 | 51 |

Event Sink

52 |

If PrefixOrSink is an object, whenever an event is raised, the corresponding method of that object is called. Although the object can be constructed dynamically, it is more typical for PrefixOrSink to refer to a class or an instance of a class. In that case, methods are defined as shown above, but without Prefix.

53 |

As with any call to a method, the method's (normally hidden) this parameter contains a reference to the object through which the method was called; i.e. the event sink object, not the COM object. This can be used to provide context to the event handlers, or share values between them.

54 |

To catch all events without defining a method for each one, define a __Call meta-function.

55 |

ComObject releases its reference to PrefixOrSink automatically if the COM object releases the connection. For example, Internet Explorer does this when it exits. If the script does not retain its own reference to PrefixOrSink, it can use __Delete to detect when this occurs. If the object is hosted by a remote process and the process terminates unexpectedly, it may take several minutes for the system to release the connection.

56 | 57 |

Remarks

58 |

The script must retain a reference to ComObj, otherwise it would be freed automatically and would disconnect from its COM object, preventing any further events from being detected. There is no standard way to detect when the connection is no longer required, so the script must disconnect manually by calling ComObjConnect.

59 |

The Persistent function may be needed to keep the script running while it is listening for events.

60 |

An exception is thrown on failure.

61 | 62 | 63 |

ComObject, ComObjGet, ComObjActive, WScript.ConnectObject (Microsoft Docs)

64 | 65 |

Examples

66 |
67 |

Launches an instance of Internet Explorer and connects events to corresponding script functions with the prefix "IE_". For details about the COM object and DocumentComplete event used below, see InternetExplorer object (Microsoft Docs).

68 |
ie := ComObject("InternetExplorer.Application")
69 | 
70 | ; Connects events to corresponding script functions with the prefix "IE_".
71 | ComObjConnect(ie, "IE_")
72 | 
73 | ie.Visible := true  ; This is known to work incorrectly on IE7.
74 | ie.Navigate("https://www.autohotkey.com/")
75 | Persistent
76 | 
77 | IE_DocumentComplete(ieEventParam, &url, ieFinalParam) {
78 |     ; IE passes url as a reference to a VARIANT, therefore &url is used above
79 |     ; so that the code below can refer to it naturally rather than as %url%.
80 |     s := ""
81 |     if (ie != ieEventParam)
82 |         s .= "First parameter is a new wrapper object.`n"
83 |     if (ie == ieFinalParam)
84 |         s .= "Final parameter is the original wrapper object.`n"
85 |     if (ComObjValue(ieEventParam) == ComObjValue(ieFinalParam))
86 |         s .= "Both wrapper objects refer to the same IDispatch instance.`n"
87 |     MsgBox s . "Finished loading " ie.Document.title " @ " url
88 |     ie.Quit()
89 |     ExitApp
90 | }
91 | 
92 |
93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /docs/lib/ComObjFlags.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjFlags - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ComObjFlags

15 |

Retrieves or changes flags which control a COM wrapper object's behaviour.

16 |
Flags := ComObjFlags(ComObj , NewFlags, Mask)
17 | 18 |

Parameters

19 |
20 | 21 |
ComObj
22 |
23 |

Type: Object

24 |

A COM wrapper object. See ComValue for details.

25 |
26 | 27 |
NewFlags
28 |
29 |

Type: Integer

30 |

New values for the flags identified by Mask, or flags to add or remove.

31 |
32 | 33 |
Mask
34 |
35 |

Type: Integer

36 |

A bitmask of flags to change.

37 |
38 | 39 |
40 | 41 |

Return Value

42 |

Type: Integer

43 |

This function returns the current flags of the specified COM object (after applying NewFlags, if specified).

44 | 45 |

Error Handling

46 |

A TypeError is thrown if ComObj is not a COM wrapper object.

47 | 48 |

Flags

49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 61 | 62 |
FlagEffect
1 57 |

F_OWNVALUE

58 |

SafeArray: If the flag is set, the SafeArray is destroyed when the wrapper object is freed. Since SafeArrays have no reference counting mechanism, if a SafeArray with this flag is assigned to an element of another SafeArray, a separate copy is created.

59 |

BSTR: If the flag is set, the BSTR is freed when the wrapper object is freed. The flag is set automatically when a BSTR is allocated as a result of type conversion performed by ComValue, such as ComValue(8, "example").

60 |
63 | 64 |

Remarks

65 |

If Mask is omitted, NewFlags specifies the flags to add (if positive) or remove (if negative). For example, ComObjFlags(obj, -1) removes the F_OWNVALUE flag. Do not specify any value for Mask other than 0 or 1; all other bits are reserved for future use.

66 | 67 | 68 |

ComValue, ComObjActive, ComObjArray

69 | 70 |

Examples

71 |
72 |

Checks for the presence of the F_OWNVALUE flag.

73 |
arr := ComObjArray(0xC, 1)
 74 | if ComObjFlags(arr) & 1
 75 |     MsgBox "arr will be automatically destroyed."
 76 | else
 77 |     MsgBox "arr will not be automatically destroyed."
 78 | 
79 |
80 | 81 |
82 |

Changes array-in-array behaviour.

83 |
arr1 := ComObjArray(0xC, 3)
 84 | arr2 := ComObjArray(0xC, 1)
 85 | arr2[0] := "original value"
 86 | arr1[0] := arr2         ; Assign implicit copy.
 87 | ComObjFlags(arr2, -1)   ; Remove F_OWNVALUE.
 88 | arr1[1] := arr2         ; Assign original array.
 89 | arr1[2] := arr2.Clone() ; Assign explicit copy.
 90 | arr2[0] := "new value"
 91 | for arr in arr1
 92 |     MsgBox arr[0]
 93 | 
 94 | arr1 := ""
 95 | ; Not valid since arr2 == arr1[1], which has been destroyed: 
 96 | ;  arr2[0] := "foo"
 97 | 
98 |
99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /docs/lib/ComObjFromPtr.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjFromPtr - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ComObjFromPtr

15 | 16 |

Wraps a raw IDispatch pointer (COM object) for use by the script.

17 |
ComObj := ComObjFromPtr(DispPtr)
18 | 19 |

Parameters

20 |
21 | 22 |
DispPtr
23 |
24 |

Type: Integer

25 |

A non-null interface pointer for IDispatch or a derived interface.

26 |
27 | 28 |
29 | 30 |

Return Value

31 |

Type: ComObject

32 |

Returns a wrapper object containing the variant type VT_DISPATCH and the given pointer.

33 |

Wrapping a COM object enables the script to interact with it more naturally, using object syntax. However, the majority of scripts do not need to do this manually since a wrapper object is created automatically by ComObject, ComObjActive, ComObjGet and any COM method which returns an object.

34 | 35 |

Remarks

36 |

The wrapper object assumes responsibility for automatically releasing the pointer when appropriate. This function queries the object for its IDispatch interface; if one is returned, DispPtr is immediately released. Therefore, if the script intends to use the pointer after calling this function, it must call ObjAddRef(DispPtr) first.

37 |

Known limitation: Each time a COM object is wrapped, a new wrapper object is created. Comparisons and assignments such as obj1 == obj2 and arr[obj1] := value treat the two wrapper objects as unique, even when they contain the same COM object.

38 | 39 | 40 |

ComObject, ComValue, ComObjGet, ComObjConnect, ComObjFlags, ObjAddRef/ObjRelease, ComObjQuery, GetActiveObject (Microsoft Docs)

41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/lib/ComObjGet.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjGet - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ComObjGet

14 |

Returns a reference to an object provided by a COM component.

15 |
ComObj := ComObjGet(Name)
16 | 17 |

Parameters

18 |
19 | 20 |
Name
21 |
22 |

Type: String

23 |

The display name of the object to be retrieved. See MkParseDisplayName (Microsoft Docs) for more information.

24 |
25 | 26 |
27 | 28 |

Return Value

29 |

Type: ComObject

30 |

This function returns a new COM wrapper object with the variant type VT_DISPATCH (9).

31 | 32 |

Error Handling

33 |

An exception is thrown on failure.

34 | 35 | 36 | ComObject, ComObjActive, ComObjConnect, ComObjQuery, CoGetObject (Microsoft Docs) 37 | 38 |

Examples

39 |
40 |

Press Shift+Esc to show the command line which was used to launch the active window's process. For Win32_Process, see Microsoft Docs.

41 |
+Esc::
42 | {
43 |     pid := WinGetPID("A")
44 |     ; Get WMI service object.
45 |     wmi := ComObjGet("winmgmts:")
46 |     ; Run query to retrieve matching process(es).
47 |     queryEnum := wmi.ExecQuery(""
48 |         . "Select * from Win32_Process where ProcessId=" . pid)
49 |         ._NewEnum()
50 |     ; Get first matching process.
51 |     if queryEnum(&proc)
52 |         MsgBox(proc.CommandLine, "Command line", 0)
53 |     else
54 |         MsgBox("Process not found!")
55 | }
56 |
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/lib/ComObjQuery.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjQuery - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ComObjQuery

14 |

Queries a COM object for an interface or service.

15 |
InterfaceComObj := ComObjQuery(ComObj, SID, IID)
 16 | InterfaceComObj := ComObjQuery(ComObj, IID)
17 | 18 |

Parameters

19 |
20 | 21 |
ComObj
22 |
23 |

Type: Object or Integer

24 |

A COM wrapper object, an interface pointer, or an object with a Ptr property which returns an interface pointer. See ComValue for details.

25 |
26 | 27 |
IID
28 |
29 |

Type: String

30 |

An interface identifier (GUID) in the form "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".

31 |
32 | 33 |
SID
34 |
35 |

Type: String

36 |

A service identifier in the same form as IID.

37 |
38 | 39 |
40 | 41 |

Return Value

42 |

Type: Object

43 |

This function returns a COM wrapper object of type dependent on the IID parameter.

44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
IIDClassVariant TypeDescription
IID_IDispatchComObjectVT_DISPATCH (9)Allows the script to call properties and methods of the object using normal object syntax.
Any other IIDComValueVT_UNKNOWN (13)Provides only a Ptr property, which allows the object to be passed to DllCall or ComCall.
59 | 60 |

Error Handling

61 |

An exception is thrown on failure, such as if the interface is not supported.

62 | 63 |

Remarks

64 |

In its two-parameter mode, this function is equivalent to IUnknown::QueryInterface. When SID and IID are both specified, it internally queries for the IServiceProvider interface, then calls IServiceProvider::QueryService.

65 |

ComCall can be used to call native interface methods.

66 | 67 | 68 |

ComCall, ComObject, ComObjGet, ComObjActive

69 | 70 |

Examples

71 |
72 |

Determines the class name of an object.

73 |
 74 | obj := ComObject("Scripting.Dictionary")
 75 | 
 76 | MsgBox "Interface name: " ComObjType(obj, "name")
 77 | 
 78 | IID_IProvideClassInfo := "{B196B283-BAB4-101A-B69C-00AA00341D07}"
 79 | 
 80 | ; Request the object's IProvideClassInfo interface.
 81 | try
 82 |     pci := ComObjQuery(obj, IID_IProvideClassInfo)
 83 | catch
 84 | {
 85 |     MsgBox "IProvideClassInfo interface not supported."
 86 |     return
 87 | }
 88 | 
 89 | ; Call GetClassInfo to retrieve a pointer to the ITypeInfo interface.
 90 | ComCall(3, pci, "ptr*", &ti := 0)
 91 | 
 92 | ; Wrap ti to ensure automatic cleanup.
 93 | ti := ComValue(13, ti)
 94 | 
 95 | ; Call GetDocumentation to get the object's full type name.
 96 | ComCall(12, ti, "int", -1, "ptr*", &pname := 0, "ptr", 0, "ptr", 0, "ptr", 0)
 97 | 
 98 | ; Convert the BSTR pointer to a usable string.
 99 | name := StrGet(pname, "UTF-16")
100 | 
101 | ; Clean up.
102 | DllCall("oleaut32\SysFreeString", "ptr", pname)
103 | pci := ti := ""
104 | 
105 | ; Display the type name!
106 | MsgBox "Class name: " name
107 | 
108 |
109 | 110 |
111 |

Automates an existing Internet Explorer window.

112 |
113 | sURL := "https://www.autohotkey.com/boards/"
114 | if WebBrowser := GetWebBrowser()
115 |     WebBrowser.Navigate(sURL)
116 | 
117 | GetWebBrowser()
118 | {
119 |     ; Get a raw pointer to the document object of the top-most IE window.
120 |     static msg := DllCall("RegisterWindowMessage", "Str", "WM_HTML_GETOBJECT")
121 |     lResult := SendMessage(msg, 0, 0, "Internet Explorer_Server1", "ahk_class IEFrame")
122 |     if !lResult
123 |         return  ; IE not found.
124 |     static IID_IHTMLDocument2 := GUID("{332C4425-26CB-11D0-B483-00C04FD90119}")
125 |     static VT_UNKNOWN := 13
126 |     DllCall("oleacc\ObjectFromLresult", "Ptr", lResult
127 |         , "Ptr", IID_IHTMLDocument2, "Ptr", 0
128 |         , "Ptr*", pdoc := ComValue(VT_UNKNOWN, 0))
129 |     
130 |     ; Query for the WebBrowserApp service. In this particular case,
131 |     ; the SID and IID are the same, but it isn't always this way.
132 |     static IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
133 |     static SID_SWebBrowserApp := IID_IWebBrowserApp
134 |     pweb := ComObjQuery(pdoc, SID_SWebBrowserApp, IID_IWebBrowserApp)
135 |     
136 |     ; Return the WebBrowser object as IDispatch for usability.
137 |     ; This works only because IWebBrowserApp is derived from IDispatch.
138 |     ; pweb will release its ptr automatically, so AddRef to counter that.
139 |     ObjAddRef(pweb.ptr)
140 |     static VT_DISPATCH := 9
141 |     return ComValue(VT_DISPATCH, pweb.ptr)
142 | }
143 | 
144 | GUID(sGUID) ; Converts a string to a binary GUID and returns it in a Buffer.
145 | {
146 |     GUID := Buffer(16, 0)
147 |     if DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", GUID) < 0
148 |         throw ValueError("Invalid parameter #1", -1, sGUID)
149 |     return GUID
150 | }
151 | 
152 |
153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /docs/lib/ComObjType.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjType - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ComObjType

14 | 15 |

Retrieves type information from a COM object.

16 | 17 |
Info := ComObjType(ComObj , InfoType)
18 | 19 |

Parameters

20 |
21 | 22 |
ComObj
23 |
24 |

Type: Object

25 |

A wrapper object containing a COM object or typed value. See ComValue for details.

26 |
27 | 28 |
InfoType
29 |
30 |

Type: String

31 |

If omitted, an integer variant type code indicating the type of value contained by the COM wrapper object will be retrieved. Otherwise, specify one of the following strings indicating the type information to retrieve:

32 |

Name: The name of the object's default interface.

33 |

IID: The globally unique identifier (GUID) of the object's default interface.

34 |

Class: The object's class name. Note that this is not the same as a Prog ID (a Prog ID is a name used to identify the class in the system registry, or for ComObject).

35 |

CLSID: The globally unique identifier (GUID) of the object's class. Classes are often registered by CLSID under the HKCR\CLSID registry key.

36 |
37 | 38 |
39 | 40 |

Return Value

41 |

Type: Integer or String

42 |

The return value depends on the value of InfoType. An empty string is returned if either parameter is invalid or if the requested type information could not be retrieved.

43 | 44 |

Variant Type Constants

45 |

COM uses the following values to identify basic data types:

46 |
 47 | VT_EMPTY     :=      0  ; No value
 48 | VT_NULL      :=      1  ; SQL-style Null
 49 | VT_I2        :=      2  ; 16-bit signed int
 50 | VT_I4        :=      3  ; 32-bit signed int
 51 | VT_R4        :=      4  ; 32-bit floating-point number
 52 | VT_R8        :=      5  ; 64-bit floating-point number
 53 | VT_CY        :=      6  ; Currency
 54 | VT_DATE      :=      7  ; Date
 55 | VT_BSTR      :=      8  ; COM string (Unicode string with length prefix)
 56 | VT_DISPATCH  :=      9  ; COM object
 57 | VT_ERROR     :=    0xA  ; Error code (32-bit integer)
 58 | VT_BOOL      :=    0xB  ; Boolean True (-1) or False (0)
 59 | VT_VARIANT   :=    0xC  ; VARIANT (must be combined with VT_ARRAY or VT_BYREF)
 60 | VT_UNKNOWN   :=    0xD  ; IUnknown interface pointer
 61 | VT_DECIMAL   :=    0xE  ; (not supported)
 62 | VT_I1        :=   0x10  ; 8-bit signed int
 63 | VT_UI1       :=   0x11  ; 8-bit unsigned int
 64 | VT_UI2       :=   0x12  ; 16-bit unsigned int
 65 | VT_UI4       :=   0x13  ; 32-bit unsigned int
 66 | VT_I8        :=   0x14  ; 64-bit signed int
 67 | VT_UI8       :=   0x15  ; 64-bit unsigned int
 68 | VT_INT       :=   0x16  ; Signed machine int
 69 | VT_UINT      :=   0x17  ; Unsigned machine int
 70 | VT_RECORD    :=   0x24  ; User-defined type -- NOT SUPPORTED
 71 | VT_ARRAY     := 0x2000  ; SAFEARRAY
 72 | VT_BYREF     := 0x4000  ; Pointer to another type of value
 73 | /*
 74 |  VT_ARRAY and VT_BYREF are combined with another value (using bitwise OR)
 75 |  to specify the exact type. For instance, 0x2003 identifies a SAFEARRAY
 76 |  of 32-bit signed integers and 0x400C identifies a pointer to a VARIANT.
 77 | */
 78 | 
79 | 80 |

General Remarks

81 |

In most common cases, return values from methods or properties of COM objects are converted to an appropriate data type supported by AutoHotkey. Types which aren't specifically handled are coerced to strings via VariantChangeType; if this fails or if the variant type contains the VT_ARRAY or VT_BYREF flag, an object containing both the value and its type is returned instead.

82 |

For any variable x, if ComObjType(x) returns an integer, x contains a COM object wrapper.

83 |

If InfoType is "Name" or "IID", type information is retrieved via the IDispatch::GetTypeInfo interface method. ComObj's variant type must be VT_DISPATCH.

84 |

If InfoType is "Class" or "CLSID", type information is retrieved via the IProvideClassInfo::GetClassInfo interface method. ComObj's variant type must be VT_DISPATCH or VT_UNKNOWN, and the object must implement the IProvideClassInfo interface (some objects do not).

85 | 86 | 87 |

ComObjValue, ComValue, ComObject, ComObjGet, ComObjActive

88 | 89 |

Examples

90 |
91 |

Reports various type information of a COM object.

92 |
 93 | d := ComObject("Scripting.Dictionary")
 94 | MsgBox
 95 | (
 96 |     "Variant type:`t" ComObjType(d) "
 97 |     Interface name:`t" ComObjType(d, "Name") "
 98 |     Interface ID:`t" ComObjType(d, "IID") "
 99 |     Class name:`t" ComObjType(d, "Class") "
100 |     Class ID (CLSID):`t" ComObjType(d, "CLSID")
101 | )
102 |
103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /docs/lib/ComObjValue.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObjValue - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ComObjValue

14 | 15 |

Retrieves the value or pointer stored in a COM wrapper object.

16 | 17 |
Value := ComObjValue(ComObj)
18 | 19 |

Parameters

20 |
21 | 22 |
ComObj
23 |
24 |

Type: Object

25 |

A wrapper object containing a COM object or typed value. See ComValue for details.

26 |
27 | 28 |
29 | 30 |

Return Value

31 |

Type: Integer

32 |

This function returns a 64-bit signed integer.

33 | 34 |

Error Handling

35 |

A TypeError is thrown if ComObj is not a COM wrapper object.

36 | 37 |

Remarks

38 |

This function is not intended for general use.

39 |

Calling ComObjValue is equivalent to variant.llVal, where ComObj is treated as a VARIANT structure. Any script which uses this function must be aware what type of value the wrapper object contains and how it should be treated. For instance, if an interface pointer is returned, Release should not be called, but AddRef may be required depending on what the script does with the pointer.

40 | 41 | 42 |

ComObjType, ComObject, ComObjGet, ComObjActive

43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/lib/ComObject.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComObject - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ComObject

15 |

Creates a COM object.

16 |
ComObj := ComObject(CLSID , IID)
17 |

ComObject itself is a class derived from ComValue, but is used only to create or identify COM objects.

18 | 19 |

Parameters

20 |
21 | 22 |
CLSID
23 |
24 |

Type: String

25 |

CLSID or human-readable Prog ID of the COM object to create.

26 |
27 | 28 |
IID
29 |
30 |

Type: String

31 |

If omitted, it defaults to "{00020400-0000-0000-C000-000000000046}" (IID_IDispatch). Otherwise, specify the identifier of the interface to return. In most cases this is omitted.

32 |
33 | 34 |
35 | 36 |

Return Value

37 |

Type: Object

38 |

This function returns a COM wrapper object of type dependent on the IID parameter.

39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
IIDClassVariant TypeDescription
IID_IDispatchComObjectVT_DISPATCH (9)Allows the script to call properties and methods of the object using normal object syntax.
Any other IIDComValueVT_UNKNOWN (13)Provides only a Ptr property, which allows the object to be passed to DllCall or ComCall.
54 | 55 |

Error Handling

56 |

An exception is thrown on failure, such as if a parameter is invalid or the object does not support the interface specified by IID.

57 | 58 | 59 |

ComValue, ComObjGet, ComObjActive, ComObjConnect, ComObjArray, ComObjQuery, ComCall, CreateObject (Microsoft Docs)

60 | 61 |

Examples

62 |

For a long list of v1.1 examples, see this archived forum thread.

63 |
64 |

Launches an instance of Internet Explorer, makes it visible and navigates to a website.

65 |
ie := ComObject("InternetExplorer.Application")
66 | ie.Visible := true  ; This is known to work incorrectly on IE7.
67 | ie.Navigate("https://www.autohotkey.com/")
68 | 
69 |
70 |
71 |

Retrieves the path of the desktop's current wallpaper.

72 |
73 | AD_GETWP_BMP := 0
74 | AD_GETWP_LAST_APPLIED := 0x00000002
75 | CLSID_ActiveDesktop := "{75048700-EF1F-11D0-9888-006097DEACF9}"
76 | IID_IActiveDesktop := "{F490EB00-1240-11D1-9888-006097DEACF9}"
77 | cchWallpaper := 260
78 | GetWallpaper := 4
79 | 
80 | AD := ComObject(CLSID_ActiveDesktop, IID_IActiveDesktop)
81 | wszWallpaper := Buffer(cchWallpaper * 2)
82 | ComCall(GetWallpaper, AD, "ptr", wszWallpaper, "uint", cchWallpaper, "uint", AD_GETWP_LAST_APPLIED)
83 | Wallpaper := StrGet(wszWallpaper, "UTF-16")
84 | MsgBox "Wallpaper: " Wallpaper
85 | 
86 |
87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /docs/lib/ComValue.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ComValue - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ComValue

15 | 16 |

Wraps a value, SafeArray or COM object for use by the script or for passing to a COM method.

17 |
ComObj := ComValue(VarType, Value , Flags)
18 |

ComValue itself is a class derived from Any, but is used only to create or identify COM wrapper objects.

19 | 20 |

Parameters

21 |
22 | 23 |
VarType
24 |
25 |

Type: Integer

26 |

An integer indicating the type of value. See ComObjType for a list of types.

27 |
28 | 29 |
Value
30 |
31 |

Type: Any

32 |

The value to wrap.

33 |

If this is a pure integer and VarType is not VT_R4, VT_R8, VT_DATE or VT_CY, its value is used directly; in particular, VT_BSTR, VT_DISPATCH and VT_UNKNOWN can be initialized with a pointer value.

34 |

In any other case, the value is copied into a temporary VARIANT using the same rules as normal COM methods calls. If the source variant type is not equal to VarType, conversion is attempted by calling VariantChangeType with a wFlags value of 0. An exception is thrown if conversion fails.

35 |
36 | 37 |
Flags
38 |
39 |

Type: Integer

40 |

Flags affecting the behaviour of the wrapper object; see ComObjFlags for details.

41 |
42 | 43 |
44 | 45 |

Return Value

46 |

Type: Object

47 |

This function returns a wrapper object containing a variant type and value or pointer, specifically ComValue, ComValueRef, ComObjArray or ComObject.

48 |

This object has multiple uses:

49 |
    50 |
  1. Some COM methods may require specific types of values which have no direct equivalent within AutoHotkey. This function allows the type of a value to be specified when passing it to a COM method. For example, ComValue(0xB, true) creates an object which represents the COM boolean value true.
  2. 51 |
  3. Wrapping a COM object or SafeArray enables the script to interact with it more naturally, using object syntax. However, the majority of scripts do not need to do this manually since a wrapper object is created automatically by ComObject, ComObjArray, ComObjActive, ComObjGet and any COM method which returns an object.
  4. 52 |
  5. Wrapping a COM interface pointer allows the script to take advantage of automatic reference counting. An interface pointer can be wrapped immediately upon being returned to the script (typically from ComCall or DllCall), avoiding the need to explicitly release it at some later point.
  6. 53 |
54 | 55 |

Ptr

56 |

If a wrapper object's VarType is VT_UNKNOWN (13) or includes the VT_BYREF (0x4000) flag or VT_ARRAY (0x2000) flag, the Ptr property can be used to retrieve the address of the object, typed variable or SafeArray. This allows the ComObject itself to be passed to any DllCall or ComCall parameter which has the "Ptr" type, but can also be used explicitly. For example, ComObj.Ptr is equivalent to ComObjValue(ComObj) in these cases.

57 |

If a wrapper object's VarType is VT_UNKNOWN (13) or VT_DISPATCH (9) and the wrapped pointer is null (0), the Ptr property can be used to retrieve the current null value or to assign a pointer to the wrapper object. Once assigned (if non-null), the pointer will be released automatically when the wrapper object is freed. This can be used with DllCall or ComCall output parameters of type "Ptr*" or "PtrP" to ensure the pointer will be released automatically, such as if an error occurs. For an example, see ComObjQuery.

58 |

When a wrapper object with VarType VT_DISPATCH (9) and a null (0) pointer value is assigned a non-null pointer value, its type changes from ComValue to ComObject. The properties and methods of the wrapped object become available and the Ptr property becomes unavailable.

59 | 60 |

ByRef

61 |

If a wrapper object's VarType includes the VT_BYREF (0x4000) flag, empty brackets [] can be used to read or write the referenced value.

62 |

When creating a reference, Value must be the memory address of a variable or buffer with sufficient capacity to store a value of the given type. For example, the following can be used to create a variable which a VBScript function can write into:

63 |
vbuf := Buffer(24, 0)
 64 | vref := ComValue(0x400C, vbuf.ptr)  ; 0x400C is a combination of VT_BYREF and VT_VARIANT.
 65 | 
 66 | vref[] := "in value"
 67 | sc.Run("Example", vref)  ; sc should be initialized as in the example below.
 68 | MsgBox vref[]
69 |

Note that although any previous value is freed when a new value is assigned by vref[] or the COM method, the final value is not freed automatically. Freeing the value requires knowing which type it is. Because it is VT_VARIANT in this case, it can be freed by calling VariantClear with DllCall or by using a simpler method: assign an integer, such as vref[] := 0.

70 |

If the method accepts a combination of VT_BYREF and VT_VARIANT as shown above, a VarRef can be used instead. For example:

71 |
some_var := "in value"
 72 | sc.Run("Example", &some_var)
 73 | MsgBox some_var
74 |

However, some methods require a more specific variant type, such as VT_BYREF | VT_I4. In such cases, the first approach shown above must be used, replacing 0x400C with the appropriate variant type.

75 | 76 |

General Remarks

77 |

When this function is used to wrap an IDispatch or IUnknown interface pointer (passed as an integer), the wrapper object assumes responsibility for automatically releasing the pointer when appropriate. Therefore, if the script intends to use the pointer after calling this function, it must call ObjAddRef(DispPtr) first. By contrast, this is not necessary if Value is itself a ComValue or ComObject.

78 |

Conversion from VT_UNKNOWN to VT_DISPATCH results in a call to IUnknown::QueryInterface, which may produce an interface pointer different to the original, and will throw an exception if the object does not implement IDispatch. By contrast, if Value is an integer and VarType is VT_DISPATCH, the value is used directly, and therefore must be an IDispatch-compatible interface pointer.

79 |

The VarType of a wrapper object can be retrieved using ComObjType.

80 |

The Value of a wrapper object can be retrieved using ComObjValue.

81 |

Known limitation: Each time a COM object is wrapped, a new wrapper object is created. Comparisons and assignments such as obj1 == obj2 and arr[obj1] := value treat the two wrapper objects as unique, even when they contain the same variant type and value.

82 | 83 | 84 |

ComObjFromPtr, ComObject, ComObjGet, ComObjConnect, ComObjFlags, ObjAddRef/ObjRelease, ComObjQuery, GetActiveObject (Microsoft Docs)

85 | 86 |

Examples

87 |
88 |

Passes a VARIANT ByRef to a COM function.

89 |
 90 | #Requires AutoHotkey v2 32-bit ; 32-bit for ScriptControl.
 91 | code := "
 92 | (
 93 | Sub Example(Var)
 94 |     MsgBox Var
 95 |     Var = "out value!"
 96 | End Sub
 97 | )"
 98 | sc := ComObject("ScriptControl"), sc.Language := "VBScript", sc.AddCode(code)
 99 | 
100 | 
101 | ; Example: Pass a VARIANT ByRef to a COM method.
102 | var := ComVar()
103 | var[] := "in value"
104 | sc.Run("Example", var.ref)
105 | MsgBox var[]
106 | 
107 | ; The same thing again, but more direct:
108 | variant_buf := Buffer(24, 0)  ; Make a buffer big enough for a VARIANT.
109 | var := ComValue(0x400C, variant_buf.ptr)  ; Make a reference to a VARIANT.
110 | var[] := "in value"
111 | sc.Run("Example", var)  ; Pass the VT_BYREF ComValue itself, no [] or .ref.
112 | MsgBox var[]
113 | ; If a VARIANT contains a string or object, it must be explicitly freed
114 | ; by calling VariantClear or assigning a pure numeric value:
115 | var[] := 0
116 | 
117 | ; The simplest way when the method accepts VT_BYREF|VT_VARIANT:
118 | var := "in value"
119 | sc.Run("Example", &var)
120 | MsgBox var
121 | 
122 | 
123 | ; ComVar: An object which can be used to pass a value ByRef.
124 | ;   this[] retrieves the value.
125 | ;   this[] := Val sets the value.
126 | ;   this.ref retrieves a ByRef object for passing to a COM method.
127 | class ComVar {
128 |     __new(vType := 0xC) {
129 |         ; Allocate memory for a VARIANT to hold our value. VARIANT is used even
130 |         ; when vType != VT_VARIANT so that VariantClear can be used by __delete.
131 |         this.var := Buffer(24, 0)
132 |         ; Create an object which can be used to pass the variable ByRef.
133 |         this.ref := ComValue(0x4000|vType, this.var.ptr + (vType=0xC ? 0 : 8))
134 |         ; Store the variant type for VariantClear (if not VT_VARIANT).
135 |         if vType != 0xC
136 |             NumPut "ushort", vType, this.var
137 |     }
138 |     __item {
139 |         get => this.ref[]
140 |         set => this.ref[] := value
141 |     }
142 |     __delete() {
143 |         DllCall("oleaut32\VariantClear", "ptr", this.var)
144 |     }
145 | }
146 | 
147 |
148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /docs/lib/Continue.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Continue - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Continue

14 |

Skips the rest of a loop statement's current iteration and begins a new one.

15 |
Continue LoopLabel
16 | 17 |

Parameters

18 |
19 |
LoopLabel
20 |
21 |

If omitted or 1, this statement applies to the innermost loop in which it is enclosed. Otherwise, specify which loop this statement should apply to; either by label name or numeric nesting level. If a label is specified, it must point directly at a loop statement.

22 |

LoopLabel must be a constant value - variables and expressions are not supported, with the exception of a single literal number or quoted string enclosed in parentheses. For example: continue("outer")

23 |
24 |
25 | 26 |

Remarks

27 |

Continue behaves the same as reaching the loop's closing brace:

28 |
    29 |
  1. It increases A_Index by 1.
  2. 30 |
  3. It skips the rest of the loop's body.
  4. 31 |
  5. The loop's condition (if it has one) is checked to see if it is satisfied. If so, a new iteration begins; otherwise the loop ends.
  6. 32 |
33 |

The use of Break and Continue are encouraged over Goto since they usually make scripts more readable and maintainable.

34 | 35 | 36 |

Break, Loop, Until, While-loop, For-loop, Blocks, Labels

37 | 38 |

Examples

39 |
40 |

Displays 5 message boxes, one for each number between 6 and 10. Note that in the first 5 iterations of the loop, the Continue statement causes the loop to start over before it reaches the MsgBox line.

41 |
42 | Loop 10
43 | {
44 |     if (A_Index <= 5)
45 |         continue
46 |     MsgBox A_Index
47 | }
48 |
49 | 50 |
51 |

Continues the outer loop from within a nested loop.

52 |
outer:
53 | Loop 3
54 | {
55 |     x := A_Index
56 |     Loop 3
57 |     {
58 |         if (x*A_Index = 4)
59 |             continue outer  ; Equivalent to continue 2 or goto continue_outer.
60 |         MsgBox x "," A_Index
61 |     }
62 |     continue_outer: ; For goto.
63 | }
64 |
65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/lib/Control.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | List of Control Functions | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Control Functions

14 | 15 |

Functions for retrieving information about a control or for performing various operations on a control. Click on a function name for details.

16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 |
FunctionDescription
ControlAddItemAdds the specified string as a new entry at the bottom of a ListBox or ComboBox.
ControlChooseIndexSets the selection in a ListBox, ComboBox or Tab control to be the Nth item.
ControlChooseStringSets the selection in a ListBox or ComboBox to be the first entry whose leading part matches the specified string.
ControlClickSends a mouse button or mouse wheel event to a control.
ControlDeleteItemDeletes the specified entry number from a ListBox or ComboBox.
ControlFindItemReturns the entry number of a ListBox or ComboBox that is a complete match for the specified string.
ControlFocusSets input focus to a given control on a window.
ControlGetCheckedReturns a non-zero value if the checkbox or radio button is checked.
ControlGetChoiceReturns the name of the currently selected entry in a ListBox or ComboBox.
ControlGetClassNNReturns the ClassNN (class name and sequence number) of the specified control.
ControlGetEnabledReturns a non-zero value if the specified control is enabled.
ControlGetFocusRetrieves which control of the target window has keyboard focus, if any.
ControlGetHwndReturns the unique ID number of the specified control.
ControlGetIndexReturns the index of the currently selected entry or tab in a ListBox, ComboBox or Tab control.
ControlGetItemsReturns an array of items/rows from a ListBox, ComboBox, or DropDownList.
ControlGetPosRetrieves the position and size of a control.
ControlGetStyle
ControlGetExStyle
Returns an integer representing the style or extended style of the specified control.
ControlGetTextRetrieves text from a control.
ControlGetVisibleReturns a non-zero value if the specified control is visible.
ControlHideHides the specified control.
ControlHideDropDownHides the drop-down list of a ComboBox control.
ControlMoveMoves or resizes a control.
ControlSend
ControlSendText
Sends simulated keystrokes or text to a window or control.
ControlSetCheckedTurns on (checks) or turns off (unchecks) a checkbox or radio button.
ControlSetEnabledEnables or disables the specified control.
ControlSetStyle
ControlSetExStyle
Changes the style or extended style of the specified control, respectively.
ControlSetTextChanges the text of a control.
ControlShowShows the specified control if it was previously hidden.
ControlShowDropDownShows the drop-down list of a ComboBox control.
EditGetCurrentColReturns the column number in an Edit control where the caret (text insertion point) resides.
EditGetCurrentLineReturns the line number in an Edit control where the caret (text insert point) resides.
EditGetLineReturns the text of the specified line in an Edit control.
EditGetLineCountReturns the number of lines in an Edit control.
EditGetSelectedTextReturns the selected text in an Edit control.
EditPastePastes the specified string at the caret (text insertion point) in an Edit control.
ListViewGetContentReturns a list of items/rows from a ListView.
166 | 167 |

The Control Parameter

168 |

Functions which operate on individual controls have a parameter named Control which supports a few different ways to identify the control. The Control parameter can be one of the following:

169 |

ClassNN (String): The ClassNN (classname and instance number) of the control, which can be determined via Window Spy. For example "Edit1" is the first control with classname "Edit".

170 |

Text (String): The control's text. The matching behavior is determined by SetTitleMatchMode.

171 |

HWND (Integer): The control's HWND, which is typically retrieved via ControlGetHwnd, MouseGetPos, or DllCall. This also works on hidden controls even when DetectHiddenWindows is Off. Any subsequent window parameters are ignored.

172 |

Object: An object of any type with a Hwnd property, such as a GuiControl. A PropertyError is thrown if the object has no Hwnd property, or TypeError if it does not return a pure integer. Any subsequent window parameters are ignored.

173 |

Omitted: A few functions are able to operate on either a control or a top-level window. Omitting the Control parameter causes the function to use the target window (specified by WinTitle) instead of one of its controls. For example, ControlSend can send keyboard messages directly to the window.

174 | 175 |

Error Handling

176 |

Typically one of the following errors may be thrown:

177 | 182 | 183 |

Remarks

184 |

To improve reliability, a delay is done automatically after each use of a Control function that changes a control (except for ControlSetStyle and ControlSetExStyle). That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

185 |

To discover the ClassNN or HWND of the control that the mouse is currently hovering over, use MouseGetPos.

186 |

To retrieve an array of all controls in a window, use WinGetControls or WinGetControlsHwnd.

187 | 188 | 189 |

SetControlDelay, Win functions, GuiControl object (for controls created by the script)

190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /docs/lib/ControlAddItem.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlAddItem - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlAddItem

15 | 16 |

Adds the specified string as a new entry at the bottom of a ListBox or ComboBox.

17 | 18 |
ControlAddItem String, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
String
23 |
24 |

Type: String

25 |

The string to add.

26 |
27 |
Control
28 |
29 |

Type: String, Integer or Object

30 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

31 |
32 |
WinTitle, WinText, ExcludeTitle, ExcludeText
33 |
34 |

Type: String, Integer or Object

35 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

36 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

37 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

38 |
39 |
40 | 41 |

Return Value

42 |

Type: Integer

43 |

This function returns the index of the new item, where 1 is the first item, 2 is the second, etc.

44 | 45 |

Error Handling

46 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo" or "List".

47 |

An Error or OSError is thrown if the item could not be added.

48 | 49 |

Remarks

50 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

51 | 52 | 53 |

ControlDeleteItem, ControlFindItem, Add method (GuiControl object), Control functions

54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/lib/ControlChooseIndex.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlChooseIndex - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlChooseIndex

15 | 16 |

Sets the selection in a ListBox, ComboBox or Tab control to be the Nth item.

17 | 18 |
ControlChooseIndex N, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
N
23 |
24 |

Type: Integer

25 |

The index of the item, where 1 is the first item, 2 is the second, etc. To deselect all entries in a ListBox or ComboBox, specify 0.

26 |
27 |
Control
28 |
29 |

Type: String, Integer or Object

30 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

31 |
32 |
WinTitle, WinText, ExcludeTitle, ExcludeText
33 |
34 |

Type: String, Integer or Object

35 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

36 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

37 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

38 |
39 |
40 | 41 |

Error Handling

42 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo", "List" or "Tab".

43 |

An Error or OSError is thrown if the change could not be applied.

44 | 45 |

Remarks

46 |

To select all items in a multi-select listbox, follow this example:

47 |
PostMessage(0x0185, 1, -1, "ListBox1", WinTitle)  ; Select all listbox items. 0x0185 is LB_SETSEL.
48 |

Unlike GuiControl.Choose(), this function raises a Change or DoubleClick event.

49 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

50 | 51 | 52 |

ControlGetIndex, ControlChooseString, Choose method (GuiControl object), Control functions

53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /docs/lib/ControlChooseString.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlChooseString - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlChooseString

15 | 16 |

Sets the selection in a ListBox or ComboBox to be the first entry whose leading part matches the specified string.

17 | 18 |
ControlChooseString String, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
String
23 |
24 |

Type: String

25 |

The string to choose. The search is not case-sensitive. For example, if a ListBox/ComboBox contains the item "UNIX Text", specifying the word unix (lowercase) would be enough to select it.

26 |
27 |
Control
28 |
29 |

Type: String, Integer or Object

30 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

31 |
32 |
WinTitle, WinText, ExcludeTitle, ExcludeText
33 |
34 |

Type: String, Integer or Object

35 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

36 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

37 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

38 |
39 |
40 | 41 |

Return Value

42 |

Type: Integer

43 |

This function returns the index of the chosen item, where 1 is the first item, 2 is the second, etc.

44 | 45 |

Error Handling

46 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo" or "List".

47 |

An Error or OSError is thrown if the change could not be applied.

48 | 49 |

Remarks

50 |

Unlike GuiControl.Choose(), this function raises a Change or DoubleClick event.

51 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

52 | 53 | 54 |

ControlChooseIndex, ControlGetChoice, Choose method (GuiControl object), Control functions

55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/lib/ControlClick.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlClick - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlClick

14 | 15 |

Sends a mouse button or mouse wheel event to a control.

16 | 17 |
ControlClick Control-or-Pos, WinTitle, WinText, WhichButton, ClickCount, Options, ExcludeTitle, ExcludeText
18 |

Parameters

19 |
20 | 21 |
Control-or-Pos
22 |
23 |

Type: String, Integer or Object

24 |

If omitted, the target window itself will be clicked. Otherwise, use one of the following modes.

25 |

Mode 1 (Position): Specify the X and Y coordinates relative to the upper left corner of the target window's client area. The X coordinate must precede the Y coordinate and there must be at least one space or tab between them. For example: "X55 Y33". If there is a control at the specified coordinates, it will be sent the click-event at those exact coordinates. If there is no control, the target window itself will be sent the event (which might have no effect depending on the nature of the window).

26 |

Note: In mode 1, the X and Y option letters of the Options parameter are ignored.

27 |

Mode 2 (Control): Specify the control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

28 |

By default, mode 2 takes precedence over mode 1. For example, in the unlikely event that there is a control whose text or ClassNN has the format "Xnnn Ynnn", it would be acted upon by mode 2. To override this and use mode 1 unconditionally, specify the word Pos in Options as in the following example: ControlClick "x255 y152", WinTitle,,,, "Pos".

29 |
30 | 31 |
WinTitle, WinText, ExcludeTitle, ExcludeText
32 |
33 |

Type: String, Integer or Object

34 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

35 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

36 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

37 |
38 | 39 |
WhichButton
40 |
41 |

Type: String

42 |

If blank or omitted, it defaults to Left (the left mouse button). Otherwise, specify the button to click or the rotate/push direction of the mouse wheel.

43 |

Button: Left, Right, Middle (or just the first letter of each of these); or X1 (fourth button) or X2 (fifth button).

44 |

Mouse wheel: Specify WheelUp or WU to turn the wheel upward (away from you); specify WheelDown or WD to turn the wheel downward (toward you). Specify WheelLeft (or WL) or WheelRight (or WR) to push the wheel left or right, respectively. ClickCount is the number of notches to turn the wheel.

45 |
46 | 47 |
ClickCount
48 |
49 |

Type: Integer

50 |

If omitted, it defaults to 1. Otherwise, specify the number of times to click the mouse button or turn the mouse wheel.

51 |
52 | 53 |
Options
54 |
55 |

Type: String

56 |

If blank or omitted, each click consists of a down-event followed by an up-event, and occurs at the center of the control when mode 2 is in effect. Otherwise, specify a series of one or more of the following options. For example: "d x50 y25".

57 |

NA: May improve reliability. See reliability below.

58 |

D: Press the mouse button down but do not release it (i.e. generate a down-event). If both the D and U options are absent, a complete click (down and up) will be sent.

59 |

U: Release the mouse button (i.e. generate an up-event). This option should not be present if the D option is already present (and vice versa).

60 |

Pos: Specify the word Pos anywhere in Options to unconditionally use the X/Y positioning mode as described in the Control-or-Pos parameter above.

61 |

Xn: Specify for n the X position to click at, relative to the control's upper left corner. If unspecified, the click will occur at the horizontal-center of the control.

62 |

Yn: Specify for n the Y position to click at, relative to the control's upper left corner. If unspecified, the click will occur at the vertical-center of the control.

63 |

Use decimal (not hexadecimal) numbers for the X and Y options.

64 |
65 | 66 |
67 | 68 |

Error Handling

69 |

An exception is thrown in the following cases:

70 | 76 | 77 |

Reliability

78 |

To improve reliability -- especially during times when the user is physically moving the mouse during the ControlClick -- one or both of the following may help:

79 |

1) Use SetControlDelay -1 prior to ControlClick. This avoids holding the mouse button down during the click, which in turn reduces interference from the user's physical movement of the mouse.

80 |

2) Specify the string NA anywhere in the sixth parameter (Options) as shown below:

81 |
SetControlDelay -1
 82 | ControlClick "Toolbar321", WinTitle,,,, "NA"
83 |

The NA option avoids marking the target window as active and avoids merging its input processing with that of the script, which may prevent physical movement of the mouse from interfering (but usually only when the target window is not active). However, this method might not work for all types of windows and controls.

84 |

Remarks

85 |

Not all applications obey a ClickCount higher than 1 for turning the mouse wheel. For those applications, use a loop to turn the wheel more than one notch as in this example, which turns it 5 notches:

86 |
Loop 5
 87 |     ControlClick Control, WinTitle, WinText, "WheelUp"
88 | 89 | 90 |

SetControlDelay, Control functions, Click

91 |

Examples

92 |
93 |

Clicks the OK button.

94 |
ControlClick "OK", "Some Window Title"
95 |
96 | 97 |
98 |

Clicks at a set of coordinates. Note the lack of a comma between X and Y.

99 |
ControlClick "x55 y77", "Some Window Title"
100 |
101 | 102 |
103 |

Clicks in NA mode at coordinates that are relative to a named control.

104 |
SetControlDelay -1  ; May improve reliability and reduce side effects.
105 | ControlClick "Toolbar321", "Some Window Title",,,, "NA x192 y10"
106 |
107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /docs/lib/ControlDeleteItem.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlDeleteItem - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlDeleteItem

15 | 16 |

Deletes the specified entry number from a ListBox or ComboBox.

17 | 18 |
ControlDeleteItem N, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
N
23 |
24 |

Type: Integer

25 |

The index of the item, where 1 is the first entry, 2 is the second, etc.

26 |
27 |
Control
28 |
29 |

Type: String, Integer or Object

30 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

31 |
32 |
WinTitle, WinText, ExcludeTitle, ExcludeText
33 |
34 |

Type: String, Integer or Object

35 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

36 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

37 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

38 |
39 |
40 | 41 |

Error Handling

42 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo" or "List".

43 |

An Error or OSError is thrown if the item could not be deleted.

44 | 45 |

Remarks

46 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

47 | 48 | 49 |

ControlAddItem, ControlFindItem, Delete method (GuiControl object), Control functions

50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /docs/lib/ControlFindItem.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlFindItem - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlFindItem

15 | 16 |

Returns the entry number of a ListBox or ComboBox that is a complete match for the specified string.

17 | 18 |
FoundItem := ControlFindItem(String, Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
String
23 |
24 |

Type: String

25 |

The string to find. The search is case-insensitive. Unlike ControlChooseString, the entry's entire text must match, not just the leading part.

26 |
27 |
Control
28 |
29 |

Type: String, Integer or Object

30 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

31 |
32 |
WinTitle, WinText, ExcludeTitle, ExcludeText
33 |
34 |

Type: String, Integer or Object

35 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

36 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

37 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

38 |
39 |
40 | 41 |

Return Value

42 |

Type: Integer

43 |

This function returns the entry number of a ListBox or ComboBox that is a complete match for String. The first entry in the control is 1, the second 2, and so on. If no match is found, an exception is thrown.

44 | 45 |

Error Handling

46 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo" or "List".

47 |

An Error is thrown if the item could not be found.

48 | 49 |

Remarks

50 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

51 | 52 | 53 |

ControlAddItem, ControlDeleteItem, Control functions

54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/lib/ControlFocus.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlFocus - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlFocus

14 | 15 |

Sets input focus to a given control on a window.

16 | 17 |
ControlFocus Control , WinTitle, WinText, ExcludeTitle, ExcludeText
18 | 19 |

Parameters

20 |
21 |
Control
22 |
23 |

Type: String, Integer or Object

24 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

25 |
26 |
WinTitle, WinText, ExcludeTitle, ExcludeText
27 |
28 |

Type: String, Integer or Object

29 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

30 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

31 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

32 |
33 | 34 |
35 | 36 |

Error Handling

37 |

A TargetError is thrown if the window or control could not be found.

38 | 39 |

Remarks

40 |

To be effective, the control's window generally must not be minimized or hidden.

41 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

42 |

When a control is focused in response to user input (such as pressing the Tab key), the dialog manager applies additional effects which are independent of the control having focus. These effects are not applied by ControlFocus, and therefore the following limitations apply:

43 | 48 |

The WM_NEXTDLGCTL message can be used to focus the control and apply these additional effects. For example:

49 |
WinExist("A") ; Set the Last Found Window to the active window
50 | hWndControl := ControlGetHwnd("Button1")  ; Get HWND of first Button
51 | SendMessage 0x0028, hWndControl, True  ; 0x0028 is WM_NEXTDLGCTL
52 | 53 | 54 |

SetControlDelay, ControlGetFocus, Control functions

55 |

Examples

56 |
57 |

Sets the input focus to the OK button.

58 |
ControlFocus "OK", "Some Window Title"
59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /docs/lib/ControlGetChecked.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetChecked - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetChecked

15 | 16 |

Returns a non-zero value if the checkbox or radio button is checked.

17 | 18 |
IsChecked := ControlGetChecked(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: Integer (boolean)

38 |

This function returns 1 (true) if the checkbox or radio button is checked, or 0 (false) if not.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if the window or control could not be found.

42 |

An OSError is thrown if a message could not be sent to the control.

43 | 44 | 45 |

ControlSetChecked, Value property (GuiControl object), Control functions

46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/lib/ControlGetChoice.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetChoice - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetChoice

15 | 16 |

Returns the name of the currently selected entry in a ListBox or ComboBox.

17 | 18 |
Choice := ControlGetChoice(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: String

38 |

This function returns the name of the currently selected entry in a ListBox or ComboBox.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo" or "List".

42 |

An Error is thrown on failure.

43 | 44 |

Remarks

45 |

To instead retrieve the position of the selected item, follow this example (use only one of the first two lines):

46 |
ChoicePos := SendMessage(0x0188, 0, 0, "ListBox1", WinTitle)  ; 0x0188 is LB_GETCURSEL (for a ListBox).
47 | ChoicePos := SendMessage(0x0147, 0, 0, "ComboBox1", WinTitle)  ; 0x0147 is CB_GETCURSEL (for a DropDownList or ComboBox).
48 | ChoicePos += 1  ; Convert from 0-based to 1-based, i.e. so that the first item is known as 1, not 0.
49 | ; ChoicePos is now 0 if there is no item selected.
50 | 51 | 52 |

ControlChooseIndex, ControlChooseString, Value property (GuiControl object), Choose method (GuiControl object), Control functions

53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /docs/lib/ControlGetClassNN.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetClassNN - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetClassNN

15 | 16 |

Returns the ClassNN (class name and sequence number) of the specified control.

17 | 18 |
ClassNN := ControlGetClassNN(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: String

38 |

This function returns the ClassNN (class name and sequence number) of the specified control.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if there is a problem determining the target window or control.

42 |

An Error or OSError is thrown if the ClassNN could not be determined.

43 | 44 |

Remarks

45 |

A control's ClassNN is the name of its window class followed by its sequence number within the top-level window which contains it. For example, "Edit1" is the first Edit control on a window and "Button12" is the twelth button.

46 |

A control's ClassNN can also be determined via Window Spy, MouseGetPos or WinGetControls.

47 |

Some class names include digits which are not part of the control's sequence number. For example, "SysListView321" is the window's first ListView control, not its 321st. To retrieve the class name without the sequence number, pass the control's HWND to WinGetClass.

48 | 49 | 50 |

WinGetClass, WinGetControls, ClassNN property (GuiControl object), MouseGetPos, Control functions

51 | 52 |

Examples

53 |
54 |

Retrieves the ClassNN of the currently focused control.

55 |
classNN := ControlGetClassNN(ControlGetFocus("A"))
56 |
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/lib/ControlGetEnabled.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetEnabled - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetEnabled

15 | 16 |

Returns a non-zero value if the specified control is enabled.

17 | 18 |
IsEnabled := ControlGetEnabled(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: Integer (boolean)

38 |

This function returns 1 (true) if the specified control is enabled, or 0 (false) if disabled.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if the window or control could not be found.

42 | 43 | 44 |

ControlSetEnabled, WinSetEnabled, Enabled property (GuiControl object), Control functions

45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/lib/ControlGetFocus.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetFocus - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlGetFocus

14 | 15 |

Retrieves which control of the target window has keyboard focus, if any.

16 | 17 |
HWND := ControlGetFocus(WinTitle, WinText, ExcludeTitle, ExcludeText)
18 |

Parameters

19 |
20 | 21 |
WinTitle, WinText, ExcludeTitle, ExcludeText
22 |
23 |

Type: String, Integer or Object

24 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

25 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

26 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

27 |
28 | 29 |
30 | 31 |

Return Value

32 |

Type: Integer

33 |

This function returns the window handle (HWND) of the focused control.

34 |

If none of the target window's controls has focus, the return value is 0.

35 | 36 |

Error Handling

37 |

A TargetError is thrown if there is a problem determining the target window or control.

38 |

An OSError is thrown if there is a problem determining the focus.

39 | 40 |

Remarks

41 |

The control retrieved by this function is the one that has keyboard focus, that is, the one that would receive keystrokes if the user were to type any.

42 |

The target window must be active to have a focused control, but even the active window may lack a focused control.

43 | 44 | 45 |

ControlFocus, Control functions

46 |

Examples

47 |
48 |

Reports the HWND and ClassNN of the active window's focused control.

49 |
50 | FocusedHwnd := ControlGetFocus("A")
51 | FocusedClassNN := ControlGetClassNN(FocusedHwnd)
52 | MsgBox 'Control with focus = {Hwnd: ' FocusedHwnd ', ClassNN: "' FocusedClassNN '"}'
53 |
54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/lib/ControlGetHwnd.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetHwnd - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetHwnd

15 | 16 |

Returns the unique ID number of the specified control.

17 | 18 |
Hwnd := ControlGetHwnd(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: Integer

38 |

This function returns the window handle (HWND) of the specified control.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if the window or control could not be found.

42 | 43 |

Remarks

44 |

A control's HWND is often used with PostMessage, SendMessage, and DllCall. On a related note, a control's HWND can also be retrieved via MouseGetPos. Finally, a control's HWND can be used directly in a WinTitle parameter. This also works on hidden controls even when DetectHiddenWindows is Off.

45 | 46 | 47 |

WinGetID, Hwnd property (GuiControl object), Control functions

48 | 49 |

Examples

50 |
51 |

Retrieves the unique ID number of the Notepad's Edit control.

52 |
editHwnd := ControlGetHwnd("Edit1", "ahk_class Notepad")
53 |
54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/lib/ControlGetIndex.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetIndex - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetIndex

15 | 16 |

Returns the index of the currently selected entry or tab in a ListBox, ComboBox or Tab control.

17 | 18 |
Index := ControlGetIndex(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: Integer

38 |

This function returns the index of the currently selected entry or tab. The first entry or tab is 1, the second is 2, etc. If no entry or tab is selected, the return value is 0.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo", "List" or "Tab".

42 |

An OSError is thrown if a message could not be sent to the control.

43 | 44 |

Remarks

45 |

To instead discover how many tabs (pages) exist in a tab control, follow this example:

46 |
TabCount := SendMessage(0x1304,,, "SysTabControl321", WinTitle)  ; 0x1304 is TCM_GETITEMCOUNT.
47 | 48 | 49 |

ControlChooseIndex, ControlGetChoice, ControlChooseString, Value property (GuiControl object), Choose method (GuiControl object), Control functions

50 | 51 |

Examples

52 | 53 |
54 |

Retrieves the active tab number of the first Tab control.

55 |
56 | WhichTab := ControlGetIndex("SysTabControl321", "Some Window Title")
57 | MsgBox "Tab #" WhichTab " is active."
58 | 
59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /docs/lib/ControlGetItems.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetItems - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetItems

15 | 16 |

Returns an array of items/rows from a ListBox, ComboBox, or DropDownList.

17 | 18 |
Items := ControlGetItems(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: Array

38 |

This function returns an array containing the text of each item or row.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if the window or control could not be found, or if the control's class name does not contain "Combo" or "List".

42 |

An Error is thrown on failure, such as if a message returned a failure code or could not be sent.

43 | 44 |

Remarks

45 |

Some applications store their item data privately, which prevents their text from being retrieved. In these cases, an exception will usually not be thrown, but all the retrieved fields will be empty.

46 | 47 | 48 |

ListViewGetContent, WinGetList, Control functions

49 | 50 |

Examples

51 |
52 |

Accesses the items one by one.

53 |
for item in ControlGetItems("ComboBox1", WinTitle)
54 |     MsgBox "Item number " A_Index " is " item
55 |
56 | 57 |
58 |

Accesses a specific item by index.

59 |
items := ControlGetItems("ListBox1", WinTitle)
60 | MsgBox "The first item is " items[1]
61 | MsgBox "The last item is " items[-1]
62 |
63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/lib/ControlGetPos.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetPos - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlGetPos

14 | 15 |

Retrieves the position and size of a control.

16 | 17 |
ControlGetPos &OutX, &OutY, &OutWidth, &OutHeight, Control, WinTitle, WinText, ExcludeTitle, ExcludeText
18 |

Parameters

19 |
20 | 21 |
&OutX, &OutY
22 |
23 |

Type: VarRef

24 |

If omitted, the corresponding value will not be stored. Otherwise, specify references to the output variables in which to store the X and Y coordinates (in pixels) of the control's upper left corner. These coordinates are relative to the upper-left corner of the target window's client area and thus are the same as those used by ControlMove.

25 |
26 | 27 |
&OutWidth, &OutHeight
28 |
29 |

Type: VarRef

30 |

If omitted, the corresponding value will not be stored. Otherwise, specify references to the output variables in which to store the control's width and height (in pixels).

31 |
32 | 33 |
Control
34 |
35 |

Type: String, Integer or Object

36 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

37 |
38 | 39 |
WinTitle, WinText, ExcludeTitle, ExcludeText
40 |
41 |

Type: String, Integer or Object

42 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

43 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

44 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

45 |
46 | 47 |
48 | 49 |

Error Handling

50 |

A TargetError is thrown if the window or control could not be found.

51 | 52 |

Remarks

53 |

Unlike functions that change a control, ControlGetPos does not have an automatic delay (SetControlDelay does not affect it).

54 | 55 | 56 |

ControlMove, WinGetPos, Control functions

57 |

Examples

58 |
59 |

Continuously updates and displays the name and position of the control currently under the mouse cursor.

60 |
Loop
61 | {
62 |     Sleep 100
63 |     MouseGetPos ,, &WhichWindow, &WhichControl
64 |     try ControlGetPos &x, &y, &w, &h, WhichControl, WhichWindow
65 |     ToolTip WhichControl "`nX" X "`tY" Y "`nW" W "`t" H
66 | }
67 |
68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /docs/lib/ControlGetStyle.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetStyle / ControlGetExStyle - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetStyle / ControlGetExStyle

15 | 16 |

Returns an integer representing the style or extended style of the specified control.

17 | 18 |
Style := ControlGetStyle(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | ExStyle := ControlGetExStyle(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
20 | 21 |

Parameters

22 |
23 |
Control
24 |
25 |

Type: String, Integer or Object

26 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

27 |
28 |
WinTitle, WinText, ExcludeTitle, ExcludeText
29 |
30 |

Type: String, Integer or Object

31 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

32 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

33 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

34 |
35 |
36 | 37 |

Return Value

38 |

Type: Integer

39 |

These functions return the style or extended style of the specified control.

40 | 41 |

Error Handling

42 |

A TargetError is thrown if the window or control could not be found.

43 | 44 |

Remarks

45 |

See the styles table for a partial listing of styles.

46 | 47 | 48 |

ControlSetStyle / ControlSetExStyle, WinGetStyle / WinGetExStyle, styles table, Control functions

49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /docs/lib/ControlGetText.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetText - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlGetText

14 | 15 |

Retrieves text from a control.

16 | 17 |
Text := ControlGetText(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
18 |

Parameters

19 |
20 | 21 |
Control
22 |
23 |

Type: String, Integer or Object

24 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

25 |
26 | 27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 | 35 |
36 | 37 |

Return Value

38 |

Type: String

39 |

This function returns the text of the specified control.

40 | 41 |

Error Handling

42 |

A TargetError is thrown if the window or control could not be found.

43 | 44 |

Remarks

45 |

Note: To retrieve text from a ListView, ListBox, or ComboBox, use ListViewGetContent or ControlGetItems instead.

46 |

If the retrieved text appears to be truncated (incomplete), it may be necessary to retrieve the text by sending the WM_GETTEXT message via SendMessage instead. This is because some applications do not respond properly to the WM_GETTEXTLENGTH message, which causes AutoHotkey to make the return value too small to fit all the text.

47 |

This function might use a large amount of RAM if the target control (e.g. an editor with a large document open) contains a large quantity of text. However, a variable's memory can be freed after use by assigning it to nothing, i.e. Text := "".

48 |

Text retrieved from most control types uses carriage return and linefeed (`r`n) rather than a solitary linefeed (`n) to mark the end of each line.

49 |

It is not necessary to do SetTitleMatchMode "Slow" because ControlGetText always retrieves the text using the slow mode (since it works on a broader range of control types).

50 |

To retrieve an array of all controls in a window, use WinGetControls or WinGetControlsHwnd.

51 | 52 | 53 |

ControlSetText, WinGetText, Control functions

54 |

Examples

55 |
56 |

Retrieves the current text from Notepad's edit control and stores it in Text. This example may fail on Windows 11 or later, as it requires the classic version of Notepad.

57 |
Text := ControlGetText("Edit1", "Untitled -")
58 |
59 |
60 |

Retrieves and reports the current text from the main window's edit control.

61 |
ListVars
62 | WinWaitActive "ahk_class AutoHotkey"
63 | MsgBox ControlGetText("Edit1") ; Use the window found above.
64 |
65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/lib/ControlGetVisible.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlGetVisible - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlGetVisible

15 | 16 |

Returns a non-zero value if the specified control is visible.

17 | 18 |
IsVisible := ControlGetVisible(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Return Value

37 |

Type: Integer (boolean)

38 |

This function returns 1 (true) if the specified control is visible, or 0 (false) if hidden.

39 | 40 |

Error Handling

41 |

A TargetError is thrown if the window or control could not be found.

42 | 43 | 44 |

ControlHide, ControlShow, Visible property (GuiControl object), Control functions

45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/lib/ControlHide.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlHide - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlHide

15 | 16 |

Hides the specified control.

17 | 18 |
ControlHide Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Error Handling

37 |

A TargetError is thrown if the window or control could not be found.

38 | 39 |

Remarks

40 |

If you additionally want to prevent a control's shortcut key (underlined letter) from working, disable the control via ControlSetEnabled.

41 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

42 | 43 | 44 |

ControlShow, ControlGetVisible, WinHide, Visible property (GuiControl object), Control functions

45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/lib/ControlHideDropDown.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlHideDropDown - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlHideDropDown

15 | 16 |

Hides the drop-down list of a ComboBox control.

17 | 18 |
ControlHideDropDown Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Error Handling

37 |

A TargetError is thrown if the window or control could not be found.

38 |

An OSError is thrown if a message could not be sent to the control.

39 | 40 |

Remarks

41 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

42 | 43 | 44 |

ControlShowDropDown, Control functions

45 | 46 |

Examples

47 |

See example #1 on the ControlShowDropDown page.

48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /docs/lib/ControlMove.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlMove - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlMove

14 | 15 |

Moves or resizes a control.

16 | 17 |
ControlMove X, Y, Width, Height, Control, WinTitle, WinText, ExcludeTitle, ExcludeText
18 | 19 |

Parameters

20 |
21 |
X, Y
22 |
23 |

Type: Integer

24 |

If either is omitted, the control's position in that dimension will not be changed. Otherwise, specify the X and Y coordinates (in pixels) of the upper left corner of the control's new location. The coordinates are relative to the upper-left corner of the target window's client area; ControlGetPos can be used to determine them.

25 |
26 | 27 |
Width, Height
28 |
29 |

Type: Integer

30 |

If either is omitted, the control's size in that dimension will not be changed. Otherwise, specify the new width and height of the control (in pixels).

31 |
32 | 33 |
Control
34 |
35 |

Type: String, Integer or Object

36 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

37 |
38 | 39 |
WinTitle, WinText, ExcludeTitle, ExcludeText
40 |
41 |

Type: String, Integer or Object

42 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

43 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

44 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

45 |
46 |
47 | 48 |

Error Handling

49 |

A TargetError is thrown if the window or control could not be found.

50 |

An OSError is thrown if the control's current position could not be determined.

51 | 52 | 53 |

Remarks

54 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

55 | 56 | 57 |

ControlGetPos, WinMove, SetControlDelay, Control functions

58 | 59 |

Examples

60 |
61 |

Demonstrates how to manipulate the OK button of an input box while the script is waiting for user input.

62 |
SetTimer ControlMoveTimer
63 | IB := InputBox(, "My Input Box")
64 | 
65 | ControlMoveTimer()
66 | {
67 |     if !WinExist("My Input Box")
68 |         return
69 |     ; Otherwise the above set the "last found" window for us:
70 |     SetTimer , 0
71 |     WinActivate
72 |     ControlMove 10,, 200,, "OK"  ; Move the OK button to the left and increase its width.
73 | }
74 |
75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /docs/lib/ControlSend.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlSend / ControlSendText - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlSend / ControlSendText

14 | 15 |

Sends simulated keystrokes or text to a window or control.

16 | 17 |
ControlSend Keys , Control, WinTitle, WinText, ExcludeTitle, ExcludeText
 18 | ControlSendText Keys , Control, WinTitle, WinText, ExcludeTitle, ExcludeText
19 |

Parameters

20 |
21 | 22 |
Keys
23 |
24 |

Type: String

25 |

The sequence of keys to send (see the Send function for details). The rate at which characters are sent is determined by SetKeyDelay.

26 |

Unlike the Send function, mouse clicks cannot be sent by ControlSend. Use ControlClick for that.

27 |
28 | 29 |
Control
30 |
31 |

Type: String, Integer or Object

32 |

If omitted, the keystrokes will be sent directly to the target window instead of one of its controls (see Automating Winamp for an example). Otherwise, specify the control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

33 |
34 | 35 |
WinTitle, WinText, ExcludeTitle, ExcludeText
36 |
37 |

Type: String, Integer or Object

38 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

39 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

40 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

41 |
42 | 43 |
44 | 45 |

Error Handling

46 |

A TargetError is thrown if the window or control could not be found.

47 | 48 |

Remarks

49 |

ControlSendText sends the individual characters of the Keys parameter without translating {Enter} to Enter, ^c to Ctrl+C, etc. For details, see Text mode. It is also valid to use {Raw} or {Text} with ControlSend.

50 |

If the Control parameter is omitted, this function will attempt to send directly to the target window by sending to its topmost control (which is often the correct one) or the window itself if there are no controls. This is useful if a window does not appear to have any controls at all, or just for the convenience of not having to worry about which control to send to.

51 |

By default, modifier keystrokes (Ctrl, Alt, Shift, and Win) are sent as they normally would be by the Send function. This allows command prompt and other console windows to properly detect uppercase letters, control characters, etc. It may also improve reliability in other ways.

52 |

However, in some cases these modifier events may interfere with the active window, especially if the user is actively typing during a ControlSend or if Alt is being sent (since Alt activates the active window's menu bar). This can be avoided by explicitly sending modifier up and down events as in this example:

53 |
ControlSend "{Alt down}f{Alt up}", "Edit1", "Untitled - Notepad"
54 |

The method above also allows the sending of modifier keystrokes (Ctrl, Alt, Shift, and Win) while the workstation is locked (protected by logon prompt).

55 |

BlockInput should be avoided when using ControlSend against a console window such as command prompt. This is because it might prevent capitalization and modifier keys such as Ctrl from working properly.

56 |

The value of SetKeyDelay determines the speed at which keys are sent. If the target window does not receive the keystrokes reliably, try increasing the press duration via the second parameter of SetKeyDelay as in these examples:

57 |
SetKeyDelay 10, 10
 58 | SetKeyDelay 0, 10
 59 | SetKeyDelay -1, 0
60 |

If the target control is an Edit control (or something similar), the following are usually more reliable and faster than ControlSend:

61 |
EditPaste("This text will be inserted at the caret position.", ControlName, WinTitle)
62 |
ControlSetText("This text will entirely replace any current text.", ControlName, WinTitle)
63 |

ControlSend is generally not capable of manipulating a window's menu bar. To work around this, use MenuSelect. If that is not possible due to the nature of the menu bar, you could try to discover the message that corresponds to the desired menu item by following the SendMessage Tutorial.

64 | 65 | 66 |

SetKeyDelay, Escape sequences (e.g. `n) , Control functions, Send, Automating Winamp

67 |

Examples

68 |
69 |

Opens Notepad minimized and send it some text. This example may fail on Windows 11 or later, as it requires the classic version of Notepad.

70 |
Run "Notepad",, "Min", &PID  ; Run Notepad minimized.
 71 | WinWait "ahk_pid " PID  ; Wait for it to appear.
 72 | ; Send the text to the inactive Notepad edit control.
 73 | ; The third parameter is omitted so the last found window is used.
 74 | ControlSend "This is a line of text in the notepad window.{Enter}", "Edit1"
 75 | ControlSendText "Notice that {Enter} is not sent as an Enter keystroke with ControlSendText.", "Edit1"
 76 | 
 77 | Msgbox "Press OK to activate the window to see the result."
 78 | WinActivate "ahk_pid " PID  ; Show the result.
79 |
80 | 81 |
82 |

Opens the command prompt and sent it some text. This example may fail on Windows 11 or later, as it requires the classic version of the command prompt.

83 |
SetTitleMatchMode 2
 84 | Run A_ComSpec,,, &PID  ; Run command prompt.
 85 | WinWait "ahk_pid " PID  ; Wait for it to appear.
 86 | ControlSend "ipconfig{Enter}",, "cmd.exe"  ; Send directly to the command prompt window.
87 |
88 |
89 |

Creates a GUI with an edit control and sent it some text.

90 |
MyGui := Gui()
 91 | MyGui.Add("Edit", "r10 w500")
 92 | MyGui.Show()
 93 | ControlSend "This is a line of text in the edit control.{Enter}", "Edit1", MyGui
 94 | ControlSendText "Notice that {Enter} is not sent as an Enter keystroke with ControlSendText.", "Edit1", MyGui
 95 | 
96 |
97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /docs/lib/ControlSetChecked.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlSetChecked - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlSetChecked

15 | 16 |

Turns on (checks) or turns off (unchecks) a checkbox or radio button.

17 | 18 |
ControlSetChecked NewSetting, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 | 23 |
NewSetting
24 |
25 |

Type: Integer

26 |

One of the following values:

27 | 32 |
33 |
Control
34 |
35 |

Type: String, Integer or Object

36 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

37 |
38 |
WinTitle, WinText, ExcludeTitle, ExcludeText
39 |
40 |

Type: String, Integer or Object

41 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

42 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

43 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

44 |
45 |
46 | 47 |

Error Handling

48 |

A TargetError is thrown if the window or control could not be found.

49 |

An OSError is thrown if a message could not be sent to the control.

50 | 51 |

Remarks

52 |

To ensure correct functionality, this function also sets the input focus to the control.

53 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

54 | 55 | 56 |

ControlGetChecked, Value property (GuiControl object), Control functions

57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/lib/ControlSetEnabled.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlSetEnabled - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlSetEnabled

15 | 16 |

Enables or disables the specified control.

17 | 18 |
ControlSetEnabled NewSetting, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 | 23 |
NewSetting
24 |
25 |

Type: Integer

26 |

One of the following values:

27 | 32 |
33 |
Control
34 |
35 |

Type: String, Integer or Object

36 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

37 |
38 |
WinTitle, WinText, ExcludeTitle, ExcludeText
39 |
40 |

Type: String, Integer or Object

41 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

42 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

43 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

44 |
45 |
46 | 47 |

Error Handling

48 |

A TargetError is thrown if the window or control could not be found.

49 | 50 |

Remarks

51 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

52 | 53 | 54 |

ControlGetEnabled, WinSetEnabled, Enabled property (GuiControl object), Control functions

55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/lib/ControlSetStyle.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlSetStyle / ControlSetExStyle - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlSetStyle / ControlSetExStyle

15 | 16 |

Changes the style or extended style of the specified control, respectively.

17 | 18 |
ControlSetStyle Value, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | ControlSetExStyle Value, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
20 | 21 |

Parameters

22 |
23 |
Value
24 |
25 |

Type: Integer or String

26 |

Pass a positive integer to completely overwrite the window's style; that is, to set it to Value.

27 |

To easily add, remove or toggle styles, pass a numeric string prefixed with a plus sign (+), minus sign (-) or caret (^), respectively. The new style value is calculated as shown below (where CurrentStyle could be retrieved with ControlGetStyle, ControlGetExStyle, WinGetStyle or WinGetExStyle):

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
OperationPrefixExampleFormula
Add+"+0x80"NewStyle := CurrentStyle | Value
Remove-"-0x80"NewStyle := CurrentStyle & ~Value
Toggle^"^0x80"NewStyle := CurrentStyle ^ Value
54 |

If Value is a negative integer, it is treated the same as the corresponding numeric string.

55 |

To use the + or ^ prefix literally in an expression, the prefix or value must be enclosed in quote marks. For example: ControlSetStyle("+0x80") or ControlSetStyle("^" StylesToToggle). This is because the expression +123 produces 123 (without a prefix) and ^123 is a syntax error.

56 |
57 |
Control
58 |
59 |

Type: String, Integer or Object

60 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

61 |
62 |
WinTitle, WinText, ExcludeTitle, ExcludeText
63 |
64 |

Type: String, Integer or Object

65 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

66 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

67 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

68 |
69 |
70 | 71 |

Error Handling

72 |

A TargetError is thrown if the window or control could not be found.

73 |

An OSError is thrown if the style could not be changed. Partial change is considered a success.

74 | 75 |

Remarks

76 |

See the styles table for a partial listing of styles.

77 |

Certain style changes require that the entire window be redrawn using WinRedraw.

78 | 79 | 80 |

ControlGetStyle / ControlGetExStyle, WinSetStyle / WinSetExStyle, styles table, Control functions

81 | 82 |

Examples

83 |
84 |

Sets the WS_BORDER style of the Notepad's Edit control to its opposite state.

85 |
ControlSetStyle("^0x800000", "Edit1", "ahk_class Notepad")
86 |
87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /docs/lib/ControlSetText.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlSetText - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

ControlSetText

14 | 15 |

Changes the text of a control.

16 | 17 |
ControlSetText NewText, Control , WinTitle, WinText, ExcludeTitle, ExcludeText
18 |

Parameters

19 |
20 | 21 |
NewText
22 |
23 |

Type: String

24 |

The new text to set into the control.

25 |
26 | 27 |
Control
28 |
29 |

Type: String, Integer or Object

30 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

31 |
32 | 33 |
WinTitle, WinText, ExcludeTitle, ExcludeText
34 |
35 |

Type: String, Integer or Object

36 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

37 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

38 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

39 |
40 | 41 |
42 | 43 |

Error Handling

44 |

A TargetError is thrown if the window or control could not be found.

45 | 46 |

Remarks

47 |

Most control types use carriage return and linefeed (`r`n) rather than a solitary linefeed (`n) to mark the end of each line. To translate a block of text containing `n characters, follow this example:

48 |
MyVar := StrReplace(MyVar, "`n", "`r`n")
49 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

50 | 51 | 52 |

SetControlDelay, ControlGetText, Control functions

53 |

Examples

54 |
55 |

Changes the text of Notepad's edit control. This example may fail on Windows 11 or later, as it requires the classic version of Notepad.

56 |
ControlSetText("New Text Here", "Edit1", "Untitled -")
57 |
58 |
59 |

Changes the text of the main window's edit control.

60 |
ListVars
61 | WinWaitActive "ahk_class AutoHotkey"
62 | ControlSetText "New Text Here", "Edit1" ; Use the window found above.
63 |
64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/lib/ControlShow.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlShow - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlShow

15 | 16 |

Shows the specified control if it was previously hidden.

17 | 18 |
ControlShow Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Error Handling

37 |

A TargetError is thrown if the window or control could not be found.

38 | 39 |

Remarks

40 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

41 | 42 | 43 |

ControlHide, ControlGetVisible, WinShow, Visible property (GuiControl object), Control functions

44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /docs/lib/ControlShowDropDown.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControlShowDropDown - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

ControlShowDropDown

15 | 16 |

Shows the drop-down list of a ComboBox control.

17 | 18 |
ControlShowDropDown Control , WinTitle, WinText, ExcludeTitle, ExcludeText
19 | 20 |

Parameters

21 |
22 |
Control
23 |
24 |

Type: String, Integer or Object

25 |

The control's ClassNN, text or HWND, or an object with a Hwnd property. For details, see The Control Parameter.

26 |
27 |
WinTitle, WinText, ExcludeTitle, ExcludeText
28 |
29 |

Type: String, Integer or Object

30 |

If each of these is blank or omitted, the Last Found Window will be used. Otherwise, specify for WinTitle a window title or other criteria to identify the target window and/or for WinText a substring from a single text element of the target window (as revealed by the included Window Spy utility).

31 |

ExcludeTitle and ExcludeText can be used to exclude one or more windows by their title or text. Their specification is similar to WinTitle and WinText, except that ExcludeTitle does not recognize any criteria other than the window title.

32 |

Window titles and text are case-sensitive. By default, hidden windows are not detected and hidden text elements are detected, unless changed with DetectHiddenWindows and DetectHiddenText; however, when using pure HWNDs, hidden windows are always detected regardless of DetectHiddenWindows. By default, a window title can contain WinTitle or ExcludeTitle anywhere inside it to be a match, unless changed with SetTitleMatchMode.

33 |
34 |
35 | 36 |

Error Handling

37 |

A TargetError is thrown if the window or control could not be found.

38 |

An OSError is thrown if a message could not be sent to the control.

39 | 40 |

Remarks

41 |

To improve reliability, a delay is done automatically after each use of this function. That delay can be changed via SetControlDelay or by assigning a value to A_ControlDelay. For details, see SetControlDelay remarks.

42 | 43 | 44 |

ControlHideDropDown, Control functions

45 | 46 |

Examples

47 |
48 |

Opens the Run dialog, shows its drop-down list for 2 seconds and closes the dialog.

49 |
Send "#r"  ; Open the Run dialog.
50 | WinWaitActive "ahk_class #32770"  ; Wait for the dialog to appear.
51 | ControlShowDropDown "ComboBox1"  ; Show the drop-down list. The second parameter is omitted so that the last found window is used.
52 | Sleep 2000
53 | ControlHideDropDown "ComboBox1"  ; Hide the drop-down list.
54 | Sleep 1000
55 | Send "{Esc}"  ; Close the Run dialog.
56 |
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/lib/CoordMode.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CoordMode - Syntax & Usage | AutoHotkey v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

CoordMode

14 | 15 |

Sets coordinate mode for various built-in functions to be relative to either the active window or the screen.

16 | 17 |
CoordMode TargetType , RelativeTo
18 |

Parameters

19 |
20 | 21 |
TargetType
22 |
23 |

Type: String

24 |

Specify one of the following words to indicate the type of target to affect:

25 |

ToolTip: Affects ToolTip.

26 |

Pixel: Affects PixelGetColor, PixelSearch, and ImageSearch.

27 |

Mouse: Affects MouseGetPos, Click, MouseMove, MouseClick, and MouseClickDrag.

28 |

Caret: Affects CaretGetPos.

29 |

Menu: Affects the Menu.Show method when coordinates are specified for it.

30 |
31 | 32 |
RelativeTo
33 |
34 |

Type: