AutoHotKeyで、ウィンドウがある特定の状態になった事を検出し、それに合わせてキーを送信し、自動処理を行う。
通常はスクリーン全体の任意の位置にある画像と同じイメージが検出されたら、処理を行う。
ImageSearchという命令がAutoHotKeyに用意されているが、これは確実ではない。
なぜならピクセルで一致する程度を見ているが、パラメータで不一致度が変えられるにもかかわらず、ほぼ一致していないと失敗するためだ。
Windows11では2023/11/3現在、WindowsUpdate毎にGUIが変化している。
画面のアンチエイリアシングやフォントの描画、ボタンなどのWindowsコントロールの形や色がわずかに変化しているからだ。
その影響を画像イメージも受けていて、アプリの画像であっても、Windowsイメージコントロールの上に描画しているため、影響を受けてしまう。テキストコントロールもClearTypeやOpenTextなどの描画が微妙に変化する。
しかし、テキスト文字列自体はどんなにGUIが綺麗になっても変化しない。
そのため、次の命令が有効で、なおかつ簡単で、性能も高い。
WinActive([WinTitle,WinText,ExcludeTitle,ExcludeText])
この命令が真を返せば、任意のウィンドウが表示されていることがわかる。
必要なのは、WinTextまでの部分なので、次のようになる。
if WinActive("ウィンドウのタイトルバーの文字","画面のテキスト")
これはAutoHotKeyのツール、WinSpyで取得できる。
例えば、
今開発している、RFO-BASICのAPK作成アプリの実行を自動化する。
画面は3つあり、
①プロジェクト選択画面
②APKビルド中画面(ビルド終了後自動的に③へ)
③APK完了画面
この②と③を検出して、自動化する。
WinSpyは、右上のチェックボックスをはずし、マウスクリック時の情報のみにする。
②の様子
APKビルド中は、右画面のように「Creating~」と表示されている。
ウィンドウタイトル文字列は、左WinSpy画面の上の赤枠の「Quick APK v2016-07-27 based on RFO-BASIC! v01.88.01」、
ウィンドウのテキスト文字列は下の赤枠の「Creating~」。
※WinSpy画面の最も下のAll Textでは、隠れた文字列まで表示される。
なので、
if WinActive("Quick APK v2016-07-27 based on RFO-BASIC! v01.88.01","Creating")
で検出できる。
同様に、③の様子は
このようになっている。
従って、
if WinActive("Quick APK v2016-07-27 based on RFO-BASIC! v01.88.01","Congratulations")
で検出できる。
このように②を検出したら③が検出されるまで待ち、③が表示されたら、任意のボタンを押す(ここでは4番目のボタンを押すと①に戻る)とすれば、ビルドの完了を自動監視してくれる。
実際には、③表示時にブザー鳴動し、タブキーを4つ、Enterキーを1つ送って①に戻るように組んでいる。
これで、Windowをスキャンする対象が画面イメージの重い処理でなく、ウィンドウタイトルとその内部文字列という、軽い処理になり、常駐するスクリプトがCPUに高負荷を与えないかつWindowsUpdateに影響されない、確実な処理となった。