スクリプト

スクリプトの構成要素

AutoHotkeyのスクリプトは、以下のような要素で構成される。

コマンド

FileAppend,This is test file.,test.txt
Run,notepad.exe test.txt

AutoHotkeyのスクリプトは、原則として1行に一つのコマンドを記述する。
1行の文字数は16,383バイト以内という制限がある。
コマンドは、コマンド名と引数をカンマで区切って記述する。
コマンド名の直後は、空白文字で区切れば、カンマを省略してもよい。(第1引数に空白を指定する場合を除く)
引数に文字列を指定する場合でも、「"」などで括ったりはせず、そのまま記述する。
引数の先頭と末尾の空白文字は無視されるが、「%A_Space%」のように組み込み変数の参照として記述すれば無視されなくなる。
また、AutoTorimをOffにすることでも、前後の空白を無視されなくすることが出来る。

コマンドには、単にその場で実行されて次の行に移るものだけでなく、条件によって次に実行される行が変わるIf系コマンドや、一連のコマンドを繰り返し実行するLoopコマンド、スクリプトの他の場所にジャンプするGoToコマンド、GoSubコマンドなどもある。

使用できるコマンドについては、リファレンスを参照。

複数行に渡る式・コマンド

if(value=1
    or value=2){
    MsgBox,value is 1 or 2
}

最初の非空白文字が「++」および「--」以外の演算子の場合、前の行の続きとみなされる。
長い式を分割することで、スクリプトの可読性を向上させられる。

Gui,Add,Text
    ,w100 h100 xp+0 yp+24 vTextLabel
    ,DUMMYMESSAGE

「,」も連結に使えるため、コマンドの引数を複数行に分割することも出来る。

MsgBox,1
    +2

コマンドの引数では、「+」などの演算子は文字列の一部とみなされるが、行の連結には有効であるため、上記例では「1+2」という文字列が表示される。

val:=var1
    ;comment
    +var2 ;comment
    /* comment
    */ +var3

空行、空白文字のみの行、コメントなどが間にあっても連結できる。

ヒアドキュメント

MsgBox,this
(
 is
 long
) message

「(」だけの行があると、その次の行から次の「)」で始まる行のまでが改行(`n)区切りで連結され、直前の行の続きとして追加される。

上記例では、以下のように表示される。

this is
 long message

途中に「)」で始まる行を含めたい場合は、「`)」のようにエスケープする

連結後の行の総文字数は16,383バイトまでである。

「(」の後には、以下のオプションを空白文字区切りで列挙することが出来る。

Join[Str]
各行の間に挿入する文字列を改行(「`n」)以外に変更する。単に「Join」と指定すると、区切り文字無しで連結される。
Strには15バイトまでの文字列が指定できる。このStr部分でのみ、「`s」が半角スペースとみなされる。(例:「Join<br`s/>」)
LTrim
各行の行頭の半角スペースやTab文字を無視する
RTrim0
行末の末尾の半角スペースやTab文字を無視しないようにする
C
「;」による行コメント、行末コメントを有効にする
%
「%」を自動的に「`%」にエスケープする(変数展開などが行われなくなる)
`
「`」を自動的に「``」にエスケープする(「`n」などがそのまま文字列の一部として扱われる)
,
カンマ(「,」)が自動的に「`,」としてエスケープされるのを抑止する(コマンドの引数の区切りなどとして扱われるようになる)

ブロック

If a=1
{
	FileAppend,This is test file.,test.txt
	Run,notepad.exe test.txt
}

「{」という内容の行があると、「}」という内容の行が現れるまでが一つのブロックとなる。If系コマンドによる条件分岐やLoopによる繰り返し処理で、複数のコマンドを連続して実行させる場合に使用する。
行頭のTabによるインデントは有っても無くてもよいが、インデントしておけば可読性が向上する。
詳しい例などはブロックの説明を参照。

プリプロセッサ指令

コマンドとは別に「#」で始まるプリプロセッサ指令のようなものがある。
これは、スクリプトが実行される前の解析の段階で処理されるので、引数に変数の参照を含めることは原則として出来ない。
通常は、ブロックなどの内側で使うことは出来ない。

各種指令についても、リファレンスを参照。

ラベル

Label1:
MsgBox,Label1

Goto,Label1

ラベル名に続いて「:」が記述されただけの行があると、ラベルとして認識される。
GoToコマンドやGoSubコマンドを使うことで、特定のラベルの直後の行に処理をジャンプさせることが出来る。
GoSubコマンドでジャンプした場合は、Returnコマンドを実行することによりGoSubが実行された次の行に戻ることが出来る。

OnClipboardChangeなど特定の名称のラベルが存在すると、対応するイベントが発生したときにAutoHotkeyによって自動的に実行される。
また、OnExitコマンドなどのようにイベントに対しラベルを割り当てるコマンドもある。

ホットキーラベル

#F1::
Run,notepad
Run,iexplore
return

キー名に続いて「::」が記述された行はホットキーラベルとなり、そのキーが押されたときにその場所に記述されたコマンドが実行されるようになる。
また、普通のラベルのようにGoToなどでジャンプすることも可能である。
詳細はホットキーの項を参照。
また、利用できるキー名についてはキーリストの項を参照。

#F1::Run,notepad

ホットキーに割り当てるサブルーチンは、1行だけならラベルと同じ行に記述しても良い。

キーリマップ定義

q::d

キー名と「::」に続いて別のキー名だけを記述すると、あるキーの動作を別のキーの動作に変えてしまうリマップが行える。
これはラベルではないので、GoToなどによるジャンプは出来ない。
詳細はリマップの項を参照。

ホットストリングラベル

::ahk::AutoHotkey

ホットキーの他に、特定の文字列がタイプされたときに自動的の他の文字列にタイプし直したり、サブルーチンを実行させたりする「ホットストリング」という機能が存在する。
詳細はHotstringの項を参照。

ユーザー定義関数

add(a,b,c=0,d=0){
	return a+b+c+d
}
MsgBox,% add(1,2,3)

引数を受け取って一連の動作を実行し、返り値を返す関数を定義できる。
関数は式の中で使ったり、単独で呼び出したりして使う。

詳細は関数の項を参照。

コメント

;this is comment
MsgBox,this is message ;this is comment
/*
this
     is
        comment
*/

行頭に「;」(セミコロン)のある行はコメント行となり、無視される。
また、コマンドのあとに半角スペースを空けてセミコロンがあれば、それ以降もコメントとなる。

「/*」で始まる行と「*/」という内容の行の間もコメントになる。

値のデータ形式

コマンドの引数として使われるデータは、すべて文字列として保持される。
一定の書式に合致する文字列の場合、整数・小数・日付時刻として計算などで使うことができる。
「100」や「0xFFFF」のようなものが整数値、「10.05」や「6.023e+23」のようなものが小数値、「20061231235959」のようなものが日付時刻として扱われる。
変数の内容がこれらの形式であるかどうかを判定するには、If var is [not] typeを使用する。
各コマンドが整数や小数を出力するときは、SetFormatコマンドで設定した書式に従って出力される。
整数は符号付き64ビット相当の範囲の値が扱える。
小数はdouble相当のものが扱える。

a=this is string
MsgBox,%a%

b=10
b*=10
MsgBox,%b%

c=0.1
c*=4
MsgBox,%c%

d=20060101
EnvAdd,d,2,Days
MsgBox,%d%

変数

Var = 123abc			;変数「Var」に「123abc」という値を代入
MsgBox,Var is %Var%		;「Var is 123abc」と表示される

名前の付いた「変数」にデータを格納しておくことが出来る。
変数名にはアルファベット、数字、「_」などの文字が使える。
「Var=this is value」のように書くことで、変数に値を格納できる。
変数に格納した値は、「%Var%」のようにコマンドの引数中に埋め込むことで、内容を展開して使える。
同じ値を複数の場所で使いたいときなど、様々な目的で使用される。

FileRead,Var,test.txt		;test.txtの内容が読み込まれ、変数「Var」に格納される

また、コマンドによっては、処理の結果などを変数に格納することがある。
多くの場合、引数として格納先の変数の変数名を指定できる。

VarName=FileContent
FileRead,%VarName%,test.txt		;格納先変数は「FileContent」
MsgBox,%FileContent%			;読み込んだ内容が表示される

格納先の変数名を指定する引数でも、「%Var%」のような変数展開を使用できる。
このテクニックは、不特定多数のデータを扱うときなどに役に立つことがある。

EnvSet,TestEnv,this is a test env
Run,%ComSpec% /K set TestEnv 		cmd.exeが起動し、TestEnvに格納された内容を表示する

変数とは別に、環境変数も扱うことが出来る。EnvSetコマンドで環境変数に代入を行える。
この環境変数は、Runコマンドなどで起動したプログラム内から参照できる。
「%Var%」のような変数の展開では、通常の変数と同じように環境変数も展開できるが、未定義の変数は長さ0の文字列に展開される。
#NoEnv」指令を使用することで、環境変数の参照を無効化し、処理効率を高めることが出来る。
この場合でも、「EnvGet」コマンドを使用すれば、環境変数の値を読み込むことは可能である。

あらかじめ用意された組み込み変数と呼ばれる変数もある。
使用できる組み込み変数については、組み込み変数の項を参照。
多くの組み込み変数は代入により直接変更することは出来ない。
よく使われる組み込み変数として、コマンドの実行結果を格納するErrorLevel変数がある。

変数に値を格納すると、値の容量より若干多めのメモリが確保される。
これは、内容の変更で容量が多くなったとき、いちいちメモリを確保し直す必要がないようにするためである。
「var=」というように、空の値を割り当てることで、割り当てられたメモリを開放できる。
一つの変数の容量の上限は64KBまでとなっているが、#MaxMem指令で変更できる。

変数の計算

変数が数値の場合、EnvAdd, EnvSub, EnvMult, EnvDivコマンドで四則演算が行える。
これらコマンドの省略形として、「+=」,「-=」,「*=」,「/=」が使用できる。
左辺には変数名が来るが、右辺には値がこなければならないので、「%」で挟んで変数の内容を展開するようにする必要がある。

posX = 0
posX += %speedX%

これらのコマンドでは、第1引数と第2引数のどちらもが整数なら結果は整数に、どちらか一方にでも小数形式の値が含まれていれば結果は小数になる。
整数で除算を行い結果を小数で得たい場合、次のように小数形式の値で割ってやる必要がある。

var=10
var/=3.0

また、0を足すなどの結果が変わらない計算を行うことで、形式の変換だけを行うことができる。

SetFormat,FLOAT,0.0	;小数の小数点以下を切り捨てるようにする
var+=0		;varの内容が整数形式に変換される
var+=0.0	;varの内容を小数形式に変換

「:=」による代入や「If()」による条件分岐などでは、複雑な式を使うことも出来る。
1回の四則演算だけなら「v:=v+1」より「v+=1」の方が高速に実行されるが、2回以上の演算は複数のコマンドに分けるより一つの式にした方が高速に実行される可能性がある。

文字列処理

「StringTrimLeft」など、「String」から始まるコマンドでは、文字列の切り出しや分割などの文字列処理が行える。
文字列を順番に並び替える「Sort」コマンドなどもある。
また、Transformコマンドのサブコマンド「Deref」では、「value is %var%」のような文字列の変数参照を展開させることが出来る。
テンプレートファイルに項目を埋め込んだりするのに利用できる。

条件分岐コマンド

Ifコマンドで条件分岐が行える。
比較条件は、if var = valueという形で記述できる。
比較演算子は、「=」、「<>」(not equal)、「>」「<」「>=」「<=」が使用できる。
左辺には変数名が来るが、右辺には値がこなければならないので、「%」で挟んで変数の内容を展開するようにする必要がある。

If MyVar > %Max%
	MsgBox,over
else
	MsgBox,not over

そのほかにも、いくつかの条件文が使用できる。

If/IfEqual/IfNotEqual/IfLess/IfLessOrEqual/IfGreater/IfGreaterOrEqual
変数の比較(「=」「<>」「>」「<」「>=」「<=」と同じ)
if(式)
式の結果の値によって分岐
IfExist / IfNotExist
ファイルの存在の有無
IfInString / IfNotInString
文字列中に指定の文字列が含まれるかどうか
If var [not] in values / If var [not] contains values
varの内容がvaluesに列挙した文字列と一致するかどうか
If var is [not] type
変数のデータ形式
IfMsgBox
一番最近のMsgBoxコマンドで押されたボタン
IfWinActive
指定したウィンドウがアクティブかどうか
IfWinExist
指定したウィンドウが存在するかどうか

繰り返し処理

Loop文で繰り返し処理が使用できる。
繰り返し回数や、対象データは組み込み変数として取得できる。
複数行の処理を繰り返すときには、Continueコマンドで残りの処理をスキップして次の回の実行に移ることが出来る。
また、Breakコマンドでは繰り返しを即座に終了することが出来る。

多くのプログラミング言語に存在するwhile構文やfor構文に該当するようなものはないので、IfコマンドやBreakコマンドを使って自前で記述する必要がある。

繰り返しには、以下の種類がある。

Loop
指定回数の繰り返し
LoopFile
ワイルドカードなどにマッチするファイルやフォルダそれぞれに対する処理
LoopReg
レジストリの指定キー以下のキーに対する処理
LoopReadFile
ファイルを1行ずつ読みながら処理
LoopParse
文字列の1文字ごと、あるいは指定の区切り記号で区切られたフィールドごとに処理

サブルーチン呼び出し、ジャンプ

Gotoコマンドを実行すると、指定したラベルの行にジャンプして、その次の行からを実行させることが出来る。
また、Returnコマンドでジャンプ元に戻ることが出来るGosubコマンドもある。 Goto文を多用しすぎるとプログラムが分かりづらくなるので、出来るだけ使わない方がよい。

関数を使用すれば、呼び出し先に引数を渡したり、返り値を戻したり、他の場所の変数と隔離されたローカル変数を使用したり出来る。

スレッド割り込み

以下のコマンドでラベルを指定しておくと、特定のイベントが発生したときにそのサブルーチンが呼び出されるようになる。
これらのサブルーチン呼び出しでは、スレッドの割り込みが行われる。

SetTimer
タイマーで定期的に実行されるサブルーチンを指定
Menu
カスタムメニューを作成し、選択されたときに実行されるサブルーチンを指定
GUI
GUIを作成し、ボタンが押されたときなどに実行されるサブルーチンを指定
OnExit
スクリプトが終了するときに実行されるサブルーチンを指定
Hotkey
指定されたホットキーが押されたときに実行されるサブルーチンを指定
ホットストリング
特定の文字列をタイプしたときにサブルーチンが実行されるように設定

エスケープ文字

コマンドの引数の中で特別な意味のある記号を含む文字列を扱いたい場合は、記号の前にエスケープ文字を付けてエスケープする必要がある。
多くのプログラミング言語では「\」がエスケープ文字として使われているが、AutoHotkeyではファイルパスの「\」のエスケープの必要をなくすため「`」(Shift+@)が使われる。
以下のようなエスケープシーケンスがある。
それ以外の文字をエスケープした場合、その文字自身になる。(例:「`x」→「x」)
#EscapeChar指令でエスケープ文字を変更できる。

エスケープシーケンス一覧
記号 意味
`, 「,」(カンマ)の文字。
コマンドの区切りと区別するため、エスケープが必要。
なお、コマンドの最後の引数内では、文字としてのカンマであることが自明なため、カンマをエスケープする必要は無い。
`; 「;」(セミコロン)の文字。
半角スペースかTab文字の次に来る場合のみ、コメントの開始記号と区別するためにエスケープする必要がある。
`:: 文字列「::」(コロン二つ)。ホットストリングなどで使用。
`% 「%」(パーセント記号)
`n 改行(LF/0x0A)
`r 復帰(CR/0x0D)
`t Tab文字(0x09)
`v 垂直Tab(0x0B)
`b BackSpace文字(0x08)
`a Bell文字(0x07)
`f 改ページ(0x0C)
`` 「`」自身。
(エスケープ文字2つでエスケープ文字自身になる。)

スクリプトの起動とAuto-executeセクション

スクリプトは読み込み時に解析され最適化される
文法エラーは読み込み時にチェックされ、修正されるまで実行できない。

スクリプトが読み込まれると、最初にReturnExitが実行されるか、ホットキーラベルが記述されている行やスクリプトの終わりに達するまで、スクリプトが実行される。
この部分のことを、auto-executeセクションと呼ぶ。

ホットキーが割り当てられたり、#Persistent指令、Lock系キーの固定などで常駐状態にされない場合、auto-executeセクションが終了した時点でスクリプトは終了する。

ホットキーカスタムメニューアイテムタイマーで起動されるスレッドでは、下記のコマンドで設定される値はそれぞれ独立している。
これらの初期値はAuto-executeセクションで設定できる。
設定が行われる前にスレッドが呼び出されると、期待した動作にならないことがあるので、Auto-executeセクションのできるだけ最初の方で設定するとよい。

スクリプトのデバッグ

スクリプトが期待通りに動作しているかを確認するには、スクリプトの要所要所にMsgBoxコマンドを入れて、動作状況や変数の内容を表示すればよい。
他にも、ListVarsコマンドとPauseコマンドで変数の内容をまとめて表示するという方法もある。
これらのデバッグは、アクティブウィンドウが変わってしまうと正常に動作しないようなところでは使用できないので注意が必要である。