Come rendere AutoHotkey automaticamente chiudere una finestra di dialogo?


2

Domanda

Mi piacerebbe AutoHotkey per rilevare automaticamente quando appare una certa finestra di dialogo pop-up e prendere determinate azioni. Come lo faccio?

Esempio concreto

Nel mio caso particolare, mi piacerebbe AutoHotkey per chiudere il Aggiorna sommario dialog Word viene visualizzata quando voglio aggiornare il sommario.

Questo è il flusso di lavoro:

  1. Aggiorno i titoli nel mio documento di Word
  2. Io premo Ctrl + UN per selezionare l'intero documento
  3. Io premo F9 per aggiornare tutti i campi
  4. Questa fastidiosa finestra di dialogo modale appare (che non può essere configurata in base alle mie ricerche su Google) enter image description here

  5. Ora, ho bisogno di premere Freccia in giù selezionare Aggiorna l'intera tabella seguito da accedere pressare Ok e continua

Mi piacerebbe AutoHotkey per emettere automaticamente il Freccia in giù , accedere comando perché il flusso di lavoro sopra descritto è qualcosa che eseguo una dozzina di volte al giorno.

Naturalmente, poiché avvio il flusso di lavoro, potrei semplicemente scrivere uno script AutoHotkey che faccia il tutto per me iniziando con Ctrl + UN come questo:

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

Tuttavia, l'esempio sopra è solo a scopo illustrativo, e ci sono casi in cui le finestre di dialogo a comparsa appaiono a caso e mi piacerebbe che AutoHotkey eseguisse un'azione in base al titolo della finestra di dialogo a comparsa.

La mia ricerca finora

  • Alcune fonti Internet suggeriscono di utilizzare un ciclo AutoHotkey che cicli e controlli indefinitamente, diciamo ogni secondo, se esiste una finestra con un certo titolo e poi la chiude. Ma trovo che sia uno spreco di risorse della CPU
  • Alcune altre fonti Internet menzionano a guscio insieme a un frammento di codice, e penso che sia la strada da percorrere, ma non capisco lo snippet di codice; qualcuno potrebbe spiegare come funziona e dare un esempio comprensibile se questa fosse la soluzione?

Il seguente frammento di codice è copiato da qui .

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
}

Vedo il

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

parte. Cosa fa tutto il resto?

Risposte:


0

Stai andando in profondità. Avere un monitor di programma per un determinato nome di finestra non è una grande tassa sulle risorse di sistema. Questa è probabilmente la strada da percorrere.

ShellMessage potrebbe essere qualsiasi nome di tua scelta, perché è la funzione chiamata da OnMessage, che è ciò che viene attivato quando il tuo script riceve un messaggio. Il contenuto di questa funzione dovrebbe essere il tuo codice per assicurarti di essere nella finestra giusta e quindi emettere i comandi che vuoi inviare. La tua funzione può accettare fino a quattro parametri, come definito nel file della guida per OnMessage.

Il DllCall le linee sono il bit arcano che si lega a Windows per ottenere messaggi dal sistema. È qui che dovresti sapere cosa stai facendo, se hai intenzione di rovinare l'incappucciamento in Windows.

SetBatchLines, -1 e Process, Priority,, High Dite che il vostro script è molto importante e dovrebbe funzionare a tutta velocità sempre e nessun altro processo di sistema dovrebbe mai rallentarlo.

Gui +LastFound e hWnd := WinExist() stanno trovando l'ID univoco di questo script quando è in esecuzione in modo che possa essere registrato con Windows nel successivo DllCall.


0

Per un codice efficiente che non esegue il polling ed è più reattivo, puoi adattare il codice qui:

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

Nella parte di installazione del file aggiungi queste istruzioni:

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

Assicurati che ci siano delle schede tra le colonne in questa parte di impostazione dello script (e non gli spazi, a seconda dell'editor che stai utilizzando). Il nome exe è anche case sensitive poiché usa la corrispondenza RegEx a meno che non lo si cambi.

Quindi questo codice scende nel corpo della sceneggiatura ...

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

Puoi anche usare lo snippet che hai postato ... è praticamente la stessa cosa.

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}   
  }
} 

!! Invia Alt + e per aggiornare l'intera tabella.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.