^j:: ; hotkey label
::ftw::Free the whales ; hotstring label abbreviation
::btw:: ; hotstring label action
MsgBox, You typed btw.
Run, notepad.exe  ; Run Notepad when you press CTRL+N.
MsgBox, Wow!
MsgBox, There are
Run, notepad.exe
WinActivate, Untitled - Notepad
WinWaitActive, Untitled - Notepad
Send, 7 lines{!}{Enter}
SendInput, inside the CTRL{+}J hotkey.
return

Numpad0 & Numpad1::
MsgBox, You pressed Numpad1 while holding down Numpad0.
Run, notepad.exe
return

; Untitled - Notepad
#IfWinActive Untitled - Notepad
!q::
MsgBox, You pressed ALT+Q in Notepad.
return

; Any window that isn't Untitled - Notepad
#IfWinActive
!q::
MsgBox, You pressed ALT+Q in any window.
return

; Retrieve the ID/HWND of the active window
id := WinExist("A")
MsgBox % id

; Press Win+↑ to maximize the active window
#Up::WinMaximize, A

#i::
Run, https://www.google.com/
return

^p::
Run, notepad.exe
return

~j::
Send, ack
return

:*:acheiv::achiev
::achievment::achievement
::acquaintence::acquaintance
:*:adquir::acquir
::aquisition::acquisition
:*:agravat::aggravat
:*:allign::align
::ameria::America
:*:ftw::Free the whales ; Hotstring modifiers
this_is_a_label: ; label

#IfWinActive Untitled - Notepad
#Space::
MsgBox, You pressed WIN+SPACE in Notepad.
return

Send, {Ctrl down}c{Ctrl up}
SendInput, [b]{Ctrl down}v{Ctrl up}[/b]
return  ; This ends the hotkey. The code below this point will not get triggered.

Send, This text has been typed{!}
Send, {a}       ; WRONG
Send, {a}{b}{c} ; WRONG
Send, {abc}     ; WRONG
Send, abc       ; CORRECT
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.

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

Send %A_Hour%
SubStr(37 * 12, 1, 2)
SubStr(A_Hour - 12, 2)
SubStr(A_AhkPath, InStr(A_AhkPath, "AutoHotkey"))
SubStr("I'm scripting, awesome!", 16)

SetTitleMatchMode RegEx
WinActivate ahk_exe i)\\notepad\.exe$  ; Match the name part of the full path.
WinActivate ahk_exe im)(*BSR_ANYCRLF)abc\Rxyz
WinActivate ahk_exe im)(*BSR_ANY[^]]CRLF)abc\Rxyz

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

MyVar = Text
MyVar = %MyVar2%
MyVar = %MyVar2% some text %MyVar3%.
MyVar := SubStr("I'm scripting, awesome!", 16)
MyVar := "Text"
MyVar := MyVar2
MyVar := 6 + 8 / 3 * 2 - Sqrt(9)
MyVar := "The value of 5 + " MyVar2 " is: " 5 + MyVar2
if (Var1 != Var2)
    Var1 := Var2 + 100

; Some examples showing when to use percents and when not:
Var = Text  ; Assign some text to a variable (legacy).
Number := 6  ; Assign a number to a variable (expression).
Var2 = %Var%  ; Assign a variable to another (legacy).
Var3 := Var  ; Assign a variable to another (expression).
Var4 .= Var  ; Append a variable to the end of another (expression).
Var5 += Var  ; Add the value of a variable to another (expression).
Var5 -= Var  ; Subtract the value of a variable from another (expression).
Var6 := SubStr(Var, 2, 2)  ; Variable inside a function. This is always an expression.
Var7 = %Var% Text  ; Assigns a variable to another with some extra text (legacy).
Var8 := Var " Text"  ; Assigns a variable to another with some extra text (expression).
MsgBox, %Var%  ; Variable inside a command.
StringSplit, Var, Var, x  ; Variable inside a command that uses InputVar and OutputVar.
if (Number = 6)  ; Whenever an IF has parentheses, it'll be an expression. So no percent signs.
if (Var != Number)  ; Whenever an IF has parentheses, it'll be an expression. So no percent signs.
if Number = 6  ; Without parentheses, the IF is legacy. However, only variables on the 'right side' need percent signs.
if Var1 < %Var2%  ; Without parentheses, the IF is legacy. However, only variables on the 'right side' need percent signs.

MyObject := ["one", "two", "three", 17]
Banana := {"Color": "Yellow", "Taste": "Delicious", "Price": 3}
MyObject := Array("one", "two", "three", 17)
Banana := Object("Color", "Yellow", "Taste", "Delicious", "Price", 3)
Banana["Pickled"] := True ; This banana has been pickled. Eww.
Banana.Consistency := "Mushy"
Value := Banana["Color"]
Value := Banana.Color
MyObject["NewerKey"] := 3.1415
MyObject.NewKey := "Shiny"
MyObject.Push(Value1, Value2, Value3...)
Banana.Consistency := ""
RemovedValue := MyObject.Delete(AnyKey)
NumberOfRemovedKeys := MyObject.Delete(FirstKey, LastKey)
arr := [{}]  ; Creates an array containing an object.
arr[1] := {}  ; Creates a second object, implicitly freeing the first object.
arr.RemoveAt(1)  ; Removes and frees the second object.
x := {}, y := {}             ; Create two objects.
x.child := y, y.parent := x  ; Create a circular reference.
y.parent := ""
x := "", y := ""
table.base.__Get(table, x)[y] := content   ; A
table.base.__Set(table, x, y, content)     ; B
RemovedValue := MyObject.RemoveAt(Index)
NumberOfRemovedKeys := MyObject.RemoveAt(Index, Length)
val := obj.Property := 42
m1 := new GMem(0, 20)
m2 := {base: GMem}.__New(0, 30)
x ? CallIfTrue() : CallIfFalse()
ProductIsAvailable := (Color = "Red")
    ? false  ; We don't have any red products, so don't bother calling the function.
    : ProductIsAvailableInColor(Product, Color)
MyObject.Pop()
%Var%()

Sleep MillisecondsToWait
Sleep %MillisecondsToWait%
Sleep % MillisecondsToWait
MsgBox % 1+1  ; Shows "2"
MsgBox   1+1  ; Shows "1+1"

MsgBox % "This is text."
MsgBox    This is text.
MsgBox %  A_AhkVersion
MsgBox   %A_AhkVersion%
MsgBox % %A_AhkVersion%
MsgBox % "Hello %A_UserName%."  ; Shows "%A_UserName%"
MsgBox    Hello %A_UserName%.   ; Shows your username.
MsgBox % "Hello " . A_UserName . "."  ; Shows your username.
MyVar := "This is text."
MyVar = This is text.

if (Var1 = Var2)
if Var1 = %Var2%
if (Var1 >= Low and Var1 <= High)
if Var1 between %Low% and %High%

Format("{:L}{:U}{:T}", input, input, input)

*#up::MouseMove, 0, -10, 0, R  ; Win+UpArrow hotkey => Move cursor upward
*#Down::MouseMove, 0, 10, 0, R  ; Win+DownArrow => Move cursor downward
*#Left::MouseMove, -10, 0, 0, R  ; Win+LeftArrow => Move cursor to the left
*#Right::MouseMove, 10, 0, 0, R  ; Win+RightArrow => Move cursor to the right

*<#RCtrl::  ; LeftWin + RightControl => Left-click (hold down Control/Shift to Control-Click or Shift-Click).
SendEvent {Blind}{LButton down}
KeyWait RCtrl  ; Prevents keyboard auto-repeat from repeating the mouse click.
SendEvent {Blind}{LButton up}
return

*<#AppsKey::  ; LeftWin + AppsKey => Right-click
SendEvent {Blind}{RButton down}
KeyWait AppsKey  ; Prevents keyboard auto-repeat from repeating the mouse click.
SendEvent {Blind}{RButton up}
return

#Persistent  ; Keep this script running until the user explicitly exits it.
SetTimer, WatchPOV, 5
return

WatchPOV:
POV := GetKeyState("JoyPOV")  ; Get position of the POV control.
KeyToHoldDownPrev := KeyToHoldDown  ; Prev now holds the key that was down before (if any).

; Some joysticks might have a smooth/continous POV rather than one in fixed increments.
; To support them all, use a range:
if (POV < 0)   ; No angle to report
    KeyToHoldDown := ""
else if (POV > 31500)               ; 315 to 360 degrees: Forward
    KeyToHoldDown := "Up"
else if POV between 0 and 4500      ; 0 to 45 degrees: Forward
    KeyToHoldDown := "Up"
else if POV between 4501 and 13500  ; 45 to 135 degrees: Right
    KeyToHoldDown := "Right"
else if POV between 13501 and 22500 ; 135 to 225 degrees: Down
    KeyToHoldDown := "Down"
else                                ; 225 to 315 degrees: Left
    KeyToHoldDown := "Left"

if (KeyToHoldDown = KeyToHoldDownPrev)  ; The correct key is already down (or no key is needed).
    return  ; Do nothing.

; Otherwise, release the previous key and press down the new key:
SetKeyDelay -1  ; Avoid delays between keystrokes.
if KeyToHoldDownPrev   ; There is a previous key to release.
    Send, {%KeyToHoldDownPrev% up}  ; Release it.
if KeyToHoldDown   ; There is a key to press down.
    Send, {%KeyToHoldDown% down}  ; Press it down.
return

<^>!m::MsgBox You pressed AltGr+m.
<^<!m::MsgBox You pressed LeftControl+LeftAlt+m.

AppsKey::ToolTip Press < or > to cycle through windows.
AppsKey Up::ToolTip
~AppsKey & <::Send !+{Esc}
~AppsKey & >::Send !{Esc}

; Press AppsKey and Alt in any order, then slash (/).
#if GetKeyState("AppsKey", "P")
Alt & /::MsgBox Hotkey activated.

; If the keys are swapped, Alt must be pressed first (use one at a time):
#if GetKeyState("Alt", "P")
AppsKey & /::MsgBox Hotkey activated.

; [ & ] & \::
#if GetKeyState("[") && GetKeyState("]")
\::MsgBox

; Ctrl+Shift+O to open containing folder in Explorer.
; Ctrl+Shift+E to open folder with current file selected.
; Supports SciTE and Notepad++.
^+o::
^+e::
    editor_open_folder() {
        WinGetTitle, path, A
        if RegExMatch(path, "\*?\K(.*)\\[^\\]+(?= [-*] )", path)
            if (FileExist(path) && A_ThisHotkey = "^+e")
                Run explorer.exe /select`,"%path%"
            else
                Run explorer.exe "%path1%"
    }

#h::  ; Win+H hotkey
; Get the text currently selected. The clipboard is used instead of
; "ControlGet Selected" because it works in a greater variety of editors
; (namely word processors).  Save the current clipboard contents to be
; restored later. Although this handles only plain text, it seems better
; than nothing:
AutoTrim Off  ; Retain any leading and trailing whitespace on the clipboard.
ClipboardOld := ClipboardAll
Clipboard := ""  ; Must start off blank for detection to work.
Send ^c
ClipWait 1
if ErrorLevel  ; ClipWait timed out.
    return
; Replace CRLF and/or LF with `n for use in a "send-raw" hotstring:
; The same is done for any other characters that might otherwise
; be a problem in raw mode:
StringReplace, Hotstring, Clipboard, ``, ````, All  ; Do this replacement first to avoid interfering with the others below.
StringReplace, Hotstring, Hotstring, `r`n, ``r, All  ; Using `r works better than `n in MS Word, etc.
StringReplace, Hotstring, Hotstring, `n, ``r, All
StringReplace, Hotstring, Hotstring, %A_Tab%, ``t, All
StringReplace, Hotstring, Hotstring, `;, ```;, All
Clipboard := ClipboardOld  ; Restore previous contents of clipboard.
; This will move the InputBox's caret to a more friendly position:
SetTimer, MoveCaret, 10
if ErrorLevel  ; The user pressed Cancel.
    return
if InStr(Hotstring, ":R`:::")
{
    MsgBox You didn't provide an abbreviation. The hotstring has not been added.
    return
}
; Otherwise, add the hotstring and reload the script:
FileAppend, `n%Hotstring%, %A_ScriptFullPath%  ; Put a `n at the beginning in case file lacks a blank line at its end.
Reload
Sleep 200
MsgBox, 4,, The hotstring just added appears to be improperly formatted.
IfMsgBox, Yes, Edit
return

MoveCaret:
IfWinNotActive, New Hotstring
    return
; Otherwise, move the InputBox's insertion point to where the user will type the abbreviation.
Send {Home}{Right 3}
SetTimer, MoveCaret, Off
return

; This example also demonstrates one way to implement case conformity in a script.
:C:BTW::  ; Typed in all-caps.
:C:Btw::  ; Typed with only the first letter upper-case.
: :btw::  ; Typed in any other combination.
    case_conform_btw() {
        hs := A_ThisHotkey  ; For convenience and in case we're interrupted.
        if (hs == ":C:BTW")
            Send BY THE WAY
        else if (hs == ":C:Btw")
            Send By the way
        else
            Send by the way
    }

#IfWinActive ahk_class Notepad
::btw::This replacement text will appear only in Notepad.
#IfWinActive
::btw::This replacement text appears in windows other than Notepad.

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

Hotstring("EndChars", "-()[]{}:;")

::btw::
MsgBox You typed "``btw``".
return

:*:]d::  ; This hotstring replaces "]d" with the current date and time via the commands below.

MyFunction(FirstParameter, Second, ByRef Third, Fourth:="")
{
    return "a value"
}

Loop 3
    MsgBox % MyArray%A_Index%

SysGet, WA, MonitorWorkArea
MsgBox, Left: %WALeft% -- Top: %WATop% -- Right: %WARight% -- Bottom: %WABottom%.

n := 123 00123 -1.  0x7B 0x007B -0x1  3.14159

FileAppend,   ; Comment.
; Comment.
( LTrim Join    ; Comment.
     ; This is not a comment; it is literal. Include the word Comments in the line above to make it a comment.
), C:\File.txt   ; Comment.

param := %A_Index%  ; Fetch the contents of the variable whose name is contained in A_Index.

Add(X, Y, Z:=0) {
    return X + Y + Z
}

Join(sep, params*) {
    for index,param in params
        str .= param . sep
    return SubStr(str, 1, -StrLen(sep))
}
MsgBox % Join("`n", "one", "two", "three")

LogToFile(TextToLog)
{
    global LogFileName  ; This global variable was previously given a value somewhere outside this function.
    FileAppend, %TextToLog%`n, %LogFileName%
}

SetDefaults()
{
    global
    MyGlobal := 33
    local x, y:=0, z
}

LogToFile(TextToLog)
{
    static LoggedLines := 0
    LoggedLines += 1
    global LogFileName
    FileAppend, %LoggedLines%: %TextToLog%`n, %LogFileName%
}

GetFromStaticArray(WhichItemNumber)
{
    static
    static FirstCallToUs := true
    if FirstCallToUs
    {
        FirstCallToUs := false
        Loop 10
            StaticArray%A_Index% := "Value #" . A_Index
    }
    return StaticArray%WhichItemNumber%
}

if (ColorName != "" AND not FindColor(ColorName))
    MsgBox %ColorName% could not be found.

class baseObject {
    static foo := "bar"
}
baseObject := {foo: "bar"}

thing := {}
thing.foo := "bar"
thing.test := Func("thing_test")
thing.test()

thing_test(this) {
    MsgBox % this.foo
}

class Color
{
    __New(aRGB)
    {
        this.RGB := aRGB
    }

    __Delete()
    {
        MsgBox % "Delete Color."
    }

    static Shift := {R:16, G:8, B:0}

    __Get(aName)
    {
        ; NOTE: Using this.Shift here would cause an infinite loop!
        shift := Color.Shift[aName]  ; Get the number of bits to shift.
        if (shift != "")  ; Is it a known property?
            return (this.RGB >> shift) & 0xff
        ; NOTE: Using 'return' here would break this.RGB.
    }

    __Set(aName, aValue)
    {
        if ((shift := Color.Shift[aName]) != "")
        {
            aValue &= 255  ; Truncate it to the proper range.

            ; Calculate and store the new RGB value.
            this.RGB := (aValue << shift) | (this.RGB & ~(0xff << shift))

            ; 'Return' must be used to indicate a new key-value pair should not be created.
            ; This also defines what will be stored in the 'x' in 'x := clr[name] := val':
            return aValue
        }
        ; NOTE: Using 'return' here would break this.stored_RGB and this.RGB.
    }

    ; Meta-functions can be mixed with properties:
    RGB {
        get {
            ; Return it in hex format:
            return format("0x{:06x}", this.stored_RGB)
        }
        set {
            return this.stored_RGB := value
        }
    }

    class __Get extends Properties
    {
        R() {
            return (this.RGB >> 16) & 255
        }
        G() {
            return (this.RGB >> 8) & 255
        }
        B() {
            return this.RGB & 255
        }
    }

    Property[]  ; Brackets are optional
    {
        get {
            return ...
        }
        set {
            return ... := value
        }
    }
}

class Properties extends FunctionObject
{
    Call(aTarget, aName, aParams*)
    {
        ; If this Properties object contains a definition for this half-property, call it.
        if ObjHasKey(this, aName)
            return this[aName].Call(aTarget, aParams*)
    }
}

MyGet(this, Key, Key2)
MySet(this, Key, Key2, Value)
MyCall(this, Name, Params)

ClassName := { __Get: Func("MyGet"), __Set: Func("MySet"), __Call: Func("MyCall") }

red  := new Color(0xff0000), red.R -= 5
cyan := new Color(0), cyan.G := 255, cyan.B := 255

MsgBox % "red: " red.R "," red.G "," red.B " = " red.RGB
MsgBox % "cyan: " cyan.R "," cyan.G "," cyan.B " = " cyan.RGB

; This example requires the FunctionObject class in order to work.
blue := new Color(0x0000ff)
MsgBox % blue.R "," blue.G "," blue.B

x := {base: {addr: Func("x_Addr"), __Set: Func("x_Setter")}}

; Assign value, implicitly calling x_Setter to create sub-objects.
x[1,2,3] := "..."

; Retrieve value and call example method.
MsgBox % x[1,2,3] "`n" x.addr() "`n" x[1].addr() "`n" x[1,2].addr()

x_Setter(x, p1, p2, p3) {
    x[p1] := new x.base
}

x_Addr(x) {
    return &x
}

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

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

MsgBox, 4,, Would you like to continue?
IfMsgBox, No
    return  ; If No, stop the code from going further.
MsgBox, You pressed YES.  ; Otherwise, the user picked yes.

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

if (Color = "Red" or Color = "Green"  or Color = "Blue"   ; Comment.
    or Color = "Black" or Color = "Gray" or Color = "White")   ; Comment.
    and ProductIsAvailableInColor(Product, Color)   ; Comment.

if (codepage != "")
    codepage := " /CP" . codepage
cmd="%A_AhkPath%"%codepage% "`%1" `%*
key=AutoHotkeyScript\Shell\Open\Command
if A_IsAdmin    ; Set for all users.
    RegWrite, REG_SZ, HKCR, %key%,, %cmd%
else            ; Set for current user only.
    RegWrite, REG_SZ, HKCU, Software\Classes\%key%,, %cmd%

^j:: ; hotkey label
MsgBox, You typed btw.