Как заставить AutoHotkey автоматически закрывать всплывающее диалоговое окно?

Как заставить AutoHotkey автоматически закрывать всплывающее диалоговое окно?

Вопрос

Я хотел бы, чтобы AutoHotkey автоматически определял, когда появляется определенное всплывающее диалоговое окно, и выполнял определенные действия. Как это сделать?

Конкретный пример

В моем конкретном случае я бы хотел, чтобы AutoHotkey закрылОбновить оглавлениедиалоговое окно Word отображается, когда я хочу обновить оглавление.

Вот рабочий процесс:

  1. Я обновляю заголовки в своем документе Word

  2. Я нажимаю Ctrl+, Aчтобы выбрать весь документ

  3. Я нажимаю F9, чтобы обновить все поля

  4. Появляется раздражающее модальное диалоговое окно (которое, судя по моим поискам в Google, невозможно отключить) введите описание изображения здесь

  5. Теперь мне нужно нажать, Arrow downчтобы выбратьОбновить всю таблицузатем EnterнажатьХорошои продолжай

Я бы хотел, чтобы AutoHotkey автоматически выдавал команду Arrow down, Enterпоскольку описанный выше рабочий процесс я выполняю дюжину раз в день.

Конечно, поскольку я инициирую рабочий процесс, я мог бы просто написать скрипт AutoHotkey, который сделает все за меня, начав с Ctrl+ A, например так:

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

Однако приведенный выше пример приведен только для иллюстрации, и бывают случаи, когда всплывающие диалоговые окна появляются случайным образом, и мне бы хотелось, чтобы AutoHotkey выполнял какое-то действие в зависимости от заголовка всплывающего диалогового окна.

Мои исследования на данный момент

  • Некоторые интернет-источники предлагают использовать цикл AutoHotkeyкоторый бесконечно зацикливается и проверяет, скажем, каждую секунду, существует ли окно с определенным заголовком, а затем закрывает его. Но я считаю, что это пустая трата ресурсов процессора
  • Некоторые другие интернет-источники упоминаюткрючок-ракушкавместе с фрагментом кода, и я думаю, что это правильный путь, но я не понимаю фрагмент кода; может ли кто-нибудь объяснить, как это работает, и привести понятный пример, если это решение?

Следующий фрагмент кода:скопировано отсюда.

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, которая запускается, когда ваш скрипт получает сообщение. Содержимое этой функции должно быть вашим кодом, чтобы убедиться, что вы находитесь в нужном окне, а затем выдать команды, которые вы хотите отправить. Ваша функция может принимать до четырех параметров,как определено в файле справкидля OnMessage.

Строки DllCall— это тайная часть, которая связывается с Windows, чтобы получать сообщения от системы. Здесь вы должны знать, что делаете, если собираетесь возиться с hooding в Windows.

SetBatchLines, -1и Process, Priority,, Highскажите, что ваш скрипт очень важен и должен работать на полной скорости все время, и никакой другой системный процесс не должен его замедлять.

Gui +LastFoundи hWnd := WinExist()находим уникальный идентификатор этого скрипта во время его работы, чтобы его можно было зарегистрировать в 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 для обновления всей таблицы.

Связанный контент