AutoHotkey Expression Examples: "" %% () and all that

AutoHotkey Expression Examples: "" %% () and all that. Good for beginners.

AutoHotkey Expression Examples: "" %% () and all that. 
because I can never get them right, so I made this. These are all working examples.   Version 1.21c  08/24/2009 
[source: http://www.daviddeley.com/autohotkey/xprxmp/autohotkey_expression_examples.htm#K]
CONTENTS: 

A: RETRIEVING COMMAND LINE PARAMETERS
B: COMMON THINGS AT THE BEGINNING AND END OF AUTOHOTKEY SCRIPTS
C: WHEN TO USE %% AROUND VARIABLES
D: ERASE A VARIABLE
E: SET A VARIABLE   :=   [store numbers, quoted strings]
F: SET A VARIABLE   =    [assign unquoted literal strings]
G: COPY A VARIABLE
H: IF STATEMENTS with ()
  H2: Comparing Numeric Values vs. Comparing Strings
I: IF STATEMENTS without () [Translate the 1st, take the 2nd literally]
  I2: Comparing Numeric Values vs. Comparing Strings
J: CHECK FOR A BLANK VARIABLE
K: STRING MANIPULATION 
  K1: Trim whitespace at the start of the string
  K2: Trim whitespace at the end of the string
  K3: Trim whitespace at the start and the end of the string
  K4: Concatenate two strings together
  K5: Two ways of using MsgBox
L: NUMBERS 
L1: Adding numbers together
L2: Adding two strings together:
when both can be interpreted as integers, gives the resulting integer (as a string)
when both can be interpreted as float, gives the resulting float (as a string)
when one or both can NOT be interpreted as a number, result is an empty string
L3: Remove leading and trailing blanks and leading zeros from a number
L4: Various ways to pad a number with leading zeros or spaces
M: working with FILE NAMES
N: REGULAR EXPRESSIONS 
N1: Links to: Cheat Sheets, documentation, programs, libraries
N2: Examples
N3: RegExReplace 
N3.1: Examples
N3.2: Extract Month, Day, Year, from 1/22/2009
N3.3: An example of how we can step by step build up our Regular Expression
N3.4: Find the $ dollar sign. Extract price and add a dollar sign.
O: MISC AUTOHOTKEY NOTES. CAVEATS & DEBUGGING TIPS 
O1: Notes / Caveats
O2: Sending debug data to a log file
O3: Capturing a screen image during run
P: MISC AUTOHOTKEY SCRIPTS 
  P1: Misc AutoHotkey Scripts
  P2: Index of notable scripts found in the AutoHotkey Forum
  P3: AHK Functions - ƒ()
  P4: Library for Text File Manipulation
  P5: Tray Icons
  P6: Force Exit another AutoHotkey script
Q: NAVIGATING WEB SITES 
Q1: Determining when a webpage has finished loading
Q2: Positioning on a control
Q3: Search for a certain colored pixel
R: NEWBIE RECOMMENDED LEARNING SEQUENCE
S: Press ESC to cancel this scipt
T: THE AUTOHOTKEY RUN COMMAND
U: PASSING PARAMETERS TO AUTOHOTKEY SCRIPTS
V: PASSING PARAMETERS TO ANY PROGRAM




/******************************************************************************

NOTE:  ALL VARIABLES ARE STORED AS CHARACTER STRINGS !!! 
Strings containing numbers are converted to numbers when needed, and the result is converted back to a string.
 
NOTE:  Closing */ must be first thing on line. Otherwise you'll be asking yourself, "Why does my script stop running at this point, as if the whole rest of the script was commented out?"




/****************************************************************************** 
A:  PASSING COMMAND LINE PARAMETERS TO AN AUTOHOTKEY SCRIPT 

  • Arguments are delimited by white space, which is either a space or a tab.
  • The caret character (^) is not recognized as an escape character or delimiter. The character is handled completely by the command-line parser in the operating system before being passed to the argv array in the program.
  • A string surrounded by double quotation marks ("string") is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
  • A double quotation mark preceded by a backslash (\") is interpreted as a literal double quotation mark character (").
  • Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
  • If an even number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is interpreted as a string delimiter.
  • If an odd number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is "escaped" by the remaining backslash, causing a literal double quotation mark (") to be placed in argv.
  • Tech note on passing command line parameters to any program

A:  RETRIEVING COMMAND LINE PARAMETERS

NumParams = %0%
Param1 = %1%
Param2 = %2%
Param3 = %3%
MsgBox NumParams = %0%
MsgBox Param1 = %1%
MsgBox Param2 = %2%
MsgBox Param3 = %3%



/****************************************************************************** 
B:  COMMON THINGS OFTEN FOUND AT THE BEGINNING OF AUTOHOTKEY SCRIPTS 

#NoTrayIcon              ;if you don't want a tray icon for this AutoHotkey program.
#NoEnv                   ;Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force    ;Skips the dialog box and replaces the old instance automatically
;;SendMode Input           ;I discovered this causes MouseMove to jump as if Speed was 0. (was Recommended for new scripts due to its superior speed and reliability.)
SetKeyDelay, 90          ;Any number you want (milliseconds)
CoordMode,Mouse,Screen   ;Initial state is Relative
CoordMode,Pixel,Screen   ;Initial state is Relative. Frustration awaits if you set Mouse to Screen and then use GetPixelColor because you forgot this line. There are separate ones for: Mouse, Pixel, ToolTip, Menu, Caret
MouseGetPos, xpos, ypos  ;Save initial position of mouse
WinGet, SavedWinId, ID, A     ;Save our current active window

;Set Up a Log File:
SetWorkingDir, %A_ScriptDir%  ;Set default directory to where this script file is located. (Note %% because it's expecting and unquoted string)
LogFile := "MyLog.txt"
FileAppend, This is a message`n, %LogFile%  ;Note the trailing (`n) to start a new line. This could instead be a leading (`n) if you want. (Note %% because it's expecting and unquoted string)

and things at the end where we restore window and mouse cursor position:

WinActivate ahk_id %SavedWinId%  ;Restore original window
MouseMove, xpos, ypos, 10    ;Restore original mouse position
ExitApp
Esc::ExitApp  ;Press ESC to cancel this script. Placed after the ExitApp.
              ;Note this is a hotkey definition (we're defining the ESC key to run ExitApp). A
              ;hotkey definition line stops execution at that point, so if you want the script
              ;to run to the end but have the ESC key available to terminate the script, put
              ;the hotkey definition at the end, just after your ExitApp statement.




/****************************************************************************** 
C:  WHEN TO USE %% AROUND VARIABLES 

LESSON #1: 
The only place to use %x% is where a literal string NOT enclosed in double-quotes is expected. Otherwise, don't use %% around a variable name. 

Notice in the following examples that unquoted literal strings are expected. 
( = assigns unquoted literal strings ) 

n = Ishmael
x = Call me %n%
MsgBox %x%

x = 500
y = 500
z = 10
MouseMove, 500, 500, 10           ;works
MouseMove, 500 - 1, 500 + 1, 10   ;works
MouseMove,  x, y, z               ;works
MouseMove,  x - 1, y + 1, z + 2   ;works

;However, this doesn't work, because MouseMove
;doesn't expect an unquoted literal string
MouseMove, %x% - 1, %y% + 1, 10   ;doesn't work

    Confusion is caused because the following also happens to work: 

MouseMove, %x%, %y%, %c%   ;works because "for backward compatibility, command parameters that are
                           ;documented as 'can be an expression' treat an isolated name in percent signs
                           ;(e.g. %Var%, but not Array%i%) as though the percent signs are absent."
                           ;        --AutoHotkey Documentation: Variables and Expressions


LESSON #2: 
Use (%x%) (enclosed in parentheses) when x contains the name of a 2nd variable which in turn contains the contents you want. 

a = 500    ;a = "500"
b = 200    ;b = "200"
x := "a"
y := "b"
MouseMove, (%x%), (%y%)            ;x = a, a = 500.  y = b, b = 200
MouseGetPos, xpos, ypos
MsgBox xpos=%xpos%  ypos=%ypos%    ;xpos=500  ypos=200


LESSON #3: 
Instances which look like exceptions to the rule: 

MyDocument := "C:\Program Files\AutoHotkey\license.txt"
Run, notepad.exe "%MyDocument%"

Looks like we're using %% inside a quoted string, but actually the "" are not required, just recommended. This happens to also work:

Run, notepad.exe %MyDocument%

The run function expects an unquoted string, so we use %%, otherwise notepad would try to open a file named 'MyDocument'. 

In the first case above, the run function is actually accepting an unquoted string which happens to begin and end with a double quote character. 
 

Tech Note
I believe the Target string in the AutoHotkey Run command is passed as the command_line parameter to the Windows CreateProcess() function. I see in AutoHotkey source file script.cpp routine Script::ActionExec the call to CreateProcess is:
if (CreateProcess(NULL, command_line, NULL, NULL, FALSE, 0, NULL, aWorkingDir, &si, &pi))
MSDN documentaion for CreateProcess says, "If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin." 

So the beginning and ending double quote characters are actually a part of the string being passed. 

(05/29/2009 — I'm testing how AutoHotkey parses the Run command. I'll post the results when I'm done.) 

Reference:
    CreateProcess() : http://msdn.microsoft.com/en-us/library/ms682425.aspx 
    CreateProcess() : http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx



/****************************************************************************** 
D:  ERASE A VARIABLE 

v =
v := ""



/****************************************************************************** 
E:  SET A VARIABLE (:=) 
Use the colon-equal operator (:=) for storing numbers and quoted strings 

NOTE: All variables including numbers are stored as character strings. Strings are automatically converted to numbers when necessary, then converted back to strings when result is stored in a variable.

ABC := "David"
David := "Susan"

v := "ABC"                      ; v = "ABC"
MsgBox v := "ABC"`n`nv = "%v%"

v := ABC                        ; ABC is a variable. v = "David"
MsgBox v := ABC`n`nv = "%v%"

v := %ABC%                      ; ABC is a variable containing the name of a variable. v = "Susan"
MsgBox v := `%ABC`%`n`nv="%v%"  ; NOTE: If ABC is undefined or blank, program halts!

v := "123"                      ; v = "123" (quotes NOT included)
MsgBox v := "123"`n`nv = "%v%"

v := 123                        ; v = "123" (If it can be interpreted as a number then it's a number, otherwise it's a variable name.)
MsgBox v := 123`n`nv = "%v%"

;123 can be made into a variable, as in this horrendous example:
123 := 456
MsgBox v = %123%  ; message is "v = 456"




/****************************************************************************** 
F:  SET A VARIABLE (=) 
equal sign operator (=) to assign unquoted literal strings 
To include variable ABC instead of literal string "ABC", use %ABC% 

ABC = David
David = Susan

v =  123                        ;v = "123"
MsgBox v = 123`n`nv = "%v%"

v = 0001                        ;v = "0001"
MsgBox v = 0001`n`nv = "%v%"

v = ABC                         ;v = "ABC"
MsgBox v = ABC`n`nv = "%v%"

v = %ABC%                       ;ABC is a variable. v = "David"
MsgBox v = `%ABC`%`n`nv = "%v%" (ABC = "David")

;PROBABLY NOT WHAT YOU WANTED:
v = "ABC"                       ;v = the literal string "ABC" (including double-quotes)
MsgBox v = "ABC"`n`nv = '%v%'




/****************************************************************************** 
G:  COPY A VARIABLE 

ABC := "David"
David := "Susan"

v := ABC                        ; ABC is a variable. v = "David"
MsgBox v := ABC`n`nv = "%v%"
v = %ABC%                       ; ABC is a variable. v = "David"
MsgBox v = `%ABC`%`n`nv = "%v%"

;PROBABLY NOT WHAT YOU WANTED:
v = ABC                         ; v = "ABC" (the literal string)
MsgBox v = ABC`n`nv = "%v%"
v := %ABC%                      ; ABC is a variable containing the name of a variable. v = "Susan"
MsgBox v := `%ABC`%`n`nv="%v%"  ; NOTE: If ABC is undefined, PROGRAM HALTS!
                                        (If David is undefined, then v = "")




/****************************************************************************** 
H:  IF STATEMENTS with () 

SAT := "Saturday"          ;Another way to view this is:
Saturday := "Saturn"       ;  SAT --> Saturday --> Saturn
MON := "Monday"            ;  MON --> Monday --> Moon
Monday := "Moon"

MsgBox SAT := "Saturday"`nSaturday := "Saturn"`nMON := "Monday"`nMonday := "Moon"`n`n(another way to view this:)`nSAT --> Saturday --> Saturn`nMON --> Monday --> Moon`n`n#16

; =
If ("Saturday" = "Saturday")
  MsgBox ("Saturday" = "Saturday")
If ("Saturday" = "SATURDAY")
  MsgBox ("Saturday" = "SATURDAY")

; ==  (case sensitive compare)
If ("Saturday" == "Saturday")              ;== Case Sensitive
  MsgBox ("Saturday" == "Saturday")
If ("Saturday" == "SATURDAY")              ;== Case Sensitive
  MsgBox NO

;SAT = "Saturday"
If (SAT = "Saturday")       ;SAT = "Saturday", compare with "Saturday"
  MsgBox (SAT = "Saturday")
If ("Saturday" = SAT)       ;Reverse works the same
  MsgBox ("Saturday" = SAT)
If (SAT = "xxxxx")
  MsgBox NO
If ("xxxxx" = SAT)
  MsgBox NO

;%SAT% = "Saturn"
If ("Saturn" = "Saturn")
  MsgBox ("Saturn" = "Saturn")
If (%SAT% = "Saturn")  ;SAT = "Saturday", %SAT% = "Saturn", compare with "Saturn" (no problem if SAT not defined)
  MsgBox (`%SAT`% = "Saturn")`n`n(no problem if SAT not defined)
If ("Saturn" = %SAT%)  ;Reverse works the same (no problem if SAT not defined)
  MsgBox ("Saturn" = `%SAT`%)`n`n(no problem if SAT not defined)
If ("xxxxx" = %SAT%)   ;compare "xxxxx" with "Saturn"
  MsgBox NO
If (%SAT% = "xxxxx")   ;compare "Saturn" with "xxxxx"
  MsgBox NO

;"Moon" = %MON%
If ("Moon" = "Moon")
  MsgBox ("Moon" = "Moon")
If (%MON% = "Moon")    ;MON = "Monday", Monday = "Moon", compare with "Moon" (no problem if MON not defined)
  MsgBox (%MON% = "Moon")`n`nMON = "Monday", Monday = "Moon", compare with "Moon"`n`n(no problem if MON not defined)
If ("Moon" = %MON%)    ;"Moon", compare with MON = "Monday", Monday = "Moon" (no problem if MON not defined)
  MsgBox ("Moon" = `%MON`%)`n`n"Moon", compare with MON = "Monday", Monday = "Moon"`n`n(no problem if MON not defined)
If ("xxxxx" = %MON%)   ;compare "xxxxx" with "Moon"
  MsgBox NO
If (%MON% = "xxxxx")   ;compare "Moon" with "xxxxx"
  MsgBox NO

;SAT =? MON
If (SAT = MON)      ;Compare "Saturday" = "Monday" [SAT = "Saturday", MON = "Monday"]
  MsgBox NO
If (SAT < MON)      ;"Saturday" < "Moon"
  MsgBox NO
If (SAT > MON)      ;"Saturday" > "Moon"  [S > M]
  MsgBox (SAT > MON)`n`n"Saturday" > "Monday"`n`n[S > M]

;SAT =? %MON%
If (SAT = %MON%)    ;Compare "Saturday" = "Moon". [SAT = "Saturday", compare with MON = "Monday", Monday = "Moon"]
  MsgBox NO
If (SAT < %MON%)    ;"Saturday" < "Moon"
  MsgBox NO
If (SAT > %MON%)    ;"Saturday" > "Moon"  [S > M]
  MsgBox (SAT > `%MON`%)`n`n"Saturday" > "Moon"   [S > M]`n`nSAT = "%SAT%",`nMON = "%MON%", %MON% = "Moon"

;%SAT% =? MON
If (%SAT% = MON)    ;Compare "Saturn" = "Monday". [SAT = "Saturday", Saturday = "Saturn", MON = "Monday"]
  MsgBox NO
If (%SAT% < MON)    ;"Saturn" < "Monday"
  MsgBox NO
If (%SAT% > MON)    ;"Saturn" > "Monday"  [S > M]
  MsgBox (`%SAT`% > MON)`n`nSAT = "Saturday", %SAT% = "Saturn", compare with MON = "Monday"`n`n"Saturn" > "Moon"`n`n[S > M]

;%SAT% =? %MON%
If (%SAT% = %MON%)  ;Compare "Saturn" = "Moon". [SAT = "Saturday", Saturday = "Saturn", compare with MON = "Monday", Monday = "Moon"]
  MsgBox NO
If (%SAT% < %MON%)  ;"Saturn" < "Moon"
  MsgBox NO
If (%SAT% > %MON%)  ;"Saturn" > "Moon"  [S > M]
  MsgBox (`%SAT`% > `%MON`%)`n`nSAT = "Saturday", %SAT% = "Saturn", compare with`nMON = "Monday", %MON% = "Moon"`n`n"Saturn" > "Moon"`n`n[S > M]


H2: Comparing Numeric Values vs. Comparing Strings 
If they can both be interpreted as numbers, then they are compared as numbers. Otherwise they are compared as strings. 

;COMPARING NUMERIC VALUES VS. COMPARING STRINGS     if statements with ()
x = 05           ; x = "05"
if (x > 3.14)    ; (5 > 3.14) ?  Compare numeric values, since both can be interpreted as numeric values.
  MsgBox if (x > 3.14)`nwith x = "05"`n`nCompare numeric values, since both "05" and "3.14" can be interpreted as numbers.`n(5 > 3.14) ?`nyes
else
  MsgBox xxxxxx

if (x > "3.14")  ; ("05" > "3.14") ?  Compare strings, since "3.14" is explicitly a string. (The " " around 3.14 say it's a string, not a number, so do a string compare.)
  MsgBox xxxxxx
else
  MsgBox if (x > "3.14")`nwith x = "05"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("05" > "3.14") ?`n("0" > "3") ?`n(48 > 51) ?`nno


; ASCII table:
;   /  47
;   0  48
;   1  49
;   2  50
;   3  51
;   4  52
;   5  53
;   6  54
;   7  55
;   8  56
;   9  57
;   :  58
;DEREFERENCE TESTS
y := "x"

;Compare %y% with 3.14
x = 03             ; x = "03"
if (%y% > 3.14)    ; (3 > 3.14) ?
  MsgBox xxxxxx
else
  MsgBox if (`%y`% > 3.14)`nwith y = "x"`nand x = "03"`n`nCompare numeric values, since both "03" and "3.14" can be interpreted as numbers.`n(3 > 3.14) ?`nno

x = 05             ; x = "05"
if (%y% > 3.14)    ; (5 > 3.14) ?
  MsgBox if (`%y`% > 3.14)`nwith y = "x"`nand x = "05"`n`nCompare numeric values, since both "05" and "3.14" can be interpreted as numbers.`n(5 > 3.14) ?`nyes
else
  MsgBox NO

;Compare %y% with "3.14"
x = 03               ; x = "03"
if (%y% > "3.14")    ; ("03" > "3.14") ?
  MsgBox xxxxxx
else
  MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = "03"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("03" > "3.14") ?`n("0" > "3") ?`n(48 > 51) ?`nno

x = 05               ; x = "05"
if (%y% > "3.14")    ; ("05" > "3.14") ?
  MsgBox xxxxxx
else
  MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = "05"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("05" > "3.14") ?`n("0" > "3") ?`n(48 > 51) ?`nno

x := "/"             ; x = "/"
if (%y% > "3.14")    ; ("/" > "3.14") ?
  MsgBox xxxxxx
else
  MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = "/"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("/" > "3.14") ?`n("/" > "3") ?`n(47 > 51) ?`nno

x := ":"             ; x = ":"
if (%y% > "3.14")    ; (":" > "3.14") ?
  MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = ":"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n(":" > "3.14") ?`n(":" > "3") ?`n(58 > 51) ?`nyes
else
  MsgBox xxxxxx




/****************************************************************************** 
I:  IF STATEMENTS without () 
Translate the 1st, take the 2nd literally 

SAT := "Saturday"          ;Another way to view this is:
Saturday := "Saturn"       ;  SAT --> Saturday --> Saturn
MON := "Monday"            ;  MON --> Monday --> Moon
Monday := "Moon"

MsgBox SAT := "Saturday"`nSaturday := "Saturn"`nMON := "Monday"`nMonday := "Moon"`n`n(another way to view this:)`nSAT --> Saturday --> Saturn`nMON --> Monday --> Moon

;SAT
; If "Saturday" = .... illegal
If SAT = Saturday    ;SAT = "Saturday", compare with "Saturday"
  MsgBox If SAT = Saturday`n`nSaturday = Saturday
If SAT = %Saturday%  ;SAT = "Saturday", compare with %Saturday% = "Saturn"
  MsgBox NO
If SAT = SAT         ;SAT = "Saturday", compare with "SAT"
  MsgBox NO
If SAT = %SAT%       ;SAT = "Saturday", compare with %SAT% = "Saturday"
  MsgBox If SAT = `%SAT`%`n`nSaturday = Saturday

;%SAT%
;NOTE: if SAT is undefined or blank, program will halt!
If %SAT% = Saturn   ;SAT = "Saturday", Saturday = "Saturn", compare with "Saturn"
  MsgBox If `%SAT`% = Saturn`n`nSAT = "%SAT%", `%Saturday`% = %Saturday%, compare with "Saturn"`n`n(Note: if SAT is undefined or blank, program will halt!)
If %SAT% = xxxxx   ;SAT = "Saturday", Saturday = "Saturn", compare with "xxxxx"
  MsgBox NO

;Saturday
If Saturday = Saturn   ;Saturday = "Saturn", compare with "Saturn"
  MsgBox Saturday = Saturn`n`nSaturday="%Saturday%",compare with "Saturn"
If Saturday = xxxxx   ;Saturday = "Saturn", compare with "xxxxx"
  MsgBox NO

;%Saturday%
;NOTE: if SATURDAY is undefined or blank, program will halt!
If %Saturday% =       ;Saturday = "Saturn", Saturn = <nothing>, compare with <nothing>
  MsgBox If `%Saturday`% = `n`nSaturday=%Saturday%, Saturn=<nothing>, compare with <nothing>`n`n(NOTE: if SATURDAY is undefined or blank, program will halt!)
If %Saturday% = %Saturn%  ;Saturday = "Saturn", Saturn = <nothing>, compare with %Saturn% = <nothing> (<nothing> = <nothing>)
  MsgBox if `%Saturday`% = `%Saturn`%`n`nSaturday=%Saturday%, Saturn=<nothing>`ncompare with`%Saturn`% = <nothing>`n`n<nothing>=<nothing>
If %Saturday% = xxxxx ;Saturday = "Saturn", Saturn = <nothing>, compare with "xxxxx"
  MsgBox NO
If %Saturday% = ""    ;Saturday = "Saturn", Saturn = <nothing>, compare with literal two double-quotes (a string containing two characters, both double-quotes)
  MsgBox NO


I2: Comparing Numeric Values vs. Comparing Strings 
If they can both be interpreted as numbers, then they are compared as numbers. Otherwise they are compared as strings. 

I2:
;COMPARING NUMERIC VALUES VS. COMPARING STRINGS     if statements without ()
; ASCII table:
;   !  33
;   "  34
;   #  35
;   0  48

x = 03            ; x = "03"
if x > 3.14       ; 3 > 3.14  (Compare numeric values, since both can be interpreted as numeric values)
  MsgBox xxxxxx
else
  MsgBox if x > 3.14`nwith x=%x%`n`nCompare numeric values, since both can be interpreted as numeric values`n3 > 3.14 ?`nno

x = 05            ; x = "05"
if x > 3.14       ; 5 > 3.14  (Compare numeric values, since both can be interpreted as numeric values)
  MsgBox if x > 3.14`nwith x=%x%`n`nCompare numeric values, since both can be interpreted as numeric values`n5 > 3.14 ?`nyes
else
  MsgBox xxxxxx

x = 03            ; x = "03"
if x > "3.14"     ; compare string '03' with string '"3.14"' (double quotes are part of the string). Compare ascii 0 in 03 with leading quotation mark in "3.14" (48 > 34 ?) Yes.
  MsgBox if x > "3.14"`nwith x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare 03 with "3.14"`ncompare leading '0' in 03 with leading quotation mark in "3.14"`nascii(0) = 48`nascii(") = 34`n48 > 34 (?)`nyes
else
  MsgBox xxxxxx

x = !             ; x = '!' (ascii 33)
if x > "3.14"     ;compare string '!' with string '"3.14"' (double quotes are part of the string). Compare ascii ! with leading quotation mark in "3.14" (48 > 34 ?) Yes.
; (! > ")?  --> (33 > 34) ? no
  MsgBox xxxxxx
else
 MsgBox if x > "3.14"`nwith x=%x%`nno`n`ncompare ascii ! with leading quotation mark in "3.14"`nascii(!) = 33`nascii(") = 34`n(33 > 34)?`nno

x = #             ; x = '#' (ascii 35)
if x > "3.14"     ; (! > ")?  --> (35 > 34) ? yes
  MsgBox if x > "3.14"`nwith x=%x%`nyes`n`ncompare ascii # with leading quotation mark in "3.14"`nascii(#) = 35`nascii(") = 34`n(35 > 34)?`nyes
else
  MsgBox xxxxxx


; ASCII table:
;   !  33
;   "  34
;   #  35
;   0  48
;DEREFERENCE TESTS
y := "x"

;compare %y% with 3.14
x = 03            ; x = "03"
if %y% > 3.14     ; 3 > 3.14 (?)
  MsgBox xxxxxx
else
  MsgBox if `%y`% > 3.14`nwith y := "x"`nand x = "03"`n`nCompare numeric values, since both "03" and "3.14" can be interpreted as numbers.`n3 > 3.14 (?)`nno

x = 05            ; x = "05"
if %y% > 3.14     ; 5 > 3.14 (?)
  MsgBox if `%y`% > 3.14`nwith y := "x"`nand x = "05"`n`nCompare numeric values, since both "05" and "3.14" can be interpreted as numbers.`n5 > 3.14 (?)`nyes
else
  MsgBox xxxxxx


;compare %y% with "3.14"
x = 03            ; x = "03"
if %y% > "3.14"   ; Double quotes are part of the string "3.14" so string compare '03' with string '"3.14"'. Compare ascii 0 in 03 with leading quotation mark in "3.14" (48 > 34 ?) Yes.
  MsgBox if `%y`% > "3.14"`nwith y := "x"`nand x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare 03 with "3.14"`ncompare leading '0' in 03 with leading quotation mark in "3.14"`nascii(0) = 48`nascii(") = 34`n48 > 34 (?)`nyes
else
  MsgBox xxxxxx

x = !             ; x = '!' (ascii 33)
if x > "3.14"     ;Double quotes are part of the string "3.14" so string compare '!' with string '"3.14"'. Compare '!' with leading quotation mark in "3.14" (48 > 34 ?) Yes.
  MsgBox xxxxxx
else
  MsgBox if `%y`% > "3.14"`nwith y := "x"`nand x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare ! with "3.14"`ncompare '!' with leading quotation mark in "3.14"`nascii(!) = 33`nascii(") = 34`n33 > 34 (?)`nno

x = #             ; x = '#' (ascii 35)
if x > "3.14"     ; (! > ")?  --> (35 > 34) ? yes
  MsgBox if `%y`% > "3.14"`nwith y := "x"`nand x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare # with "3.14"`ncompare '#' with leading quotation mark in "3.14"`nascii(#) = 35`nascii(") = 34`n35 > 34 (?)`nyes
else
  MsgBox xxxxxx




/****************************************************************************** 
J:  CHECK FOR A BLANK VARIABLE 
(or undefined variable) 

v := ""

If v =
  MsgBox v = ""

If (v = "")
  MsgBox v = ""




/****************************************************************************** 
K:  STRING MANIPULATION 

K1: Trim whitespace at the START of a string

;Trim whitespace at the START of a string:
v := "     0001     "
MsgBox v="%v%"
v := RegExReplace( v, "\A\s+" )
MsgBox v="%v%"                  ;v = "0001     "


K2: Trim whitespace at the END of a string

;Trim whitespace at the END of a string:
v := "     0001     "
MsgBox v="%v%"
v := RegExReplace( v, "\s+\z" )
MsgBox v="%v%"                  ;v = "     0001"



K3: Trim whitespace at the START AND END of a string 
K3a:

;Trim whitespace at the START AND END of a string:
v := "     0001     "
MsgBox v="%v%"
v := RegExReplace( v, "(^\s+)|(\s+$)")
MsgBox v="%v%"                  ;v = "0001"

K3b:

;Trim whitespace at the START AND END of the string:
v := "     0001     "
MsgBox v="%v%"
v = %v%                         ;v = "0001" (AutoTrim ON by default)
MsgBox v="%v%"



K4: Concatenate Two Strings Together

;CONCATENATE TWO STRINGS TOGETHER
SAT := "Saturday"
MON := "Monday"
Saturday := "Saturn"
Monday := "Moon"


; using =
v = %SAT%%MON%      ; v = "SaturdayMonday"
MsgBox v = "%v%"


; using :=
v := "Saturday" . "Monday"  ; v = "SaturdayMonday"
MsgBox v = "%v%"

v := SAT . MON      ; v = "SaturdayMonday" (there must be a SPACE before and after dot)
MsgBox v = "%v%"

v := %SAT% . MON    ; v = "SaturnMonday"
MsgBox v = "%v%"

v := SAT . %MON%    ; v = "SaturdayMoon"
MsgBox v = "%v%"

v := %SAT% . %MON%  ; v = "SaturnMoon"
MsgBox v = "%v%"



K5: Two ways of using MsgBox 
This is a good place to mention the two ways of using MsgBox:

Msgbox Var = %Var%
; OR
Msgbox % "Var = " . Var
;  string-^^^^^^  | ^^^-variable name
;           Concatenate


K6: 
SEE ALSO: 
    Library for Text File Manipulation 
    http://www.autohotkey.net/~heresy/Functions/TXT.ahk 


/****************************************************************************** 
L:  NUMBERS 
NOTE: All variables are stored as character strings. 
Strings are automatically converted to numbers when necessary, 
then converted back to strings when result is stored in a variable. 

L1: Adding numbers together 

;Adding numbers together
v := "123"
v += 1
MsgBox v = "%v%"     ; v <- "124"

v := "123"
v := v + 1
MsgBox v = "%v%"     ; v <- "124"

;PROBABLY NOT WHAT YOU WANTED:
v = 123            ; v <- "123" (the literal string)
v = v + 1          ; v <- "v + 1" (the literal string)
MsgBox v = "%v%"


L2: Adding two strings together 

;Adding two strings together
;when both can be interpreted as integers, gives the resulting integer (as a string)
v1 := 123
v2 := 456
v := v1 + v2       ; v <- "579"
MsgBox v = "%v%"

;when one or both can be interpreted as float, gives the resulting float (as a string)
v1 := 1.23
v2 := 45.6
v := v1 + v2       ; v <- "46.830000"
MsgBox v = "%v%"

;When one or both can NOT be interpreted as a number, result is an empty string
v1 := "123"
v2 := "Susan"
v := v1 + v2       ; v <- "" (empty string)
MsgBox v = "%v%"


L3: Remove leading/trailing blanks/zeros from a number 

;Remove leading zeros from a number
v := 0001             ;v = "0001"
v += 0                ;v converted to integer, add zero, convert back to string
MsgBox v = "%v%"      ;v = "1" (the literal string "1"

;Remove leading blanks and trailing blanks from a number
v := "     1     "
MsgBox v = "%v%"      ;v = "     1     "
v += 0                ;v converted to integer, add zero, convert back to string
MsgBox v = "%v%"      ;v = "1" (the literal string "1"

;Remove leading and trailing blanks and leading zeros from a number
v := "     0001     "
MsgBox v = "%v%"      ;v = "     0001     "
v += 0                ;v converted to integer, add zero, convert back to string
MsgBox v = "%v%"      ;v = "1" (the literal string "1"

;(yea it's all the same. Just do v += 0)


L4: Pad a number with leading zeros or spaces 
/************************************************ 
VARIOUS WAYS TO PAD A NUMBER WITH LEADING ZEROS OR SPACES 
(To pad with spaces, substitute spaces for the zeros.) 

L4.1: Method #1: SubStr

;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #1: SUBSTR
; Documentation on SubStr: "If StartingPos is less than 1, it is
; considered to be an offset from the end of the string. For example, 0
; extracts the last character and -1 extracts the two last characters."
v := 123
            ;....v....1                   ....v....1
v := SubStr("0000000000" . v, -9)  ; v = "0000000123"
MsgBox v = "%v%"

v := SubStr("abcdefghij" . v, -9)  ; v = "defghij123"  (easier to see what's happening)
MsgBox v = "%v%"


L4.2: Method #2: StringRight

;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #2: StringRight
v := 123
     ;....v....1              ....v....1...
v := "0000000000" . v  ; v = "0000000000123"  ( or could use v = "0000000000"%v% )
StringRight, v, v, 10  ; v =    "0000000123"
MsgBox v = "%v%"


L4.3: Method #3: sprintf()

;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #3: sprintf()
StrIn := "1234"
size := VarSetCapacity(StrOut, 8)  ;want StrOut to hold 8 digits

;pad with zeros
DllCall("msvcrt\sprintf", Str, StrOut, Str, "%08d", "Int", StrIn )  ;pad with zeros
MsgBox, 0, Zeros, size=%size%`nStrIn = %StrIn%`nStrOut = %StrOut%   ;StrOut = "00000123"

;pad with blanks
DllCall("msvcrt\sprintf", Str, StrOut, Str,  "%8d", "Int", StrIn )  ;pad with blanks
MsgBox, 0, Spaces, size=%size%`nStrIn = %StrIn%`nStrOut = %StrOut%  ;StrOut = "     123"


L4.4: Method #4: Prepend leading zeros

;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #4: Prepend leading zeros
v = 123
Loop, % 9-StrLen(v)            ; (9 for 9 digits total)
    v = 0%v%                   ; OR: v := 0 . v
MsgBox, 0, Zeros, v = "%v%"    ; v = "000000123"

;Prepend leading spaces
v = 123
Loop, % 9-StrLen(v)            ; (9 for 9 digits & spaces total)
    v := A_Space . v         ; OR: v := " " . v
MsgBox, 0, Spaces, v = "%v%"   ; v = "      123"


L4.5: Method #5: SetFormat

;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #5: Using SetFormat
;(Note: Be wary of converting an integer to a float and back to an integer.
; An integer has 32 bits of data, whereas a float has only 27 bits of data.)
v = 1234
SetFormat, Float, 08.0 ; (08 for zero padded 8 digits total, .0 for zero decimal places)
v += 0.0               ; v converted to float, add zero, convert back to string
MsgBox v = %v%         ; v = '00001234'

v = 1234
SetFormat, Float, 8.0  ; (8 for space padded 8 digits & spaces total, .0 for zero decimal places)
v += 0.0               ; v converted to float, add zero, convert back to string
MsgBox v = %v%         ; v = '    1234'




/****************************************************************************** 
M:  working with FILE NAMES 

;Set/Show Working Directory
SetWorkingDir,%A_ScriptDir%
MsgBox A_WorkingDir=%A_WorkingDir%

;Creating a File  (note: directory must exist)
FileAppend, test 10, MyFile10.log           ;<WorkingDir>\MyFile10.log
FileAppend, test 11, \MyFile11.log          ;C:\MyFile11.log
FileAppend, test 12, SubDir\MyFile12.log    ;<WorkingDir>\SubDir\MyFile12.log
FileAppend, test 13, SubDir\\\\\\\\\\\\\MyFile13.log   ;<WorkingDir>\SubDir\MyFile13.log Doesn't seem to matter how many extra \
V := "C:\TEMP"
FileAppend, test 14, %V%MyFile14.log        ;C:\TEMPMyFile14.log
FileAppend, test 15, %V%\MyFile15.log       ;C:\TEMP\MyFile15.log
FileAppend, test 16, %V%\\\\\\\\\\\MyFile16.log   ;C:\TEMP\MyFile16.log  Doesn't seem to matter how many extra \
FileAppend, test 17, ..\MyFile17.log        ;Up one directory from WorkingDir. <WorkingDir-^>\MyFile17.log
MsgBox ErrorLevel=%ErrorLevel%              ;FileAppend test for error. 0=SUCCESS, 1=FAIL




/****************************************************************************** 
N:  REGULAR EXPRESSIONS 
(Note: AutoHotkey uses PCRE Perl-compatible format) 

N1:  Regular Expression RESOURCES 

CHEAT SHEETS 
Regular Expressions (RegEx) - Quick Reference: http://www.autohotkey.com/docs/misc/RegEx-QuickRef.htm 
Regular Expression Cheat Sheet: http://regexlib.com/CheatSheet.aspx 
One Page Reference Cheat Sheet: http://www.regular-expressions.info/reference.html 
Replacement Text Reference: http://www.regular-expressions.info/refreplace.html 

HEAVY DOCUMENTATION 
Syntax of regular expressions in Perl: http://search.cpan.org/dist/perl/pod/perlre.pod 
Syntax of regular expressions in Perl: http://perldoc.perl.org/perlre.html 
Concatenation of the PCRE man pages: http://www.pcre.org/pcre.txt 
Perl Compatible Regular Expressions: http://en.wikipedia.org/wiki/PCRE 

PROGRAMS 
RegExBuddy: http://www.regexbuddy.com ($40) Screenshot: http://www.regexbuddy.com/screen.html 

LIBRARIES 
Regular Expression Library: http://regexlib.com/ 
Categories:

  • Email
  • Uri
  • Numbers
  • Strings
  • Dates and Times
  • Misc
  • Address/Phone
  • Markup/Code

http://www.regular-expressions.info/examples.html

  • Grabbing HTML Tags
  • Trimming Whitespace
  • Matching an IP address
  • Matching a Floating Point Number
  • Matching an Email Address
  • Matching Valid Dates
  • Finding or Verifying Credit Card Numbers
  • Matching Complete Lines
  • Removing Duplicate Lines or Items
  • Regex Examples for Processing Source Code
  • Two Words Near Each Other

A Collection/Library Of Regular Expressions: http://www.autohotkey.com/forum/viewtopic.php?t=13544

  • Ensure that a path doesn't end with a backslash
  • Ensure that a path ends with a backslash
  • Replace characters illegal in a file name by something else (can be empty)
  • Keep only lines starting with a given string
  • Parse a date
  • trim chars on left and/or right of strings
  • How to make parsing loops work from back to front?
  • How to replace variable references in a template text file by the value of the referenced variables?
  • How to replace i with I only if it has spaces before and after
  • remove duplicate lines


N2:   Regular Expression EXAMPLES 

Examples from: http://www.regular-expressions.info/numericranges.html 
Matching Floating Point Numbers with a Regular Expression 
Here are a few more common ranges that you may want to match: 

000..255:       ——  ^([01][0-9][0-9]|2[0-4][0-9]|25[0-5])$
0 or 000..255:  ——  ^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$
0 or 000..127:  ——  ^(0?[0-9]?[0-9]|1[0-1][0-9]|12[0-7])$
0..999:         ——  ^([0-9]|[1-9][0-9]|[1-9][0-9][0-9])$
000..999:       ——  ^[0-9]{3}$
0 or 000..999:  ——  ^[0-9]{1,3}$
1..999:         ——  ^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$
001..999:       ——  ^(00[1-9]|0[1-9][0-9]|[1-9][0-9][0-9])$
1 or 001..999:  ——  ^(0{0,2}[1-9]|0?[1-9][0-9]|[1-9][0-9][0-9])$
0 or 00..59:    ——  ^[0-5]?[0-9]$
0 or 000..366:  ——  ^(0?[0-9]?[0-9]|[1-2][0-9][0-9]|3[0-6][0-9]|36[0-6])$

Examples from: http://www.codeproject.com/KB/dotnet/regextutorial.aspx

    1. elvis                 Find elvis
    2. \belvis\b             Find elvis as a whole word
    3. \belvis\b.*\balive\b  Find text with "elvis" followed by "alive"
    4. \b\d\d\d-\d\d\d\d     Find seven-digit phone number
    5. \b\d{3}-\d{4}         Find seven-digit phone number a better way
    6. \ba\w*\b              Find words that start with the letter a
    7. \d+                   Find repeated strings of digits
    8. \b\w{6}\b             Find six letter words
    9. .^\d{3}-\d{4}$        Validate a seven-digit phone number
   10. \b\w{5,6}\b           Find all five and six letter words
   11. \b\d{3}\s\d{3}-\d{4}  Find ten digit phone numbers
   12. \d{3}-\d{2}-\d{4}     Social security number
   13. ^\w*                  The first word in the line or in the text
   14. \(?\d{3}[) ]\s?\d{3}[- ]\d{4}  A ten digit phone number
   15. \S+                   All strings that do not contain whitespace characters
   16. \b\d{5}-\d{4}\b|\b\d{5}\b           Five and nine digit Zip Codes
   17. (\(\d{3}\)|\d{3})\s?\d{3}[- ]\d{4}  Ten digit phone numbers, a better way.
                                           This expression will find phone numbers in several formats, like
                                           "(800) 325-3535" or "650 555 1212".
                                           The "\(?" searches for zero or one left parentheses,
                                           "[) ]" searches for a right parenthesis or a space. The
                                           "\s?" searches for zero or one whitespace characters.
                                           Unfortunately, it will also find cases like
                                           "650) 555-1212" in which the parenthesis is not balanced.
                                           Below, you'll see how to use alternatives to eliminate this problem.
   18. (\d{1,3}\.){3}\d{1,3}               A simple IP address finder
   19. ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)  IP finder
   20. \b(\w+)\b\s*\1\b      Find repeated words
   21. \b(?<Word>\w+)\b\s*\k<Word>\b   Capture repeated word in a named group
   22. \b\w+(?=ing\b)        The beginning of words ending with "ing"
   23. (?<=\bre)\w+\b        The end of words starting with "re"
   24. (?<=\d)\d{3}\b        Three digits at the end of a word, preceded by a digit
   25. (?<=\s)\w+(?=\s)      Alphanumeric strings bounded by whitespace
   26. \b\w*q[^u]\w*\b       Words with "q" followed by NOT "u"
   27. \b\w*q(?!u)\w*\b      Search for words with "q" not followed by "u"
   28. \d{3}(?!\d)           Three digits not followed by another digit
   29. (?<![a-z ])\w{7}      Strings of 7 alphanumerics not preceded by a letter or space
   30. (?<=<(\w+)>).*(?=<\/\1>)  Text between HTML tags
   31. Text between HTML tags (see referenced source page above)
   32. a.*b                  The longest string starting with a and ending with b
   33. a.*?b                 The shortest string starting with a and ending with b

Phone numbers:

    a. \(\d\d\d\)\s\d\d\d-\d\d\d\d
    b. \(\d{3}\)\s\d{3}-\d{4}
    4. \b\d\d\d-\d\d\d\d     Find seven-digit phone number
    5. \b\d{3}-\d{4}         Find seven-digit phone number a better way
    9. .^\d{3}-\d{4}$        Validate a seven-digit phone number
   11. \b\d{3}\s\d{3}-\d{4}  Find ten digit phone numbers
   14. \(?\d{3}[) ]\s?\d{3}[- ]\d{4}  A ten digit phone number
   17. (\(\d{3}\)|\d{3})\s?\d{3}[- ]\d{4}  Ten digit phone numbers, a better way.

Dates:

    a. (\d\d)-(\d\d)-(\d\d\d\d)    MM-DD-YYYY   (MM -& $1, DD -& $2, YYY -& $3)
    b. (\d\d\d\d)-(\d\d)-(\d\d)    YYYY-MM-DD   (YYYY -& $1, MM -& $2, DD -& $3)
    c. ^\d{1,2}\/\d{1,2}\/\d{4}$   XX/XX/YYYY where XX can be 1 or 2 digits long and YYYY is always 4 digits long.



/****************************************************************************** 
N3:  RegExReplace 
N3.1: Basic examples 

; Examples
f1 := RegExReplace("55555", "5", "five") ;f1 = "fivefivefivefivefive"
MsgBox f1=%f1%

f2 := RegExReplace("55555", "55", "x") ;f2 = "xx5"
MsgBox f2=%f2%


N3.2: EXTRACT Month, Day, Year, from 1/22/2009

;Regular Expression to EXTRACT Month, Day, Year, from 1/22/2009
;month & day can be 1 or 2 digits
 c := "xxxxxxxx 1/22/2009 yyyyyyyyyyyy"
 month := RegExReplace(c,".*?(\d{1,2})\/(\d{1,2})\/(\d{4})(.*)","$1")
 day   := RegExReplace(c,".*?(\d{1,2})\/(\d{1,2})\/(\d{4})(.*)","$2")
 year  := RegExReplace(c,".*?(\d{1,2})\/(\d{1,2})\/(\d{4})(.*)","$3")
 MsgBox month=%month%`nday=%day%`nyear=%year%


N3.3: An example of how we can step by step build up our Regular Expression

;An example of how we can step by step build up our Regular Expression
;Given string c, extract the data...
c := "  02-17-2009     238  Payment by Check.     314.15   9,265.35  "

;Trim leading and trailing spaces
c = %c%

; 1.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Start with "(.*)" which grabs the whole string
f3 := RegExReplace(c, "(.*)", "$1")
MsgBox f3=%f3%
; f3 = "02-17-2009     238  Payment by Check.     314.15   9,265.35"

; 2.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "(\d\d)" to parse off the first two digits (the month)
f4 := RegExReplace(c, "(\d\d)(.*)", "{$1} {$2}")
MsgBox f4=%f4%
; f4 = "{02} {-17-2009     238  Payment by Check.     314.15   9,265.35}"

; 3.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "-" to parse off the dash
f5 := RegExReplace(c, "(\d\d)-(.*)", "{$1} {$2}")
MsgBox f5=%f5%
; f5 = "{02} {17-2009     238  Payment by Check.     314.15   9,265.35}"

; 4.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "(\d\d)" to parse off the second two digits (the day) and save it as $2
f6 := RegExReplace(c, "(\d\d)-(\d\d)(.*)", "{$1} {$2} {$3}")
MsgBox f6=%f6%
; f6 = "{02} {17} {-2009     238  Payment by Check.     314.15   9,265.35}"

; 5.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "-" to parse off the dash
f6 := RegExReplace(c, "(\d\d)-(\d\d)(.*)", "{$1} {$2} {$3}")
MsgBox f6=%f6%
; f6 = "{02} {17} {-2009     238  Payment by Check.     314.15   9,265.35}"

; 6.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "(\d\d\d\d)" to parse off the year (4 digits) and save it as $3
f7 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d)(.*)", "{$1} {$2} {$3} {$4}")
MsgBox f7=%f7%
; f7 = "{02} {17} {2009} {     238  Payment by Check.     314.15   9,265.35}"

; 7.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add " +" to parse off one or more spaces
f8 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(.*)", "{$1} {$2} {$3} {$4}")
MsgBox f8=%f8%
; f8 = "{02} {17} {2009} {238  Payment by Check.     314.15   9,265.35}"

; 8.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "(\d+)" to parse off the check number (one or more digits) and save it as $4
f9 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+)(.*)", "{$1} {$2} {$3} {$4} {$5}")
MsgBox f9=%f9%
; f9 = "{02} {17} {2009} {238} {  Payment by Check.     314.15   9,265.35}"

; 9.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add " +" to parse off one or more spaces
f10 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*)", "{$1} {$2} {$3} {$4} {$5}")
MsgBox f10=%f10%
;f10 = "{02} {17} {2009} {238} {Payment by Check.     314.15   9,265.35}"

; 10.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "(.*?)" to parse off the text (minimal match), followed by " {5}" to parse off 5 spaces
; (there apparently is always 5 spaces. This tells us when we're done parsing off the text.)
f11 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}(.*)", "{$1} {$2} {$3} {$4} {$5} {$6}")
MsgBox f11=%f11%
; f11 = "{02} {17} {2009} {238} {Payment by Check.} {314.15   9,265.35}"

; 11.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "([\d,.]+)" to parse off the dollars and cents (one or more digits with possible commas and decimal point, e.g. 27,182.81)
f12 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}([\d,.]+)(.*)", "{$1} {$2} {$3} {$4} {$5} {$6} {$7}")
MsgBox f12=%f12%
; f12 = "{02} {17} {2009} {238} {Payment by Check.} {314.15} {   9,265.35}"

; 12.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add " {3}" to parse off 3 spaces (apparently always 3)
f13 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}([\d,.]+) {3}(.*)", "{$1} {$2} {$3} {$4} {$5} {$6} {$7}")
MsgBox f13=%f13%  ;f13 = "{02} {17} {2009} {238} {Payment by Check.} {314.15} {9,265.35}"

; 13.
; c := "02-17-2009     238  Payment by Check.     314.15   9,265.35"
; Add "([\d,.]+" to parse off the dollars and cents (one or more digits with possible commas and decimal point, e.g. 27,182.81)
f14 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}([\d,.]+) {3}([\d,.]+)(.*)", "{$1} {$2} {$3} {$4} {$5} {$6} {$7} {$8}")
MsgBox f14=%f14%
; f14 = "{02} {17} {2009} {238} {Payment by Check.} {314.15} {9,265.35} {}"
;        (the last empty {} indicates there's nothing left over)


N3.4: Find the $ dollar sign. Extract price and add a $.

;find the $ dollar sign
c := "xxx $17.25 yyy"
dollar := RegExReplace(c,"(.*?)(\$)(.*)","$2")
MsgBox dollar=%dollar%

;extract price and add a dollar sign
c := "xxx 17.25 yyy"
price := RegExReplace(c,"(.*?)([\d,.]+)(.*)","$$$2")
msgbox price=%price%   ; price = "$17.25"

; For RegExReplace replace string only:
;    To specify a literal $, use $$
;    $ is the only character that needs such special treatment in a RegEx replace string.
;    Backslashes are never needed to escape anything else in a RegEx replace string.
; (RegEx search string still needs to have many characters escaped.)




/****************************************************************************** 
O:  Misc AutoHotkey Notes & Debugging Tips 

O1: Notes / Caveats 
 

  • NOTE: 
ALL VARIABLES ARE STORED AS CHARACTER STRINGS !!! 
Strings containing numbers are converted to numbers when needed, and the result is converted back to a string.
 
  • NOTE: 
Closing */ must be first thing on line. Otherwise you'll be asking yourself, "Why does my script stop running at this point, as if the whole rest of the script was commented out?" 

MsgBox Hello
/* here is a comment
and another comment */
MsgBox Goodbye    ;You'll never see this message
MsgBox Hello
/* here is a comment
and another comment
*/
MsgBox Goodbye    ;Now you're OK
 
  • NOTE: 
      Space here ruins function call
      ↓
MyFunc (Param1)
MyFunc(Param1)
  • When sending text, if there are problems, sometimes it helps to throw in a short delay (Sleep 100), or to slow down the sending of characters by using SetKeyDelay (e.g.SetKeyDelay 90) 
     
  • MsgBox: You may need to manually restore focus to your current window after a call to MsgBox. I was debugging an AutoHotkey script by throwing in a bunch of MsgBox messages, and I discovered a problem that focus wasn't being returned to my window after the MsgBox timed out. So, I added a WinActivate after MsgBox to restore focus to my window, and all was well again. 
    (May have been caused by cross contamination from another unrelated program. I'm so tired of debugging Windows programs only to discover there's nothing wrong with the program I'm debugging, it's the Windows OS itself that's been corrupted by a completely unrelated program. I thought those days were long behind us.) 
    Update: I had another case where this fix was exactly the wrong thing to do. The "current window" wasn't the one I wanted. Removing the WinExist/WinActivate combo fixed the problem. (Alas, no solution is universal.)


O2: Sending Debug Data To A Log File

;Example 1. Log a message
SetWorkingDir, %A_ScriptDir%  ;Set default directory to where this script file is located
LogFile := "MyLog.txt"
FileAppend, This is a message`n, %LogFile%  ;(note the trailing (`n) to start a new line. This could instead be a leading (`n) if you want.
;Example 2. Include a time stamp
SetWorkingDir, %A_ScriptDir%  ;Set default directory to where this script file is located
LogFile := "MyLog.txt"
FormatTime, TimeString, , yyyy-MM-dd hh:mm:ss tt
FileAppend, `n%TimeString% : This is a message`n, %LogFile%
;Example 3. Put it all in a function named LogMsg
SetWorkingDir, %A_ScriptDir%  ;Set default directory to where this script file is located
LogFile := "MyLog.txt"
LogMsg("This is a message")   ;Note LogMsg adds a leading (`n) so each message starts on a new line
LogMsg("Variable X = " . X )  ;Concatenate using the dot .
ExitApp

;---------------------------
;And here is our function:
LogMsg( msg )
{
  global LogFile
  FormatTime, TimeString, , yyyy-MM-dd hh:mm:ss tt
  FileAppend, `n%TimeString% : %msg%, %LogFile%
}

Update: I've had cases where using FileAppend too frequently causes it to occasionally fail. An expected line in the log file just isn't there. You can check ErrorLevel, but there's no way to get further info on why it failed. Tech note: This may be because FileAppend closes the file every time. That can be a lot of opening/closing a file. 


O3: Capturing a screen image during run using IrfanView

/******************************************************************************
Capturing a screen image during run using IrfanView (www.irfanview.com)
*/
RunWait "C:\Program Files\IrfanView\i_view32.exe" "/capture=1  /convert=C:\TEMP\MyImage.bmp"



/****************************************************************************** 
P:  Misc AutoHotkey Scripts: 

P1: Misc AutoHotkey Scripts


P2: Index of notable scripts found in the AutoHotkey Forum : http://www.autohotkey.com/wiki/index.php?title=Script_Listing

  • 1 AutoHotkey Related
    • 1.1 Ports/custom builds
      • 1.1.1 Windows NT+
      • 1.1.2 Windows CE
      • 1.1.3 Windows/Linux/Mac (.NET/Mono)
    • 1.2 Compile AutoHotkey yourself
      • 1.2.1 MS Visual C++
      • 1.2.2 GCC
    • 1.3 Use AutoHotkey with other programming/scripting languages
      • 1.3.1 Any
    • 1.4 Use other programming/scripting languages inline in AutoHotkey
      • 1.4.1 Perl
      • 1.4.2 C#/VB
      • 1.4.3 VBScript/JScript, VB/VBA/MS Office
      • 1.4.4 Assembly/Machine code
      • 1.4.5 C/C++
      • 1.4.6 Lisp/ECL
    • 1.5 Scripts
    • 1.6 Tools
    • 1.7 Editors
  • 2 GUI
    • 2.1 General
    • 2.2 All
    • 2.3 3P Controls
    • 2.4 MsgBox
    • 2.5 ListBox
    • 2.6 Splash
    • 2.7 Menu
    • 2.8 Templates
    • 2.9 Hotkey
    • 2.10 Button
    • 2.11 Hyperlink
    • 2.12 ListView
    • 2.13 Edit
    • 2.14 Other
    • 2.15 Tooltip
    • 2.16 TreeView
  • 3 Functions
  • 4 Audio and Video
  • 5 File Management and Searching
  • 6 File Reading & Parsing
  • 7 Internet related
  • 8 XML, HTML and BBCode
  • 9 Window Manipulation
  • 10 Keyboard Enhancements
  • 11 Mouse Related
  • 12 Clipboard Manipulation
  • 13 Games
    • 13.1 Game Related
  • 14 Fun
  • 15 Images
  • 16 Time and Scheduling
  • 17 Encryption / Encoding / Binary
  • 18 System Related
  • 19 Security
  • 20 Miscellaneous



P3: AHK Functions - ƒ() 
http://www.autohotkey.com/forum/viewtopic.php?t=8728



P4: Library for Text File Manipulation : http://www.autohotkey.net/~heresy/Functions/TXT.ahk 

  • Basic Functions
    • TXT_TotalLines
    • TXT_ReadLines
    • TXT_Tail
  • Alignment Functions
    • TXT_AlignLeft
    • TXT_AlignCenter
    • TXT_AlignRight
    • TXT_ReverseLines
  • Removement Functions
    • TXT_RemoveLines
    • TXT_RemoveBlankLines
    • TXT_RemoveDuplicateLines
  • Replacement Functions
    • TXT_Replace
    • TXT_RegExReplace
    • TXT_ReplaceLine
  • Insertion Functions
    • TXT_LineNumber
    • TXT_InsertLine
    • TXT_InsertPrefix
    • TXT_InsertSuffix
  • Column Functions
    • TXT_ColGet
    • TXT_ColPut
    • TXT_ColCut
  • Trimming Functions
    • TXT_TrimLeft
    • TXT_TrimRight
  • CSV Functions
    • TXT_GetCSV
    • TXT_SetCSV
  • File Join/Split Functions
    • TXT_ConCat



P5: Tray Icons : http://www.autohotkey.com/wiki/index.php?title=Script_Listing 



P6: Force Exit another AutoHotkey script 
To force Exit another AutoHotkey script (and have it's icon removed from the system tray):

WM_COMMAND = 0x111
ID_FILE_EXIT = 65405
PostMessage, WM_COMMAND, ID_FILE_EXIT, 0, , <window-title>

Example: To end the DimScreen program (an AutoHotkey script at http://www.donationcoder.com/Software/Skrommel/#DimScreen)

WM_COMMAND = 0x111
ID_FILE_EXIT = 65405
PostMessage, WM_COMMAND, ID_FILE_EXIT, 0, , DimScreen Screen

Notes: The above only works for AutoHotkey scrips (*.ahk, or compiled to *.exe) 
 To determine the Window Title, run Process Explorer 
 AutoHotkey has the following WM_COMMAND numbers defined in resource.h

ID_FILE_PAUSE 65403
ID_FILE_SUSPEND 65404
ID_FILE_EXIT 65405
(0x111 is WM_COMMAND)


Tech note: Other WM_COMMAND numbers defined in AutoHotkey source file resource.h (I haven't tried any of these to see what they do)

ID_FILE_RELOADSCRIPT 65400
ID_FILE_EDITSCRIPT 65401
ID_FILE_WINDOWSPY 65402
ID_FILE_PAUSE 65403
ID_FILE_SUSPEND 65404
ID_FILE_EXIT 65405
ID_VIEW_LINES 65406
ID_VIEW_VARIABLES 65407
ID_VIEW_HOTKEYS 65408
ID_VIEW_KEYHISTORY 65409
ID_VIEW_REFRESH 65410
ID_HELP_USERMANUAL 65411
ID_HELP_WEBSITE 65412


Another way to identify the AutoHotkey script you want to Exit(/Suspend/Pause):

WM_COMMAND = 0x111
ID_FILE_EXIT = 65405
DetectHiddenWindows, On

WinGet, AList, List, ahk_class AutoHotkey       ; Make a list of all running AutoHotkey programs
Loop %AList% {                                  ; Loop through the list
  ID := AList%A_Index%
  WinGetTitle, ATitle, ahk_id %ID%              ; (You'll notice this isn't the same 'window title')
  MsgBox, 3, %A_ScriptName%, %ATitle%`n`nEnd?
  IfMsgBox Cancel
    Break
  IfMsgBox Yes
    PostMessage,WM_COMMAND,ID_FILE_EXIT,0,,% "ahk_id" AList%A_Index%   ; End the process (65404 to suspend, 65403 to pause)
}
ExitApp



/****************************************************************************** 
Q:  NAVIGATING WEB SITES 
See example file WebsiteNav.ahk 

Q1:  DETERMINING WHEN A WEBPAGE HAS FINISHED LOADING 
See FAQ: http://www.autohotkey.com/docs/FAQ.htm#load



Q2:  POSITION US ON A CERTAIN CONTROL 
Examples are from simple to more complex. All examples here are demonstrated in file WebsiteNav.ahk 

  • Method 1: Blindly hit the {Tab} key a certain number of times to position us where we want to be. 
    (Not very reliable. e.g. User may have Google toolbar installed, which we'd have to tab through. 
    Or perhaps Yahoo toolbar. Or no toolbar. Who knows...) 
    Example: 
    Send {Tab 34}  ;say, 34 tabs gets us where we want to be.
    
  • Method 2. Hit the {Tab} key until certain text appears in the status bar 
    For this example, assume we are at http://www.autohotkey.com/ and we wish to position ourselves on the Wiki link:
    ; For this example, Tab until we find the autoHotkey "Wiki" link
    ; When we tab to the AutoHotkey "Wiki" link, the status bar says "http://www.autohotkey.com/wiki/"
    target := "http://www.autohotkey.com/wiki/"
    loop, 40
    {
      sleep 10  ;this pause may help
      StatusBarGetText, StatBar, , AutoHotkey - Free Mouse and Keyboard Macro Program
      if (StatBar = target)
      {
        goto FOUNDIT
      }
      Send, {Tab}
    }
    ;If we drop out here, it means we failed to find our target after 40 tabs
    MsgBox Failed to find %target%
    ExitApp
    
    FOUNDIT:
    MsgBox Found target %target%
    
  • Method 2.5 Hit Shift+Tab to tab backwards until certain text appears in the status bar 
    (May be useful if tabbing forwards doesn't work) 
     
  • Method 3. Search for word which is link you want to click on 
     
  • Method 4. Jump directly to the control 
    The JavaScript method—we place some JavaScript code in the address bar and execute it to jump directly to the control. This is a faster and more reliable technique, but it's a bit more complicated to set up. We use AutoHotkey ControlSetText to place the JavaScript code in the address bar, specifying the HTML control ID, or the control NAME, of the control we want to jump to, then we use AutoHotkey ControlSend to execute that JavaScript. 

    For this example, assume we are at http://www.autohotkey.com/wiki/ and we wish to position ourselves in the Search field. 
    Determine the ID or NAME of the control:
    • Method 1: Read and decypher the HTML source code. Look for " ID=" 
      e.g. for page http://www.autohotkey.com/wiki/ 
      we find this line of code:
      <INPUT id=searchInput title="Search AutoHotkey [f]" accessKey=f name=search>
                ^^^^^^^^^^^                                                ^^^^^^
      
      Here our ID is searchInput, and our NAME is search (we only need one. Either ID or NAME. The ID is best if it's available.) 
       
    • Method 2: Use a tool to help us find the ID or NAME
      1. Use the Microsoft "Internet Explorer Developer Toolbar" for Internet Explorer 7. 
        (Note: for Internet Explorer 8, see "Discovering Internet Explorer Developer Tools" at http://msdn.microsoft.com/en-us/library/cc848894(VS.85).aspx )
        1. Download and install : http://www.microsoft.com/downloads/details.aspx?familyid=E59C3964-672D-4511-BB3E-2D5E1DB91038&displaylang=en
        2. Navigate to your webpage (using Internet Explorer 7)
        3. Bring up the "IE Developer Toolbar". (Note: If you do not see the "IE Developer Toolbar" button on the toolbar, it may be off to the right. Click the right-facing arrows at the end of the IE7 command bar to view all available toolbar buttons.)
        4. FIND -> SELECT ELEMENT BY CLICK
        5. Move your mouse to the desired element and click.
        6. In the middle pane ('Attribute:') scroll down and find the ID string. 
          If there is no ID string, find the NAME string. 
          If there is no NAME string, cripes, it gets a bit difficult. You'll 
          have to read up on Javascript and the DOM (Document Object Model).
      2. Use Firefox and install the Firebug add-on at http://getfirebug.com/
      3. There are other similar programs to help you examine the source code for web pages. Here are a few:


    For these examples assume you're at http://www.autohotkey.com/wiki/ 
    • General format using ID:
      ; Position to a Control Using the Control's Unique ID
      ControlSetText, Edit1, javascript:document.getElementById('<element-ID>')[0].focus()
      ControlSend, Edit1, {Enter}, <window-title>
      Sleep 100     ;give it a moment too do it's thing (important)
      
      (Caution: getElementById is case sensitive! I originally tried getElementByID (last letter D instead of d) and it didn't work.) 

      Example using ID:
      ; Position to a Control Using the Control's Unique ID
      ; For this example the control's ID is searchInput
      ; and the window title contains the word AutoHotkey
      ControlSetText, Edit1, javascript:document.getElementById('searchInput').focus()
      ControlSend, Edit1, {Enter}, AutoHotkey
      Sleep 100     ;give it a moment too do it's thing (important)
      
    • General format using NAME:
      ; Position to a Control Using the Control's NAME
      ControlSetText, Edit1, javascript:document.getElementsByName('<element-name>')[0].focus()
      ControlSend, Edit1, {Enter}, <window-title>
      Sleep 100     ;give it a moment too do it's thing (important)
      
      Example using NAME:
      ; Position to a Control Using the Control's NAME
      ; For this example the control's NAME is search
      ; and the window title contains the word AutoHotkey
      ControlSetText, Edit1, javascript:document.getElementsByName('search')[0].focus()
      ControlSend, Edit1, {Enter}, AutoHotkey
      Sleep 100     ;give it a moment too do it's thing (important)
      
      If more than one control has the same name:
      1. Go kick George Foreman in the shin for naming all 5 of his sons "George" (and two of his daughters).
      2. Then figure out what number to use instead of [0] to get to the n'th control with that NAME. 

        (Note: There is no legal way to use the NAME attribute from such tags as DIV or SPAN, according to the W3C HTML 4.01 specs. You must confine the usage of this attribute to such tags as INPUT, IMG, FRAME, IFRAME, FORM, MAP, PARAM, META, OBJECT, A, SELECT, APPLET, TEXTAREA, or BUTTON. (Those who use XML or XHTML or XFILES or whatever may have different rules to play by.)

      If the control you want has no ID or NAME:
      • Argh! This is getting hard! You'll have to go read up about JavaScript and the DOM (Document Object Model) 
        Some things you could try:
      javascript:document.getElementsByTagName('a')[6].focus() ; Get the 7th <A> tag in the document (numbering begins with 0).
      javascript:document.links[6].focus()                     ; Get the 7th link in the document (numbering begins with 0).
      
  • Methods 5,6,7,...
    For more advanced methods see these two posts:



Q3: SEARCH FOR A COLORED PIXEL 
Note: If I'm searching a white background for black text, I find it works better to search for "not white" rather than search for "black", because sometimes that black text isn't really black when you look at it closely. 

The following actually goes quite fast if you comment out the moving of the mouse. I move the mouse here for demonstration purposes. 

WinGetPos, winposX, winposY, Width, Height, A  ;Get window Width, Height
;MsgBox, 0, , winposX=%winposX%`n winposY=%winposY% `nWidth=%Width% `nHeight=%Height%,

;Calculate a starting position
X := Width - 60
Y := Height / 2
MouseMove, X, Y, 7

MsgBox, 0, , Move left until we find "not white", 1.2

;move left until we find "not white"
loop 200
{
    MouseMove, X, Y, 0
    PixelGetColor, color, X, Y, RGB
    ;MsgBox, 0, , color=%color%, 0.1
    if (color <> "0xFFFFFF")
    {
      Goto FOUND_TCOLOR
    }
    X -= 1
}
;If we drop out here, it means we failed to find our target
MsgBox, 0, , Failed to find color "not white", 2
goto Exit

FOUND_TCOLOR:
MsgBox, 0, , Found "not white". color = %color%, 2

Exit:
MsgBox, 0, , The End, 2
ExitApp


/************************************************ 
R:  NEWBIE RECOMMENDED LEARNING SEQUENCE 
Reference: Recommended by jaco0646 (thank you jaco0646) 
http://www.autohotkey.com/forum/viewtopic.php?t=29204)

  • Commands dealing with files start with FILE
  • Commands dealing with windows start with WIN
  • Commands dealing with text start with STRING

Similarly:

  • Commands that retrieve data from somewhere contain GET
  • Commands that apply data to somewhere contain SET


Suggested order of study for AutoHotkey newbies: 
First:

  1. read the Tutorial
  2. the Scripts page
  3. the FAQ


Afterwards, recommend learning concepts in the following order:

  1. Hotstrings
  2. Hotkeys
  3. Mouse Clicks & Mouse HotKeys
  4. Variables
  5. Loops - especially Parsing Loops
  6. String commands - (e.g. StringMid, StringReplace)
  7. If,Else statements
  8. Expressions
  9. Arrays & Dynamic variables - (StringSplit)
  10. GoSub & Functions
  11. GUIs
  12. Windows Messages
  13. DllCall



/****************************************************************************** 
S:  PRESS ESC TO CANCEL THIS SCRIPT 
Defining Hotkeys 
A hotkey definition line stops execution at that point, so if you want the 
script to run to the end but have the ESC key available to terminate the script, 
put the hotkey definition at the end, just after your ExitApp statement.

;Press ESC to cancel this script
Esc::ExitApp


/****************************************************************************** 
T:  THE AUTOHOTKEY RUN COMMAND 

Program:

Run, ShowParams.exe  hello  goodbye  Friday

AutoHotkey script:

Run, autohotkey.exe  ShowParams.ahk  hello  goodbye  Friday

VBScript:

Run, cscript.exe  ShowParams.vbs  hello  goodbye  Friday

JScript:

Run, cscript.exe  ShowParams.js  hello  goodbye  Friday

Any command:

                    ┌───── cmd.exe strips off these outer " ───────┐
Run, "%comspec%" /c ""ShowParams.ahk"  "hello"  "goodbye"  "friday"", , Hide

Hide is specified to prevent the Command Prompt Window from popping up. 
/c causes Command Prompt Window to exit after command is executed. 
/k instead of /c would cause Command Prompt Window to remain open after command is executed. Useful for debugging. 
 


Notes:

AutoHotkey scripts: 
Why does specifying just 'autohotkey.exe' work? Because the AutoHotkey installer adds the following entry to the registry:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AutoHotkey.exe] 
@="C:\\Program Files\\AutoHotkey\\AutoHotkey.exe"


VBscript and JScript: 
You may also use wscript.exe — wscript.exe is the windows version, cscript.exe is the console version. You'll find them in the System32 directory. 
(JScript is Microsoft's own version of JavaScript.) 

The comspec environment variable usually equates to C:\Windows\System\System32\cmd.exe . On Windows 95,98,ME it equates to COMMAND.COM . It's also possible the user may have changed it to run a fancier command prompt such as JPSoft's Take Command command line utility (http://jpsoft.com

The AutoHotkey RUN command currently does not parse <target> the way you'd expect it to, so the results often aren't quite what you wanted. Here's how it works:

  1. Autohotkey parses off the <target> parameter. 
    The <target> parameter is delimited by a comma, so if you want to include a comma somewhere in the target parameter, you need to escape it with a `
  2. Autohotkey expands any variables (e.g. %day%). 
    Variables are delimited by %, so if you want to include a literal % somewhere in the <target> parameter, you need to escape it with a `
  3. AutoHotkey tries calling CreateProcess() passing the processed <target> parameter as the lpCommandLine argument.
  4. If CreateProcess() fails, AutoHotkey tries calling ShellExecute() passing the processed <target> parameter as the lpFile parameter. Note: This is where it would be nice if AutoHotkey would split <target> between the command and parameters, passing the command as lpFile and the parameters as lpParameters, but it doesn't. It instead passes the entire line as the lpFile parameter, leaving the lpParameters argument NULL. The reason for this is the design decision mentioned in the AutoHotkey source code file script.cpp routine ActionExec: "User can launch a document name containing spaces without having to enclose it in double quotes."


An alternative to using Run is to directly call ShellExecute() :

command = ShowParams.ahk
params = hello goodbye Friday
res := DllCall("shell32\ShellExecuteA"
      , "UInt", 0             ; hwnd
      , "UInt", 0             ; lpOperation
      , "Str", command        ; lpFile
      , "Str", params         ; lpParameters
      , "Str", A_WorkingDir   ; lpDirectory
      , "UInt", 0)            ; nShowCmd
MsgBox (%ErrorLevel%) %res%


/****************************************************************************** 
U:  PASSING PARAMETERS TO AUTOHOTKEY SCRIPTS 
On Windows, parameters are parsed off the command line after the new process is created, by the new process. It's considered the responsibility of the newly started application to call theGetCommandLine() API to retrieve the command line string and parse it.

How does a C/C++ program on Windows get argv[]? The C/C++ compiler which compiles the program secretly adds extra code to the executable that retrieves and parses the command line to extract the parameters before calling WinMain (or main). Thus, for a C/C++ executable on Windows, the parameter parsing rules are determined by the C/C++ compiler that compiled the program.

AutoHotkey is written in C++ and obtains its parameters via the argv[] vector.1 Thus it uses the Microsoft C/C++ Parameter Parsing Rules. The rules are:

  1. Parameters are always separated by a space or tab (multiple spaces/tabs OK) 
  2. If the parameter does not contain any spaces, tabs, or double quotes, then all the characters in the parameter are accepted as is (there is no need to enclose the parameter in double quotes). 
  3. Enclose spaces and tabs in a double quoted part 
  4. A double quoted part can be anywhere within a parameter 
  5. 2n backslashes followed by a " produce n backslashes and start or end a double quoted part 
  6. 2n+1 backslashes followed by a " produce n backslashes + a literal quotation mark 
  7. n backslashes not followed by a quotation mark produce n backslashes 
  8. If a closing " is followed immediately by another ", the 2nd " is accepted literally and added to the parameter (this is the undocumented rule)

For more on passing parameters to programs, with numerous examples, see the essay How Command Line Parameters Are Parsed 
 


Notes:

1. Actually AutoHotkey uses the __argv[] vector.


/****************************************************************************** 
V:  PASSING PARAMETERS TO ANY PROGRAM 
You aren't sure how to escape the special characters in that parameter so it comes out right? See the essay How Command Line Parameters Are Parsed 


/****************************************************************************** 

My title: "" %% (), And All That, is taken from the wonderful book, Div, Grad, Curl, And All That: An Informal Text on Vector Calculus by H. M. Schey (1973) 

History: 
Version 1.00 02/28/2009 
Version 1.04 03/08/2009 
Version 1.05 03/09/2009 
Version 1.09 03/26/2009 
Version 1.10 04/30/2009 
Version 1.12 05/15/2009 
Version 1.14 05/24/2009 
Version 1.19 06/01/2009 
Version 1.21 08/24/2009 
Version 1.22 01/02/2011