1 (изменено: Malcev, 2012-11-05 20:15:16)

Тема: AHK: Завершить скрипт при активировании окна

Может есть иные варианты, кроме как запуска двух скриптов?
Один из которых делает действия, а второй ждет появления окна.
1-ый

run error.ahk
OnMessage(CloseMyScript, "CloseScriptMonitor") ; мониторим наше сообщение
CloseScriptMonitor()
{
    Msgbox, error
    ExitApp
}
loop 5
{
   tooltip % A_Index
   sleep, 1000
}
Msgbox Done
DetectHiddenWindows, On ; искать в скрытых окнах
; получить в массив список всех окон класса AutoHotkey:
WinGet, Array_id, list, ahk_class AutoHotkey
Loop, %Array_id% ; просмотреть массив окон
    ; выслать всем найденным окнам своё сообщение:
    PostMessage, CloseMyScriptError,,,, % "ahk_id" Array_id%A_Index%

ExitApp

2-ой error.ahk

OnMessage(CloseMyScriptError, "CloseScriptMonitor") ; мониторим наше сообщение
CloseScriptMonitor()
{
    ExitApp
}
WinWaitActive, ahk_class Notepad
DetectHiddenWindows, On ; искать в скрытых окнах
; получить в массив список всех окон класса AutoHotkey:
WinGet, Array_id, list, ahk_class AutoHotkey
Loop, %Array_id% ; просмотреть массив окон
    ; выслать всем найденным окнам своё сообщение:
    PostMessage, CloseMyScript,,,, % "ahk_id" Array_id%A_Index%

ExitApp

2 (изменено: vo1ty, 2012-11-05 21:52:51)

Re: AHK: Завершить скрипт при активировании окна

Вы бы хоть объяснили немножко, чего вы пытаетесь добиться.
Я сидел и минут пять пытался понять, ЗАЧЕМ???
Зачем это нужно?
Один скрипт запускает другой, через пять секунд посылает всем окнам AHK CloseMyScriptError и закрывается сам, а также умеет обрабатывать сообщение CloseMyScript. Обработкой является выключение скрипта.
Второй же ждёт открытия блокнота, затем посылает всем CloseMyScript. Также умеет закрываться при получении сообщения CloseMyScriptError.
А в чём суть-то?
Два варианта:
1. Ждать появления блокнота 5 секунд и, если его нет, вырубаться\делать_что-то_ещё.
2. Делать что-то, пока не появится блокнот.
Но оба глупы в принципе.
М?

3 (изменено: Malcev, 2012-11-05 22:07:57)

Re: AHK: Завершить скрипт при активировании окна

Это просто как нейтральный пример.
На самом деле мой скрипт делает комплексную работу в программе.
Но у этой программы есть привычка врубать автосохранение, при появлении которого работа скрипта нарушается.
Поэтому я и выбрал такой алгоритм работы.
Соответственно, 1-ый скрипт выполняет нужный длительный цикл, но во время появления окна автосохранения (в данном случае блокнота), скрипт должен показать, что обнаружена ошибка и его надо перезапустить.
При окончании цикла - скрипт выводит сообщение, что все ОК и закрывает себя и скрипт следящий за появлением окна автосохранения (в данном случае блокнота).

4

Re: AHK: Завершить скрипт при активировании окна

Тогда можно оставить два скрипта, но упростить второй. Зачем ему принимать сообщения от первого? Он ведь и сам закрывается после того, как послал всем сообщение CloseMyScript.
А можно, к примеру, после каждого действия или в конце\начале каждого цикла или по таймеру проверять, не появилось ли окно, и закрываться, если да.
Если честно, AHK пользуюсь совсем недавно, поэтому с конкретным кодом, возможно, не помогу.

5

Re: AHK: Завершить скрипт при активировании окна

Да, действительно я перемудрил. Я ж знаю имена скриптов.
Тогда достаточно в первом Subtitri.ahk написать

run stop.ahk
loop 5
{
   tooltip % A_Index
   sleep, 1000
}
DetectHiddenWindows, on
SetTitleMatchMode, 2
PostMessage, 0x111, 65307,,, stop.ahk - AutoHotkey
Msgbox, Done
ExitApp

А во втором stop.ahk

WinWait, Save Project
DetectHiddenWindows, on
SetTitleMatchMode, 2
PostMessage, 0x111, 65307,,, Subtitri.ahk - AutoHotkey ; Use 65306 to Pause vs. Stop.
MsgBox, ERROR! Turn off Autosave.
ExitApp

Но может все-таки есть другие способы проверки активности окна?
Чтобы все вколбасить в один скрипт?
Что скажут гуру?

6

Re: AHK: Завершить скрипт при активировании окна

Похожая тема

7

Re: AHK: Завершить скрипт при активировании окна

#Persistent
; переменная watcher должна содержать текст нужного скрипта перед выполнением строки DynaRun(watcher)
watcher =
( Ltrim
    parentHwnd := %A_ScriptHWND%
    parentPath := "%A_ScriptFullPath%"
    SetTitleMatchMode, 2
    DetectHiddenWindows, on
    WinWaitActive, Save Project
    PostMessage, 0x111, 65307,,, ahk_id `%parentHwnd`%
    WinWaitNotActive, Save Project
    Run, `%parentPath`%
)

DynaRun(watcher) ; код сохранённый в переменной watcher будет запущен в отдельном процессе ahk при выполнении данной строки

DynaRun(tempScript, pipeName = "")
{
    static DefaultArgs := ["UInt", 2, "UInt", 0, "UInt", 255, "UInt", 0, "UInt", 0, "Ptr", 0, "Ptr", 0, "Ptr"]
    static BOM := Chr(0xFEFF)

    (pipeName = "" && pipeName := "AHK_" . A_TickCount)

    pipeGA := DllCall("CreateNamedPipe", "Str", "\\.\pipe\" . pipeName, DefaultArgs*)
    pipe := DllCall("CreateNamedPipe", "Str", "\\.\pipe\" . pipeName, DefaultArgs*)
    if (pipe = -1 || pipeGA = -1)
        Throw Exception("Failed to create pipe")

    Run, % A_AhkPath . " ""\\.\pipe\" . pipeName . """",, UseErrorLevel HIDE, processID
    if ErrorLevel
        Throw Exception("Could not open file:`n ""\\.\pipe\" . pipeName . """")

    DllCall("ConnectNamedPipe", "Ptr", pipeGA, "Ptr", 0), DllCall("CloseHandle", "Ptr", pipeGA)
    DllCall("ConnectNamedPipe", "Ptr", pipe, "Ptr", 0)
    , tempScript := BOM . tempScript
    , tempScriptSize := 2 + StrLen(tempScript) * 2
    , res := DllCall("WriteFile", "Ptr", pipe, "Str", tempScript, "UInt", tempScriptSize, "UInt*", 0, "Ptr", 0)
    , DllCall("CloseHandle", "Ptr", pipe)
    if !res
        Throw Exception("Unable to write temporary file")

    return processID
}

8

Re: AHK: Завершить скрипт при активировании окна

Что-то не получается мне мой скрипт туда засунуть.
Пишет про какие-то ошибки непонятные.

#Persistent
; переменная watcher должна содержать текст нужного скрипта перед выполнением строки DynaRun(watcher)
watcher = 
(
Text = C:\1.txt ; заменить на файл с субтитрами
watchfolder = C:\222 ; заменить на истинный путь к папке с файлами титров
prtlPath = C:\111  ; заменить на истинный путь к исходным файлам (шаблону), для одной строки должно быть название "1.ptrl" , для двух "2.ptrl" и т.д.
SetBatchLines, -1
FileEncoding, UTF-16
FileRemoveDir, %watchfolder%, 1
FileCreateDir, %watchfolder%
FileRead, str, %Text%
string := RegExReplace(Trim(str,"`r`n"), "\R[\R\s]+", "`n`n")
SubStrList := RegExSplit(string, "S)\n\n")
for index, substring in SubStrList
    string%A_Index% := substring, Lines%A_Index% := SymbCount(substring, "`n")+1
n := SubStrList.MaxIndex()
Loop % n
{
   String := string%A_Index%
   k := Lines%A_Index% - 1
   FileRead, prtl, %prtlPath%\%k%.prtl
   XPos := 0
   Loop, parse, String, `n, `r
   {   
          if (A_Index = 1)
          {
                 Timecode .= A_LoopField "`n"
                 Continue
          }
          if (A_LoopField = "")
                 Continue

          StrLength := StrLen(A_LoopField ) + 1
          XPos := RegExMatch(prtl, "<XPos>", "", XPos + 1)
          prtl := RegExReplace(prtl, "<CharacterAttributes RunCount="".*?"""
                                                    , "<CharacterAttributes RunCount=""" StrLength """"
                                                    , "", 1, XPos - 1)                                    

          StringReplace, LoopField, A_LoopField, &, &amp;, 1
                                          
          if (k > 1)
          {
                 k:=k-1
                 prtl := RegExReplace(prtl, "<TRString TXMarker=""Booyah"">.*?</TRString>"
                                                           , "<TRString TXMarker=""Booyah"">" LoopField "</TRString>"
                                                           , "", 1, XPos - 1)
          }
          Else
                 prtl := RegExReplace(prtl, "<TRString>.*?</TRString>"
                                                           , "<TRString>" LoopField "</TRString>")
    }

   FileName := "title" . SubStr("000", 1, -(StrLen(A_Index))) . A_Index . ".prtl"
   FileAppend, % prtl, %watchfolder%\%FileName%
}

n:=1
TimecodesList := RegExReplace(Trim(Timecode,"`r`n"), " ", "")
Loop, parse, TimecodesList, `n, `r
{
   Timecodes = %A_LoopField%
   StringSplit, string, Timecodes, -
   varTimecode1 = % string1
   varTimecode2 =  % string2

   StringSplit, Timecode1Array, varTimecode1, :
   StringSplit, Timecode2Array, varTimecode2, :


   Digit4:
   if (Timecode2Array4 < Timecode1Array4)
   {
    Timecode2Array4 += 25
    Timecode2Array3 -= 1
    DurationArray4 := Timecode2Array4 - Timecode1Array4
    gosub, Digit3
   }
   if (Timecode2Array4 >= Timecode1Array4)
    DurationArray4 := Timecode2Array4 - Timecode1Array4

   Digit3:
   if (Timecode2Array3 < Timecode1Array3)
   {
    Timecode2Array3 += 60
    Timecode2Array2 -= 1
    DurationArray3 := Timecode2Array3 - Timecode1Array3
    gosub, Digit2
   }
   if (Timecode2Array3 >= Timecode1Array3)
    DurationArray3 := Timecode2Array3 - Timecode1Array3
    
   Digit2:    
   if (Timecode2Array2 < Timecode1Array2)
   {
    Timecode2Array2 += 24
    Timecode2Array1 -= 1
    DurationArray2 := Timecode2Array2 - Timecode1Array2
    gosub, Digit1
   }
   if (Timecode2Array2 >= Timecode1Array2)
    DurationArray2 := Timecode2Array2 - Timecode1Array2

   Digit1:
   if (Timecode2Array1 < Timecode1Array1)
   {
    msgbox, Timecode2Array1 %Timecode2Array1% < Timecode1Array1 %Timecode1Array1%
    msgbox, The "Start" timecode cannot be less than the "End" timecode.
    ExitApp
   }
   if (Timecode2Array1 >= Timecode1Array1)
    {
        DurationArray1 := Timecode2Array1 - Timecode1Array1
        goto, EndProcess
    }

   EndProcess:
   SetFormat, Float, 02.0
   Loop, 4
    DurationArray%A_Index% += 0.0
   TitleDuration%n% = %DurationArray1%:%DurationArray2%:%DurationArray3%:%DurationArray4%
   StartTimecode%n% = % string1
   n++
}


WinActivate, Adobe Premiere Pro
WinWait, Adobe Premiere Pro
Send, +1^{vkBF}Subtitri^{vk49}   ; create bin, ^i
WinWait, Import ahk_class #32770
Send, c:{enter}
Sleep 400
Send, %watchfolder%{enter}
Sleep 400
Send, +{TAB 2}
Sleep 400
Send, ^{vk41}
Sleep 400
Send,{enter}
WinWaitClose, Import ahk_class #32770
WinWait, Import Files ahk_class #32770, , 0.6
WinWaitClose, Import Files ahk_class #32770
Sleep, 300
i := n - 1
Send, {up %i%}
loop % n - 1
{
   TitleDuration := TitleDuration%A_Index%
   StartTimecode := StartTimecode%A_Index%
   Send, {down}+4{TAB}%StartTimecode%{Enter}
   Sleep, 200
   Send, +1^{vk52} ; Ctrl+R
   WinWait, Clip Speed / Duration
   Send, {TAB}%TitleDuration%{Enter}
   WinWaitClose, Clip Speed / Duration
   Send, {vkBE}    ;  .
   Sleep, 200
}
Msgbox, Done
Exit


SymbCount(ByRef string, symb) {
    count := 0
    loop, Parse, string
        (A_LoopField == symb) && ++count
    return count
}


RegExSplit(ByRef in, delim = "") {
    pos := 0, start := 1, Obj := []
    while, pos := RegExMatch(in, delim, match, start)
        Obj.Insert(SubStr(in, start, pos - start)), start := pos + StrLen(match)
    Obj.Insert(SubStr(in, start))
    return Obj
}
)

( Ltrim
    parentHwnd := %A_ScriptHWND%
    parentPath := "%A_ScriptFullPath%"
    SetTitleMatchMode, 2
    DetectHiddenWindows, on
    WinWaitActive, Save Project
    PostMessage, 0x111, 65307,,, ahk_id `%parentHwnd`%
    WinWaitNotActive, Save Project
    Run, `%parentPath`%
)
 
DynaRun(watcher) ; код сохранённый в переменной watcher будет запущен в отдельном процессе ahk при выполнении данной строки
 
DynaRun(tempScript, pipeName = "")
{
    static DefaultArgs := ["UInt", 2, "UInt", 0, "UInt", 255, "UInt", 0, "UInt", 0, "Ptr", 0, "Ptr", 0, "Ptr"]
    static BOM := Chr(0xFEFF)
 
    (pipeName = "" && pipeName := "AHK_" . A_TickCount)
 
    pipeGA := DllCall("CreateNamedPipe", "Str", "\\.\pipe\" . pipeName, DefaultArgs*)
    pipe := DllCall("CreateNamedPipe", "Str", "\\.\pipe\" . pipeName, DefaultArgs*)
    if (pipe = -1 || pipeGA = -1)
        Throw Exception("Failed to create pipe")
 
    Run, % A_AhkPath . " ""\\.\pipe\" . pipeName . """",, UseErrorLevel HIDE, processID
    if ErrorLevel
        Throw Exception("Could not open file:`n ""\\.\pipe\" . pipeName . """")
 
    DllCall("ConnectNamedPipe", "Ptr", pipeGA, "Ptr", 0), DllCall("CloseHandle", "Ptr", pipeGA)
    DllCall("ConnectNamedPipe", "Ptr", pipe, "Ptr", 0)
    , tempScript := BOM . tempScript
    , tempScriptSize := 2 + StrLen(tempScript) * 2
    , res := DllCall("WriteFile", "Ptr", pipe, "Str", tempScript, "UInt", tempScriptSize, "UInt*", 0, "Ptr", 0)
    , DllCall("CloseHandle", "Ptr", pipe)
    if !res
        Throw Exception("Unable to write temporary file")
 
    return processID
}

9 (изменено: creature.ws, 2012-11-06 07:38:32)

Re: AHK: Завершить скрипт при активировании окна

Пишет про какие-то ошибки непонятные.

Ну вы даёте. Меня переполняют реплики использование которых противоречит правилам форума.

На 180-й строке у вас лежит огрызок примера из сообщения #7.
Про экранирование символов в continuation section можно почитать по ссылке.

Что-то не получается мне мой скрипт туда засунуть.

Нет нужды хвататься за предложенные варианты как за спасательный круг. Вы уверены, что пример из сообщения #7 действительно вам нужен? Вы уверены, что поняли, что именно пример делает?

Циклический поиск нужного окна среди всех окон (то, что предоставляет WinWait) — приемлемый способ.
Если используемые вами сейчас скрипты работают — искать альтернативное решение не вижу смысла. В самих скриптах ещё есть «что совершенствовать».

10

Re: AHK: Завершить скрипт при активировании окна

Все, сейчас понял.
Он создает еще один процесс автохотки, который следит за событиями и при необходимых дает указания изначальному скрипту.
То есть, типа мультипоточность.
ХитрО

11 (изменено: teadrinker, 2012-11-06 18:26:56)

Re: AHK: Завершить скрипт при активировании окна

Для проверки активности окна новый поток создавать не нужно, достаточно хука:

EVENT_OBJECT_FOCUS := 0x8005

SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, 0, RegisterCallback("HookProc", "F"), 0, 0, 0)

Loop
{
   ToolTip % A_Index
   Sleep, 300
}
   
   
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
   WinGetClass, class, A
   if (class = "Notepad")
      ExitApp
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags)
}

Скрипт завершается при активации блокнота.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: Завершить скрипт при активировании окна

судя по заголовку, нужен такой длиннющий скрипт

#IfWinActive tratata
ExitApp

13

Re: AHK: Завершить скрипт при активировании окна

Drugoy, судя по твоему посту, тебе нужна вот эта ссылка.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

14 (изменено: Malcev, 2012-11-06 14:42:47)

Re: AHK: Завершить скрипт при активировании окна

Для проверки активности окна новый поток создавать не нужно, достаточно хука:

А что в него нужно вписать, чтобы он находил не по WinGetClass, а WinGetTitle.
Так как WinGetClass возвращает #32770, а такое же имя классов у множества других окон.
Пробовал менять  WinGetClass на WinGetTitle - не распознает.

#IfWinActive tratata
ExitApp

Это совсем не то.

15 (изменено: teadrinker, 2012-11-06 18:27:44)

Re: AHK: Завершить скрипт при активировании окна

Malcev пишет:

А что в него нужно вписать, чтобы он находил не по WinGetClass, а WinGetTitle.

WinGetActiveTitle, Title
if (Title = "Безымянный — Блокнот")
   ExitApp

Отредактировал немного исходный код (idProcess и idThread не Ptr, а UInt).

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16

Re: AHK: Завершить скрипт при активировании окна

teadrinker, твой хук сработал на все 100.
Спасибо!

17

Re: AHK: Завершить скрипт при активировании окна

А может в коллекцию этот хук?
А то там такого нету.

18

Re: AHK: Завершить скрипт при активировании окна

Да, можно добавить.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19 (изменено: Malcev, 2014-06-04 19:20:13)

Re: AHK: Завершить скрипт при активировании окна

Ошибку обнаружил.
Если создать запароленный архив и с помощью winrar его попытаться разархивировать, то выходит табличка с таким title:

Enter password
ahk_class #32770

А хук на эту табличку не срабатывает.
Точнее срабатывает, но только при деактивации и заново активации окна с паролем.

SetTitleMatchMode, 2
EVENT_OBJECT_FOCUS := 0x8005

SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, 0, RegisterCallback("HookProc", "F"), 0, 

0, 0)

Loop
{
   ToolTip % A_Index
   Sleep, 300
}
   
   
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
   WinGetActiveTitle, Title
   if (Title = "Enter password")
      ExitApp
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags)
}

А так msgbox показывается:

SetTitleMatchMode, 2
loop
{
   WinGetActiveTitle, Title
   if (Title = "Enter password")
      msgbox
}

То есть дело в хуке.

20

Re: AHK: Завершить скрипт при активировании окна

Да, подобное окно является принадлежащим основному, и в таком случае хук не считает, что активное окно сменилось. Может, потом что-нибудь придумаю.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

21 (изменено: Malcev, 2014-06-05 15:13:17)

Re: AHK: Завершить скрипт при активировании окна

А какое в данном случае считается основным окном?
Скрипт не срабатывает и на просто извлечение файла из архива.

WinGetActiveTitle, Title
if (Title ~= "Extracting from")
   ExitApp

22

Re: AHK: Завершить скрипт при активировании окна

Malcev пишет:

А какое в данном случае считается основным окном?

Главное окно WinRar.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder