
Pregunta
Me gustaría que AutoHotkey detecte automáticamente cuando aparece un determinado cuadro de diálogo emergente y realice determinadas acciones. ¿Cómo puedo hacer eso?
Ejemplo concreto
En mi caso particular, me gustaría que AutoHotkey cierre elActualizar tabla de contenidosEl cuadro de diálogo Word aparece cuando quiero actualizar la tabla de contenido.
Este es el flujo de trabajo:
Actualizo los títulos en mi documento de Word
Presiono Ctrl+ Apara seleccionar todo el documento.
Presiono F9para actualizar todos los campos.
Aparece este molesto cuadro de diálogo modal (que no se puede configurar según mis búsquedas en Google)
Ahora, necesito presionar Arrow downpara seleccionarActualizar toda la tablaseguido de EnterpresionarDe acuerdoy continuar
Me gustaría que AutoHotkey emita automáticamente el Arrow downcomando Enterporque el flujo de trabajo descrito anteriormente es algo que realizo una docena de veces al día.
Por supuesto, debido a que inicio el flujo de trabajo, podría simplemente escribir un script AutoHotkey que haga todo por mí comenzando con Ctrl+ Aasí:
#IfWinActive ahk_class OpusApp
F9::
Send, ^a
Send, {F9}
Sleep, 200
Send, {Down}
Send, {Enter}
return
Sin embargo, el ejemplo anterior es sólo para fines ilustrativos, y hay casos en los que los cuadros de diálogo emergentes aparecen al azar y me gustaría que AutoHotkey realice alguna acción dependiendo del título del cuadro de diálogo emergente.
Mi investigación hasta ahora
- Algunas fuentes de Internet sugieren utilizar un bucle AutoHotkeyque se repite indefinidamente y comprueba, digamos cada segundo, si existe una ventana con un título determinado y luego la cierra. Pero creo que eso es un desperdicio de recursos de la CPU.
- Algunas otras fuentes de Internet mencionan ungancho de conchajunto con un fragmento de código, y creo que ese es el camino a seguir, pero no entiendo el fragmento de código; ¿Alguien podría explicar cómo funciona y dar un ejemplo comprensible siempre que esta fuera la solución?
El siguiente fragmento de código escopiado de aquí.
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
}
veo el
If (Title = "sun 4 - foxtrot - Remote Desktop Connection")
parte. ¿Qué hace el resto?
Respuesta1
Estás profundizando. Tener un monitor de programa para un nombre de ventana determinado no supone un gran impuesto para los recursos del sistema. Probablemente ese sea el camino a seguir.
ShellMessage
podría ser cualquier nombre de su elección, porque es la función llamada por OnMessage
, que es lo que se activa cuando su secuencia de comandos recibe un mensaje. El contenido de esta función debe ser su código para asegurarse de que está en la ventana correcta y luego emitir los comandos que desea enviar. Su función puede aceptar hasta cuatro parámetros,como se define en el archivo de ayudapara OnMessage
.
Las DllCall
líneas son la parte arcana que se vincula a Windows para recibir mensajes del sistema. Aquí es donde debes saber lo que estás haciendo si vas a meterte con el encapuchamiento de Windows.
SetBatchLines, -1
y Process, Priority,, High
diga que su script es muy importante y debe ejecutarse a máxima velocidad todo el tiempo y ningún otro proceso del sistema debería ralentizarlo.
Gui +LastFound
y hWnd := WinExist()
estamos buscando el ID único de este script cuando se está ejecutando para poder registrarlo en Windows en el futuro DllCall
.
Respuesta2
Para obtener un código eficiente que no realice sondeos y responda mejor, puede adaptar el código aquí:
En la parte de configuración del archivo agregue estas declaraciones:
Update Table of Contents ahk_exe WINWORD.EXE B WordTOCupdate
Update Table of Figures ahk_exe WINWORD.EXE B WordTOCupdate
Asegúrese de que haya pestañas entre las columnas en esta parte de configuración del script (y no espacios, según el editor que esté utilizando). El nombre del archivo ejecutable también distingue entre mayúsculas y minúsculas, ya que utiliza coincidencias RegEx a menos que lo cambie.
Luego este código se incluye en el cuerpo del script...
;-------------------------------------------------------
; Check for Microsoft Word Update Table of Contents
;-------------------------------------------------------
WordTOCupdate:
WinActivate ;Set Window to Be on top
SendInput !e{Enter}
return
También puedes usar el fragmento que publicaste... es básicamente lo mismo.
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}
}
}
El !e envía Alt+e para actualizar toda la tabla.