AutoHotKeyの利用補足資料

AutoHotKeyは非常に便利なのですが、
日本語のリファレンスがあまりなく、最初は試行錯誤しながら利用することになります。
本記事がそのような方の手助けになれば幸いです。
なお、バージョンは1.1.33.01で利用しています。
（最新は2020/12/25時点で1.1.33.02なので１つ前のver)

# AutoHotKey is 何
AutoHotKeyはホットキーの割り当てや何か自動化する時に非常なスクリプト言語です。
通称AHKと略されます。
ダウンロードページと参考となるページは以下となります。

　●[ダウンロードページ](https://www.autohotkey.com/download/)(インストーラーとzip版がある)
　●[公式ドキュメント（英語）](https://www.autohotkey.com/docs/AutoHotkey.htm)
　●[日本語wiki](http://ahkwiki.net/Top)
　●[qiitaのAHK絡みの記事群](https://qiita.com/tags/autohotkey)
　●[お世話になった記事](https://qiita.com/draganmaistir/items/0bf4a2ff484523a2dee9#persistent)(AutoHotKey設定メモ)

# この記事の概要
①AHKを利用するうえで読んだ方が良いwikiページ
②AHKのチュートリアル
③リファレンスを読んでも正直よくわからないし、日本語wikiのバージョンも古くて一部機能が記載されていなかったりするので、そこらへんの補足。
# AHKを利用するうえで読んだ方が良いwikiページ一覧
**[利用例](http://ahkwiki.net/Examples)**
ここから目的が似ているスクリプトをコピーして作り始めると良い。

**[コマンド（名称順）](http://ahkwiki.net/Commands_Name)**
メニューリストに書いてないけど、欲しい機能はここから探すのが楽。
[コマンド(カテゴリー別)](http://ahkwiki.net/Commands_Category)もある。

**[キーリスト](http://ahkwiki.net/KeyList)**
ホットキー割り当てのお供


# AHKのチュートリアル
簡単なチュートリアル的なコードを記載していきます。
頭にある#NoEnvとかは最初は無視していいです。
意味はコマンド一覧から見れるので、必要になったら参照して変更してください。
なお、AHKを解凍したフォルダにあるTemplate.ahkをスタート地点とします。

### 「helloWorld」と出力する。
基本です。何も言うことはない。 

~~~helloWorld.ahk
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

MsgBox, helloWorld
~~~


### ホットキーを使う
ホットキーを使ってみましょう。（キーリストを参考に）
ホットキーを利用するとスクリプトが常駐するようになります。（タスクバーを見てください）

~~~hotkey.ahk
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

F1::
MsgBox, helloWorld
Return
F2::
MsgBox, byebye
Return
~~~

:: はホットキーの割り当てを意味します。
[Return](http://ahkwiki.net/Return)は関数等から戻すという意味の他にスレッドを終了させる意味合いがあります。
これを記載しないとF1を押した時に「helloWorld」だけではなく「byebye」も表示されてしまいます。
（理由はリファレンスを参照しください）
とりあえず**Returnは書いておきましょう。**

### 定期的に何かを実行する
定期的に何かを動かしたいという時の記載。
フォルダの監視とかにも応用が利きます。

~~~Timer.ahk
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Persistent

SetTimer,exampleSub,10000
Return

exampleSub:
MsgBox, helloWorld
Return
~~~
ポイントは
 #Persistentと[SetTimer](http://ahkwiki.net/SetTimer)の２つです。
 #Persistentを記載するとホットキーが無くてもスクリプトが常駐するようになります。
 SetTimerはリファレンス見ればわかると思うので割愛。

### 変数への代入、変数の利用、表示
ここからソース抜粋で書いていきます。
AHKの非常に分かりにくいところだと思います。

~~~
hoge := "あ"
if(hoge == "あ")
{
	MsgBox, %hoge%
}
~~~
これでメッセージボックスに「あ」と表示されます。
:=が代入です。型宣言はありません。
hogeが変数にあたるわけですが、ifではhogeで利用していますが、MsgBoxでは%hoge%と利用しています。
こいつが非常に厄介でコマンドやによってhogeだったり%hoge%だったりします。
もしこれを

~~~
hoge := "あ"
if(hoge == "あ")
{
	MsgBox, hoge
}

~~~
と記載した場合は、メッセージボックスには「hoge」と表示されます。
私はここで何回もデバッグで苦労しました。
見極め方としては**そのパラメーターがスクリプトの外部と接続（参照、送信）するか**だと思います。（経験則）
頑張りましょう。

### 関数
特に難しい事はないですが、
引数は複数渡せますが、戻り値は１つだけしか戻せません。

~~~
hoge1 := 1
hoge2 := 30
modori := getAddhoge(hoge1,hoge2)
MsgBox, %modori%
Return

getAddhoge(hoge1,hoge2)
{
	modori := hoge1 + hoge2
	Return modori
}
~~~
これで31と表示されます。


チュートリアルとしてはこれぐらいでしょうか。
とにかく変数絡みが非常にわかりにくいので、怪しいところは逐一デバッグ等しながら頑張りましょう。

# 補足とか色々
日本語wikiとかに書いてないけど使えたり、テクニック、小ネタ等を紹介。
ソース書いていて詰まった時に参考になればと。
（適宜追記するかも）

### ifStringでは全角文字は検索できない
ifStringを利用してtxtから指定した文字列を検索。
という事ができるのですが、この時の注意点として全角文字は検索できません。
なので日本語を検索することはできません。気を付けましょう。


### 複数のGuiを使う
Gui自体については日本語wikiを見れば大体わかると思うのですが、
複数のGuiを利用する方法についてサンプルがな
以下のような記載で使えます。

~~~
Gui, 1:Add, text,,１つ目のGUI
Gui, 2:Add, text,,２つ目のGUI
Gui, 2:Show
~~~
このような記載で「２つ目のGUI」が表示されます。


### Switch
日本語wikiには記載はありませんが1.1.33.01ではSwitch構文は使えます。
使いましょう。

~~~
hoge := 2

Switch hoge
{
    Case 1:
        MsgBox, 1
    Case 2:
        MsgBox, 2
    Case 3:
        MsgBox, 3
    Default: MsgBox, 0
~~~
これで2が表示されます。
Defaultは対応するcaseがない時に使われます。


### for~in、配列
for系はfor~inのみ利用できます。
（普通のfor文やfor~eachは使えません）
配列と組み合わせる事で検索等に利用できます。

~~~
arrayObj := Object()
arrayObj.Insert("a")
arrayObj.Insert("b")
arrayObj.Insert("c")

for i, hoge in arrayObj
{
	if(hoge == "b")
	{
		MsgBox, %hoge%
        Break
	}  
}
~~~
こんな感じ。
for~inは処理速度が微妙と評判ですが仕方ないですね。


### ComObject
AHKではComインスタンスを作成できます。
２つほど例を挙げます

１つ目は任意のアプリケーションをアクティブにする方法です。

~~~
Run cmd.exe
＜中略＞
wshObj := ComObjCreate("Wscript.Shell")
wshObj.AppActivate("cmd.exe")
send, hogehoge
~~~
これで処理の途中で色々と他のアプリがアクティブになっても、
cmd.exeがアクティブな状態になるので、cmdにコマンドを送信できるようになるんですね。


もう1つは任意のブラウザページを操作する方法です。

~~~
＜前略（任意のブラウザページを立ち上げるスクリプト、もしくは立ち上げている状態）＞

For window in ComObjCreate("Shell.Application").windows
{
    If(window.LocationName = "ブラウザページのlocationName")
    {
         Break
    }
}
window.document.getElementByID("hogehoge").click()
~~~
こんな感じで、ブラウザページの中身を参照したり操作したりできます。
ちなみにIDとかはhtmlのソースを見てください。
見れない場合は「window.document.body.innerHTML」をtxtとかに出力すればわかります。


私はComの知識が皆無なのでテンプレ構文しか利用できませんが、
知識があればAHKの利用用途は広がるのではないでしょうか？（適当）


### sendInputはコマンドプロンプトだと効果がない説
sendInputを利用することで、sendを実行している間はキーボードの入力を禁止する事ができます。
しかし、コマンドプロンプト上では入力ができてしまう事象が発生します。
最新版なら直ってるのかもしれませんが、コマンドプロンプトにsendする処理を作る際は注意してください。

終