AutoHotkey Beginner Tutorial by tidbit

Table of Contents

  1. The Basics
    1. Downloading and installing AutoHotkey
    2. How to create a script
    3. How to find the help file on your computer
  2. Hotkeys & Hotstrings
    1. Keys and their mysterious symbols
    2. Window specific hotkeys/hotstrings
    3. Multiple hotkeys/hotstrings per file
    4. Examples
  3. Sending Keystrokes
    1. Games
  4. Running Programs & Websites
  5. Function Calls with or without Parentheses
    1. Code blocks
  6. Variables
    1. Getting user input
    2. Other Examples?
  7. Objects
    1. Creating Objects
    2. Using Objects
  8. Other Helpful Goodies
    1. The mysterious square brackets
    2. Finding your AHK version
    3. Trial and Error
    4. Indentation
    5. Asking for Help
    6. Other links

1 - The Basics

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.

a. Downloading and installing AutoHotkey

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.

Text instructions:

  1. Go to the AutoHotkey Homepage: https://www.autohotkey.com/
  2. 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.
  3. The downloaded file should be named AutoHotkey_*_setup.exe or similar. Run this and click Install.
  4. Once done, great! Continue on to section b.

b. How to create a script

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".

Text instructions:

  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. It must end with a .ahk extension. For example: 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 function and variables, see section 5.

    Here is a very basic script containing a hotkey which types text using the Send function when the hotkey is pressed:

    ^j::
    {
        Send "My First Script"
    }

    We will get more in-depth later on. Until then, here's an explanation of the above code:

  8. Save the File.
  9. Double-click the file/icon in the desktop to run it. Open notepad or (anything you can type in) and press Ctrl and J.
  10. Hip Hip Hooray! Your first script is done. Go get some reward snacks then return to reading the rest of this tutorial.

For a video instruction, watch Install and Hello World on YouTube.

c. How to find the help file on your computer

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.

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.

Look for AutoHotkey.chm or a file that says AutoHotkey and has a yellow question mark on it.

If you don't need to find the file itself, there are also a number of ways to launch it:

2 - Hotkeys & Hotstrings

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:

^j::
{
    Send "My First Script"
}

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:

::ftw::Free the whales

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".

"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.

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.

Esc::
{
    MsgBox "Escape!!!!"
}

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.

Hotstrings, as mentioned above, can also launch scripted actions. That's fancy talk for "do pretty much anything". Same with hotkeys.

::btw::
{
    MsgBox "You typed btw."
}

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.

^j::
{
    MsgBox "Wow!"
    MsgBox "There are"
    Run "notepad.exe"
    WinActivate "Untitled - Notepad"
    WinWaitActive "Untitled - Notepad"
    Send "7 lines{!}{Enter}"
    SendInput "inside the CTRL{+}J hotkey."
}

a. Keys and their mysterious symbols

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:

Symbol Description
# 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.

(For the full list of symbols, see the Hotkey page)

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 Joystick Controls.

You can define a custom combination of two (and only two) keys (except joystick 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:

Numpad0 & Numpad1::
{
    MsgBox "You pressed Numpad1 while holding down Numpad0."
}

Numpad0 & Numpad2::
{
    Run "notepad.exe"
}

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:

:*:ftw::Free the whales

Visit Hotkeys and Hotstrings for additional hotkey and hotstring modifiers, information and examples.

b. Window specific hotkeys/hotstrings

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:

#HotIf WinActive(WinTitle)
#HotIf WinExist(WinTitle)

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.

#HotIf WinActive("Untitled - Notepad")
#Space::
{
    MsgBox "You pressed WIN+SPACE in Notepad."
}

To turn off context sensitivity for subsequent hotkeys or hotstrings, specify #HotIf without its parameter. For example:

; Untitled - Notepad
#HotIf WinActive("Untitled - Notepad")
!q::
{
    MsgBox "You pressed ALT+Q in Notepad."
}

; Any window that isn't Untitled - Notepad
#HotIf
!q::
{
    MsgBox "You pressed ALT+Q in any window."
}

When #HotIf directives are never used in a script, all hotkeys and hotstrings are enabled for all windows.

The #HotIf directive is positional: it affects all hotkeys and hotstrings physically beneath it in the script, until the next #HotIf directive.

; Notepad
#HotIf WinActive("ahk_class Notepad")
#Space::
{
    MsgBox "You pressed WIN+SPACE in Notepad."
}
::msg::You typed msg in Notepad

; MSPaint
#HotIf WinActive("Untitled - Paint")
#Space::
{
    MsgBox "You pressed WIN+SPACE in MSPaint!"
}
::msg::You typed msg in MSPaint!

For more in-depth information, check out the #HotIf page.

c. Multiple hotkeys/hotstrings per file

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).

#i::
{
    Run "https://www.google.com/"
}

^p::
{
    Run "notepad.exe"
}

~j::
{
    Send "ack"
}

:*:acheiv::achiev
::achievment::achievement
::acquaintence::acquaintance
:*:adquir::acquir
::aquisition::acquisition
:*:agravat::aggravat
:*:allign::align
::ameria::America

The above code is perfectly acceptable. Multiple hotkeys, multiple hotstrings. All in one big happy script file.

d. Examples

::btw::by the way  ; Replaces "btw" with "by the way" as soon as you press an default ending character.
:*:btw::by the way  ; Replaces "btw" with "by the way" without needing an ending character.
^n::  ; CTRL+N hotkey
{
    Run "notepad.exe"  ; Run Notepad when you press CTRL+N.
}  ; This ends the hotkey. The code below this will not be executed when pressing the hotkey.
^b::  ; CTRL+B hotkey
{
    Send "{Ctrl down}c{Ctrl up}"  ; Copies the selected text. ^c could be used as well, but this method is more secure.
    SendInput "[b]{Ctrl down}v{Ctrl up}[/b]" ; Wraps the selected text in BBCode tags to make it bold in a forum.
}  ; This ends the hotkey. The code below this will not be executed when pressing the hotkey.

3 - Sending Keystrokes

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.

But before we get into things, we should talk about some common issues that people have.

Just like hotkeys, the Send function has special keys too. Lots and lots of them. Here are the four most common symbols:

Symbol Description
! 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.

The gigantic table on the Send page shows pretty much every special key built-in to AHK. For example: {Enter} and {Space}.

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.

An example showing what shouldn't be done to a hotkey:

; When making a hotkey...
; WRONG
{LCtrl}::
{
    Send "AutoHotkey"
}

; CORRECT
LCtrl::
{
    Send "AutoHotkey"
}

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:

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.
; Same as above, but with the ENTER key. AHK would type out "Enter" if
; it wasn't wrapped in curly brackets.
Send "Multiple Enter lines have Enter been sent." ; WRONG
Send "Multiple{Enter}lines have{Enter}been sent." ; CORRECT

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:

Send "{a}"       ; WRONG
Send "{b}"       ; WRONG
Send "{c}"       ; WRONG
Send "{a}{b}{c}" ; WRONG
Send "{abc}"     ; WRONG
Send "abc"       ; CORRECT

To hold down or release a key, enclose the key name in curly brackets and then use the word UP or DOWN. For example:

; This is how you hold one key down and press another key (or keys).
; If one method doesn't work in your program, please try the other.
Send "^s"                     ; Both of these send CTRL+S
Send "{Ctrl down}s{Ctrl up}"  ; Both of these send CTRL+S
Send "{Ctrl down}c{Ctrl up}"
Send "{b down}{b up}"
Send "{Tab down}{Tab up}"
Send "{Up down}"  ; Press down the up-arrow key.
Sleep 1000        ; Keep it down for one second.
Send "{Up up}"    ; Release the up-arrow key.

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.

Send "
(
Line 1
Line 2
Apples are a fruit.
)"

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.

a. Games

This is important: A lot of games, especially modern ones, have cheat prevention software. 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.

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.

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.

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.

4 - Running Programs & Websites

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:

; Run a program. Note that most programs will require a FULL file path:
Run A_ProgramFiles "\Some_Program\Program.exe"

; Run a website:
Run "https://www.autohotkey.com"

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.

Here are a few more samples:

; Several programs do not need a full path, such as Windows-standard programs:
Run "notepad.exe"
Run "mspaint.exe"

; Run the "My Documents" folder using a built-in variable:
Run A_MyDocuments

; Run some websites:
Run "https://www.autohotkey.com"
Run "https://www.google.com"

For more in-depth information and examples, check out the Run page.

5 - Function Calls with or without Parentheses

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.

A list of all built-in functions can be found here.

A typical function call looks like this:

Function(Parameter1, Parameter2, Parameter3) ; with parentheses
Function Parameter1, Parameter2, Parameter3  ; without parentheses

The parameters support any kind of expression; this means for example:

  1. You can do math in them:
    SubStr(37 * 12, 1, 2)
    SubStr(A_Hour - 12, 2)
  2. 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):
    SubStr(A_AhkPath, InStr(A_AhkPath, "AutoHotkey"))
  3. Text needs to be wrapped in quotes:
    SubStr("I'm scripting, awesome!", 16)

The most common way assigning the return value of a function to a variable is like so:

MyVar := SubStr("I'm scripting, awesome!", 16)

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.

In short:

; These are function calls without parentheses:
MsgBox "This is some text."
StrReplace Input, "AutoHotKey", "AutoHotkey"
SendInput "This is awesome{!}{!}{!}"

; These are function calls with parentheses:
SubStr("I'm scripting, awesome!", 16)
FileExist(VariableContainingPath)
Output := SubStr("I'm scripting, awesome!", 16)

a. Code blocks

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.

In the following code, both lines are run only if MyVar equals 5:

if (MyVar = 5)
{
    MsgBox "MyVar equals " MyVar "!!"
    ExitApp
}

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:

if (MyVar = 5)
    MsgBox "MyVar equals " MyVar "!!"
    ExitApp

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:

if (MyVar = 5)
    MsgBox "MyVar equals " MyVar "!!"
MsgBox "We are now 'outside' of the if-statement. We did not need curly brackets since there was only one line below it."

6 - Variables

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.

Variables can be assigned a few ways. We'll cover the most common forms. Please pay attention to the colon equal sign (:=).

Text assignment
MyVar := "Text"

This is the simplest form for a variable. Simply type in your text and done. Any text needs to be in quotes.

Variable assignment
MyVar := MyVar2

Same as above, but you are assigning a value of a variable to another variable.

Number assignment
MyVar := 6 + 8 / 3 * 2 - Sqrt(9)

Thanks to expressions, you can do math!

Mixed assignment
MyVar := "The value of 5 + " MyVar2 " is: " 5 + MyVar2

A combination of the three assignments above.

Equal signs (=) with a symbol in front of it such as := += -= .= etc. are called assignment operators and always require an expression.

a. Getting user input

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:

OutputVar := InputBox("What is your first name?", "Question 1").Value
if (OutputVar = "Bill")
    MsgBox "That's an awesome name, " OutputVar "."

OutputVar2 := InputBox("Do you like AutoHotkey?", "Question 2").Value
if (OutputVar2 = "yes")
    MsgBox "Thank you for answering " OutputVar2 ", " OutputVar "! We will become great friends."
else
    MsgBox OutputVar ", That makes me sad."

b. Other Examples?

Result := MsgBox("Would you like to continue?",, 4)
if Result = "No"
    return  ; If No, stop the code from going further.
MsgBox "You pressed YES."  ; Otherwise, the user picked yes.
Var := "text"  ; Assign some text to a variable.
Num := 6  ; Assign a number to a variable.
Var2 := Var  ; Assign a variable to another.
Var3 .= Var  ; Append a variable to the end of another.
Var4 += Num  ; Add the value of a variable to another.
Var4 -= Num  ; Subtract the value of a variable from another.
Var5 := SubStr(Var, 2, 2)  ; Variable inside a function.
Var6 := Var "Text"  ; Assigns a variable to another with some extra text.
MsgBox(Var)  ; Variable inside a function.
MsgBox Var  ; Same as above.
Var := StrSplit(Var, "x")  ; Variable inside a function that uses InputVar and OutputVar.
if (Num = 6)  ; Check if a variable is equal to a number.
if Num = 6  ; Same as above.
if (Var != Num)  ; Check if a variable is not equal to another.
if Var1 < Var2  ; Check if a variable is lesser than another.

7 - Objects

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.

There are a number of reasons you might want to use an object for something. Some examples:

a. Creating Objects

There are a few ways to create an object, and the most common ones are listed below:

Bracket syntax (Array)
MyArray := ["one", "two", "three", 17]

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.

Brace syntax
Banana := {Color: "Yellow", Taste: "Delicious", Price: 3}

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 property Color and the value 3 is stored in the property Price.

Array constructor
MyArray := Array("one", "two", "three", 17)

This is equivalent to the bracket syntax. It is actually calling the Array class, not a function.

Map constructor
MyMap := Map("^", "Ctrl", "!", "Alt")

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.

Other constructor
Banana := Fruit()

Creates an object of the given class (Fruit in this case).

b. Using Objects

There are many ways to use objects, including retrieving values, setting values, adding more values, and more.

To set values:

Bracket notation
MyArray[2] := "TWO"
MyMap["#"] := "Win"

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.

Dot notation
Banana.Consistency := "Mushy"

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.

To retrieve values:

Bracket notation
Value := MyMap["^"]

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].

Dot notation
Value := Banana.Color

This example retrieves the Color property of the object Banana.

To add new keys and values:

Bracket notation
MyMap["NewerKey"] := 3.1415

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.

Dot notation
MyObject.NewProperty := "Shiny"

As mentioned above, assigning to a property that hasn't already been defined will create a new property.

InsertAt method
MyArray.InsertAt(Index, Value1, Value2, Value3...)

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.

Push method
MyArray.Push(Value1, Value2, Value3...)

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.

To remove properties and items:

Delete method
RemovedValue := MyObject.Delete(AnyKey)

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.

Pop method
MyArray.Pop()

This Array method removes the last element from an array and returns its value. The array's length is reduced by 1.

RemoveAt method
RemovedValue := MyArray.RemoveAt(Index)
MyArray.RemoveAt(Index, Length)

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.

8 - Other Helpful Goodies

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!

a. The mysterious square brackets

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.

On the ControlGetText page you will see this:

Text := ControlGetText(Control , WinTitle, WinText, ExcludeTitle, ExcludeText)

So you could simply do this if you wanted:

Text := ControlGetText(Control)

Or add in some more details:

Text := ControlGetText(Control, WinTitle)

What if you wanted to use ExcludeTitle but not fill in WinText or WinTitle? Simple!

Text := ControlGetText(Control,,, ExcludeTitle)

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:

Text := ControlGetText(Control, ExcludeTitle)

b. Finding your AHK version

Run this code to see your AHK version:

MsgBox A_AhkVersion

Or look for "AutoHotkey Help File" or "AutoHotkey.chm" in the start menu or your installation directory.

c. Trial and Error

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.

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!

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.

"If at first you don't succeed, try, try, try again." - Hickson, William E.

d. Indentation

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.

"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".

Not indented:

if (car = "old")
{
MsgBox "The car is really old."
if (wheels = "flat")
{
MsgBox "This car is not safe to drive."
return
}
else
{
MsgBox "Be careful! This old car will be dangerous to drive."
}
}
else
{
MsgBox "My, what a shiny new vehicle you have there."
}

Indented:

if (car = "old")
{
    MsgBox "The car is really old."
    if (wheels = "flat")
    {
        MsgBox "This car is not safe to drive."
        return
    }
    else
    {
        MsgBox "Be careful! This old car will be dangerous to drive."
    }
}
else
{
    MsgBox "My, what a shiny new vehicle you have there."
}

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.

e. Asking for Help

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.

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.

And while you wait for help, you can try learning and doing it yourself. It's a good feeling, making something yourself without help.

f. Other links

Frequently Asked Questions (FAQ)