Learning Autohotkey
Learning Autohotkey
#autohotkey
Table of Contents
About 1
Remarks 2
Versions 2
AutoHotkey 1.0.* - also retroactively known as AutoHotkey Basic, Classic, Vanilla, etc. 2
AutoHotkey 2.0-a* 2
Examples 3
Installation or Setup 3
Hello World 4
Chapter 2: Arrays 6
Examples 6
Intro 6
Filling an array 7
Remarks 9
Examples 9
Trim a string 9
Examples 11
When typing the word "Hello" followed by a space or enter it will be replaced by "Hello Wo 12
Syntax 13
Parameters 13
Examples 13
Hotkey 13
Hotstring 13
Multiple keypress 14
Remap keys 14
Toggleable hotkeys 15
Introduction 16
Parameters 16
Remarks 16
Examples 17
Passwords 17
Chapter 7: Open a File in a Script 18
Introduction 18
Examples 18
Remarks 20
Examples 20
Advanced use of SetTimer: Calling the same function with different parameters 20
More complicated Gui example with multiple listviews using the same event callback functio 23
Credits 26
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: autohotkey
It is an unofficial and free AutoHotkey ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official AutoHotkey.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/ 1
Chapter 1: Getting started with AutoHotkey
Remarks
AutoHotkey is a free, open-source custom scripting language for Microsoft Windows, initially
aimed at providing easy keyboard shortcuts or hotkeys, fast macro-creation and software
automation that allows users of most levels of computer skill to automate repetitive tasks in any
Windows application. User interfaces can easily be extended or modified by AutoHotkey (for
example, overriding the default Windows control key commands with their Emacs equivalents).
The Autohotkey installation includes its own extensive help file with an always updated web based
version.
You can write mouse or keyboard macros, remap keys, create hotkeys, expand abbreviations,
change clipboard contents, and make executables to run hotkey scripts on computers without
AutoHotkey installed.
Versions
v1.0.48.05 2009-09-26
v1.0.97.02 2011-04-14
v1.1.24.00 2016-05-22
v1.1.24.01 2016-08-02
AutoHotkey 2.0-a*
https://riptutorial.com/ 2
(Still in alpha stage)
v2.0-a069 2015-10-24
v2.0-a070 2015-11-09
v2.0-a071 2015-12-25
v2.0-a072 2015-12-25
v2.0-a073 2016-02-05
v2.0-a074 2016-03-11
v2.0-a075 2016-06-03
Examples
Installation or Setup
https://riptutorial.com/ 3
If you have chocolatey installed, run the following command as an admin user
Alternatively, it can be built from the source code. See here for details:
https://github.com/Lexikos/AutoHotkey_L/
Hello World
#Persistent
Tooltip, Hello World!
#Persistent
TrayTip,, Hello World!
GuiClose:
ExitApp
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".
https://riptutorial.com/ 4
1. Right-Click on your desktop.
2. Find "New" in the menu.
3. Click "AutoHotkey Script" inside the "New" menu.
4. Give the script a new name. Note: It must end with a .ahk extension. Ex. MyScript.ahk
5. Find the newly created file on your desktop and Right-Click it.
6. Click "Edit Script".
7. A window should have popped up, probably Notepad. If so, SUCCESS!
So now that you have created a script, we need to add stuff into the file. For a list of all built-in
commands, function and variables, see section 5. Here is a very basic script containing a Hotkey
which types text using the Send command when the hotkey is pressed.
^j::
Send, My First Script
Return
We will get more in-depth later on. Until then, here's an explanation of the above code.
• The first line. ^j:: is the Hotkey. ^ means CTRL, j is the letter j. Anything to the left of :: are
the keys you need to press.
• The second line. Send, My First Script is how you SEND keystrokes. SEND is the command,
anything after the comma (,) will be typed.
• The third line. Return. Return will become your best friend. It literally STOPS code from going
any further, to the lines below. This will prevent many issues when you start having a lot of
stuff in your scripts.
https://riptutorial.com/ 5
Chapter 2: Arrays
Examples
Creating and Initializing Simple Arrays
Intro
An array is a container object that holds a number of values. In the following image you can see
an array with size 10, the first element indexed 1 and the last element 10.
• Array := []
• Array := Array()
Array[0] := 1
https://riptutorial.com/ 6
If the array is not empty, MinIndex and MaxIndex/Length return the lowest and highest index
currently in use in the array. Since the lowest index is nearly always 1, MaxIndex usually returns
the number of items. However, if there are no integer keys, MaxIndex returns an empty string
whereas Length returns 0.
Array[1, 2] := 3
You can create and initialize at the same time time, and inner arrays do not need to be of same
length.
Array := [[4,5,6],7,8]
Filling an array
; Assign an item:
Array[Index] := Value
The value of an index for an array element can also be a negative integer (-1, 0, 1, 2, 3, 4, ...)
; Overrides Array()
Array(Args*) {
Args.Base := _Array
Return Args
}
; SumOfArray == 10
SumOfArray := Arr.Sum()
https://riptutorial.com/ 8
Chapter 3: Built-in Variables and Functions
Remarks
AutoHotkey comes with many built-in functions and variables which can be used anywhere inside
a script.
For a full list including explanations, see:
Examples
Determining the User Idle Time
This example inserts/sends the current day of the week's full name (e.g. Sunday) whenever Ctrl +
Alt + D is pressed:
^!d::Send, %A_DDDD%
myDebt := 9000
index := RegExMatch("You owe me $42", "\$(\d+)", dollars)
if(index > 0) { ; indices are usually 1-based in AHK
myDebt += dollars1
MsgBox, Current debt: %myDebt%
}
Result:
Trim a string
https://riptutorial.com/ 9
FileAppend, % trimmed "`n", TrimmedStrings.txt
Note that Trim() will not manipulate the original string, but return a new one which should be
stored or output somewhere.
https://riptutorial.com/ 10
Chapter 4: Hello World
Examples
Hello World examples
#Persistent
Tooltip, Hello World!
#Persistent
TrayTip,, Hello World!
GuiClose() {
ExitApp
}
https://riptutorial.com/ 11
Simulate typing "Hello, World!" when pressing enter
FileAppend,, HelloWorld.txt
::Hello::Hello World
https://riptutorial.com/ 12
Chapter 5: Hotkey Scripts
Syntax
• keybindings::
• ::abbreviation::
• Return
Parameters
Keybindings Details
^ Ctrl key
! Alt key
+ Shift key
# Windows key
Examples
Hotkey
To make a hotkey that sends the key sequence 'Hello World' from pressing Ctrl + J onto the active
window (can be demonstrated in notepad, e.g.)
^j::
Send, Hello World
Return
Hotstring
https://riptutorial.com/ 13
To make a script to replace a phrase use the ::abbreviation:: hotstring syntax. It will replace btw
with by the way whenever you enter btw and then the space key.
If you wanted to make a login script to make logging in faster you could make a script like this (the
file is not encrypted so any information in your script will be visible to anyone with access to the
file).
::lmi::user{tab}password{enter}
Multiple keypress
To run a script when multiple keys are pressed use the & between the keys.
In order to create a hotkey or hotstring that only triggers when certain windows are active or exist,
you can put one or several of the following directives before the hotkey definition:
Example: You want stackoverflow.com to be sent whenever you type so (and a whitespace after
that) in Google Chrome, but ignore the hotstring in any other window.
By using #If [, Expression ], you can make a hotkey trigger only when an arbitrary expression is
true, for example:
Remap keys
The following example remaps the key Z to Y and vice versa, e.g. if you want to work with the
QWERTY layout on a QWERTZ keyboard.
https://riptutorial.com/ 14
z::y
y::z
Toggleable hotkeys
Following script enters predefined strings on hotkey presses if the scroll lock is active. This can be
useful if you often paste a number of repeating strings. Included hotkey for script refresh (for
example if you need to edit paste-able strings).
Numpad1::
GetKeyState, state, ScrollLock, T
if ( state = "D" )
Send, Hello
Return
Numpad2::
GetKeyState, state, ScrollLock, T
if ( state = "D" )
Send, World
Return
;...
https://riptutorial.com/ 15
Chapter 6: Input Field
Introduction
To get a user's input and store it in a variable, you can use the InputBox command. The script will
not continue executing commands until the user either presses 'OK' or 'Cancel'.
'OK' will close the window and save the user's input 'Cancel' will close the window, discarding the
user's input
Parameters
Remarks
https://riptutorial.com/ 16
An input box is a GUI item, so it will be treated as a GUI item.
You can find the page for this command on the AutoHotkey documentation here:
https://autohotkey.com/docs/commands/InputBox.htm
Examples
Basic Usage Example
InputBox, userinput
This will store what the user types into the input box in the variable named userinput
Passwords
Loop, {
if (errorlevel = 1)
return
if (password = "password") {
MsgBox, The password is correct.
return
} else if (password != "password") {
MsgBox, The password is incorrect.
InputBox, password, Enter your Password,, HIDE,, 100
}
}
This will check if the user has typed "password" in the input box. If the user types the correct
value, it will say "The password is correct." and close the input box. If the user types the incorrect
value, it will say "The password is incorrect." and reopen the input box. If the errorlevel is 1 (the
user pressed cancel), it will terminate the script.
https://riptutorial.com/ 17
Chapter 7: Open a File in a Script
Introduction
Different ways to open a file to work with in a script.
Examples
Open a File through Windows Explorer
Inside the script, use the first line to store the very first variable (in this example, %1%) with a name
to deal with. Example: OpenWithFile = %1%
Once you open a file with this script through Windows (Right click on any file on MS Windows and
choose 'Open with...' then select the compiled version of the script such as script.exe) the name
of the choosed file will be stored in this variable and, so, the script will be able to work with it.
Example:
OpenWithFile = %1%
if OpenWithFile !=
{
FileRead, content, %OpenWithFile%
msgbox %content%
return
}
The following example creates a Gui with a single button wich brings the SelectFile dialog box.
return
LoaderButtonLOAD:
FileSelectFile, LoadedFile, , , ,
if ErrorLevel=1
{
return
}
else
{
FileRead, content, %LoadedFile%
msgbox %content%
}
return
https://riptutorial.com/ 18
Open a File through Windows Drag n' Drop
This examples creates a new empty Gui sensible to Drag n' Drop event:
return
DropperGuiDropFiles:
DroppedFile:=A_GuiEvent
return
https://riptutorial.com/ 19
Chapter 8: Use functions instead of labels
Remarks
AutoHotkey used to heavily rely on labels until version 1.1.20. It's reliance on labels had very
serious disadvantages. The main one being that labels usually execute in the global scope
meaning that any variable defined within a label will be globally available. This sounds great until
you realize that for example you can't just use other peoples libraries without making sure that
their variables don't interfere with yours.
Working in the global scope when not necessary is simply bad practice.
So this is where functions come in. As of version 1.1.20, every AutoHotkey command that accepts
a label-name as a parameter, now alternatively accepts a function-name.
Examples
Very basic example demonstrating function use on SetTimer.
SendLetterA() {
Send, a
}
This is an example of something that would have been straight up impossible with labels. If you
execute the same label multiple times at the same time and they rely on variables that are being
defined within them, they very likely interfere and cause unexpected behavior.
; This script will switch between showing "Hello 1" and "Hello 2"
#Persistent
DisplayMessage_Hello1 := Func("DisplayMessage").bind("Hello 1")
SetTimer, %DisplayMessage_Hello1%, 2000
Sleep, 1000
DisplayMessage(messageToDisplay) {
TrayTip ; remove other traytips
https://riptutorial.com/ 20
TrayTip, Message to display:, %messageToDisplay%
}
;This script will never display the message "Hello 1". It will always show "Hello 2".
#Persistent
messageToDisplay := "Hello 1"
SetTimer, DisplayMessage, 2000
Sleep, 1000
DisplayMessage:
TrayTip ; remove other traytips
TrayTip, Message to display:, %messageToDisplay%
Return
GuiClose(hWnd) {
WinGetTitle, windowTitle, ahk_id %hWnd%
MsgBox, The Gui with title "%windowTitle%" has been closed!
ExitApp
}
MyFunction() {
MsgBox You pressed %A_ThisHotkey%.
}
https://riptutorial.com/ 21
Or:
a::MyFunction()
MyFunction() {
MsgBox You pressed %A_ThisHotkey%.
}
#Persistent
OnDefaultTrayAction() {
MsgBox, You double clicked the tray icon of this script or you clicked the MyDefaultAction
entry!
}
Exit() {
MsgBox, You clicked the Exit entry! The script will close itself now.
ExitApp
}
With functions:
a := 3
b := 2
GoSub, Add ; execute the label "Add" then jump back to the next line here
MsgBox, Result: %c%
Return ; without this, the label would be executed again for no reason.
Add: ; This is a label. Please put them at the bottom of your script and use "Return" in a
https://riptutorial.com/ 22
line above.
c := a+b
Return
Function implementation:
#Persistent
OnClipboardChange("ClipChanged")
return
ClipChanged(Type) {
ToolTip Clipboard data type: %Type%
Sleep 1000
ToolTip ; Turn off the tip.
}
Label implementation:
#Persistent
return
OnClipboardChange:
ToolTip Clipboard data type: %A_EventInfo%
Sleep 1000
ToolTip ; Turn off the tip.
return
More complicated Gui example with multiple listviews using the same event
callback function
This script demonstrates how to receive complicated GUI events from different controls in the
same event callback function. We'll be using two ListView controls for that.
Now every time an action is detected on one of those ListView controls, we want a precise
description of what happened and have that logged into an edit control in the same GUI.
https://riptutorial.com/ 23
; Create example entries for the second ListView
Gui, ListView, MySecondListView
Loop, 10 {
LV_Add("", "Column-1 | Row-" A_Index , "Column-2 | Row-" A_Index, "Column-3 | Row-"
A_Index)
}
LV_ModifyCol()
If (guiEvent = "DoubleClick") {
whatHappened .= "`nThe user has double-clicked within the control."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "R") {
whatHappened .= "`nThe user has double-right-clicked within the control."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "ColClick") {
whatHappened .= "`nThe user has clicked a column header."
whatHappened .= "`n> Column number: " eventInfo
} Else If (guiEvent = "D") {
whatHappened .= "`nThe user has attempted to start dragging a row or icon."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "d") {
whatHappened .= "`nThe user has attempted to start right-click-dragging a row or
icon."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "e") {
whatHappened .= "`nThe user has finished editing the first field of a row."
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "Normal") {
whatHappened .= "`nThe user has left-clicked a row."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "RightClick") {
whatHappened .= "`nThe user has right-clicked a row."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "A") {
whatHappened .= "`nA row has been activated."
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "C") {
whatHappened .= "`nThe ListView has released mouse capture."
} Else If (guiEvent = "E") {
whatHappened .= "`nThe user has begun editing the first field of a row."
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "F") {
whatHappened .= "`nThe ListView has received keyboard focus."
} Else If (guiEvent = "f") {
whatHappened .= "`nThe ListView has lost keyboard focus."
} Else If (guiEvent = "I") {
whatHappened .= "`nItem changed. (A row has changed by becoming selected/deselected,
checked/unchecked, etc.)"
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "K") {
whatHappened .= "`nThe user has pressed a key while the ListView has focus."
whatHappened .= "`n> Key pressed: " GetKeyName(Format("vk{:x}", eventInfo))
} Else If (guiEvent = "M") {
https://riptutorial.com/ 24
whatHappened .= "`nItem changed. (A row has changed by becoming selected/deselected,
checked/unchecked, etc.)"
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "S") {
whatHappened .= "`nMarquee. The user has started to drag a selection-rectangle around
a group of rows or icons."
} Else If (guiEvent = "s") {
whatHappened .= "`nThe user has finished scrolling the ListView."
}
GuiControlGet, Log
GuiControl,, Log, % whatHappened "`n---------------------`n" Log
}
GuiClose(hWnd) {
WinGetTitle, windowTitle, ahk_id %hWnd%
MsgBox, The Gui with title "%windowTitle%" is going to be closed! This script will exit
afterwards!
ExitApp
}
https://riptutorial.com/ 25
Credits
S.
Chapters Contributors
No
Getting started with blackholyman, Community, depperm, Forivin, Joe DF, Shyam
1
AutoHotkey Sundar Shankar, tlm, Vijay
Open a File in a
7 freestock.tk
Script
Use functions
8 Forivin
instead of labels
https://riptutorial.com/ 26