AutoHotkey でポップアップダイアログを自動的に閉じるにはどうすればよいですか?

AutoHotkey でポップアップダイアログを自動的に閉じるにはどうすればよいですか?

質問

AutoHotkey で特定のポップアップ ダイアログが表示されたときに自動的に検出し、特定のアクションを実行するようにしたいのですが。どうすればいいですか?

具体的な例

私の場合は、AutoHotkeyで目次を更新目次を更新するときに Word に表示されるダイアログ。

ワークフローは次のとおりです。

  1. Word文書のタイトルを更新する

  2. Ctrl+を押してA文書全体を選択します

  3. F9すべてのフィールドを更新するには押してください

  4. この迷惑なモーダルダイアログが表示されます(Google 検索によると、これを非表示にすることはできません) ここに画像の説明を入力してください

  5. Arrow down選択するには押す必要がありますテーブル全体を更新続いてEnter押すわかりましたそして続ける

上記のワークフローは 1 日に何十回も実行するものなので、 AutoHotkey でArrow down,コマンドを自動的に発行したいと思います。Enter

もちろん、ワークフローを開始するのは私なので、次のようにCtrl+で始まるすべての処理を実行する AutoHotkey スクリプトを作成することもできます。A

#IfWinActive ahk_class OpusApp
F9::
Send, ^a
Send, {F9}
Sleep, 200
Send, {Down}
Send, {Enter}
return

ただし、上記の例はあくまで説明目的であり、ポップアップダイアログがランダムに表示され、ポップアップダイアログのタイトルに応じて AutoHotkey に何らかのアクションを実行させたい場合もあります。

これまでの私の研究

  • いくつかのインターネットソースでは、AutoHotkeyループの使用を推奨していますこれは、特定のタイトルのウィンドウが存在するかどうかを1秒ごとに無限にループしてチェックし、その後閉じます。しかし、私はそれがCPUリソースの無駄だと感じています。
  • 他のインターネットの情報源では、シェルフックコード スニペットも添付されており、これが正しい方法だと思いますが、コード スニペットが理解できません。これが解決策である場合、どのように機能するかを説明し、わかりやすい例を挙げていただける方はいらっしゃいますか?

次のコードスニペットはここからコピー

SetBatchLines, -1
Process, Priority,, High


Gui +LastFound
hWnd := WinExist()


DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return


ShellMessage( wParam,lParam ) {
  If ( wParam = 32772 or WParam = 4) ;  HSHELL_WINDOWACTIVATED := 4 or 32772
       WinGetActiveTitle, Title
  If  ( Title = "sun 4 - foxtrot - Remote Desktop Connection" ) 
        SetCapsLockState, on
    else SetCapsLockState, off
}

私は

If (Title = "sun 4 - foxtrot - Remote Desktop Connection") 

部分。残り全体は何をしますか?

答え1

深いところまで来ていますね。特定のウィンドウ名をプログラムで監視することは、システム リソースにそれほど負担をかけません。おそらくこれが正しいやり方でしょう。

ShellMessageは任意の名前にすることができます。これは、OnMessageスクリプトがメッセージを受信したときにトリガーされる によって呼び出される関数だからです。この関数の内容は、正しいウィンドウにいることを確認し、送信したいコマンドを発行するためのコードである必要があります。関数は最大 4 つのパラメータを受け入れることができます。ヘルプファイルで定義されている通りのためにOnMessage

これらのDllCall行は、システムからメッセージを取得するために Windows に結び付けられる難解な部分です。Windows のフードをいじる場合は、ここで何をしているのかを知っておく必要があります。

SetBatchLines, -1そしてProcess, Priority,, High、スクリプトは非常に重要であり、常にフルスピードで実行される必要があり、他のシステム プロセスによってスクリプトの速度が低下することはあってはならないと伝えます。

Gui +LastFoundそして、hWnd := WinExist()スクリプトの実行時にそのスクリプトの一意の ID を見つけて、後続の で Windows に登録できるようにしますDllCall

答え2

ポーリングを行わず、応答性の高い効率的なコードにするには、次のコードを適応させます。

http://www.autohotkey.com/board/topic/84397-winwait-framework-do-something-to-a-window-when-it-appears/

ファイルのセットアップ部分に次のステートメントを追加します。

Update Table of Contents ahk_exe WINWORD.EXE    B       WordTOCupdate
Update Table of Figures ahk_exe WINWORD.EXE     B       WordTOCupdate

スクリプトのこのセットアップ部分の列間にはタブがあることを確認してください (使用しているエディターによっては、スペースは使用しないでください)。exe 名は、変更しない限り RegEx マッチングを使用するため、大文字と小文字が区別されます。

次に、このコードをスクリプトの本体に記述します...

;-------------------------------------------------------
; Check for Microsoft Word Update Table of Contents
;-------------------------------------------------------
WordTOCupdate:
    WinActivate             ;Set Window to Be on top
    SendInput !e{Enter}
return

投稿したスニペットを使用することもできます...基本的には同じものです。

Gui +LastFound
hWnd := WinExist()


DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return


ShellMessage( wParam,lParam ) {
  If ( wParam = 32772 or WParam = 4) ;  HSHELL_WINDOWACTIVATED := 4 or 32772
       WinGetActiveTitle, Title
  If  (Title="Update Table of Contents" ) 
  {
       SendInput !e{Enter}   
  }
} 

!e は Alt+e を送信してテーブル全体を更新します。

関連情報