Что нового

[Автоматизация] Последовательное обращение к череде окон для выполнения операций

Redcut

Новичок
Сообщения
12
Репутация
0
Добрый день.

Версия AutoIt: 3.3.8.1

Описание:
Прошу помочь в следующей ситуации.

Имеется 32 запущенных копии одного и того же приложения (в зависимости от ситуации может быть меньше или больше), постоянно активно только одно или неактивны все, могут быть в свёрнутом виде. Окна приложений имеют одинаковое название (Title) вида: [[hide]] My title 5 [#], но различные поля Class вида: Part1:blum:artX:blum:art001, где X[[/hide]b] - изменяющееся число; и поля Handle, для каждого своё.

Требуется обратиться к окну по классу и названию (?): передать нажатие клавиш и щелчок мыши (по координатам), а затем перейти к следующему окну для выполнения таких же операций. Функцию для центрирования окон на рабочем столе нагуглил, но пока не работает - скорее всего, разберусь сам.

Видится так: часть PartX в классе окон заранее известна. Допустим, пользователь запустил группу копий от 0 до 31 (может быть 32-63, 64-94, 95-100); просим пользователя указать минимальное и максимальное значения, и на их основе заполняем массив. Далее из массива дёргаем по одному элементу и подставляем в класс при проверке существования окна или его активации: если такое окно есть и оно активно, то необходимо его разместить по центру рабочего стола и проделать нужные нам действия, затем переходим к следующему элементу массива и , соответственно, к следующему окну для выполнения тех же действий.

Примечания:
Набросок скрипта.
Код:
HotKeySet('{Esc}','_Stop')
HotKeySet('{Tab}','_Stage1')
HotKeySet('{Home}','_Stage2')
MsgBox(4096,'Напоминание', 'Опции горячих клавишь скрипта: Esc = закончить исполнение скрипта, Tab = первая стадия, Home = вторая стадия.',10)

While 1
   Sleep(100)
WEnd

Func _Stage1()
   $hMinVal = InputBox("Ввод данных","Введите минимальное число")
   $hMaxVal = InputBox("Ввод данных","Введите максимальное число")
   

EndFunc

Func _Stage2()


EndFunc

Func _Middle()
   $hWin = WinWaitActive("[TITLE:[[hide]] My title 5 [[/hide]], CLASS:Part1:Part(переменная, содержащая текущий элемент массива):Part001]", "", 5)
If Not $hWin Then
    MsgBox(4096, 'Сообщение', 'Окно не найдено, завершаем работу скрипта.')
    Call _Stop()
EndIf
   $aPos = WinGetPos($hWin)
   WinMove($hWin, '', (@DesktopWidth - $aPos[2]) / 2, (@DesktopHeight - $aPos[3]) / 2)
EndFunc

Func _Stop()
While 1 
   Sleep(100)
WEnd
EndFunc


Отсебятина:
Беда в том, что с языками программирования я не дружу - кое-что смогу прикрутить сам, а вот с вышеописанным проблемы. Буду благодарен за помощь.

Если что-то не дописал - спрашивайте. Также, если есть варианты проще - пожалуйста, оглашайте - рассмотрю все возможные.
 

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Код:
Opt("MouseCoordMode", 2) ; опция клика в клиентской области

HotKeySet("{ESC}", "Stop") ; выход при нажатии ESC

$Title = "[[hide]] My title 5 [[/hide]]" ; заголовок окон
$List = WinList("[TITLE:" & $Title & "]") ; массив всех окон с заданным заголовком
If Not $List[0][0] Then ; выход при отсутствии окон
  MsgBox(0, "Ошибка", "Окна не найдены: " & $Title)
  Exit
EndIf

Do ; бесконечный цикл
  For $i = 1 To $List[0][0] ; для каждого окна из массива
    If WinActivate($List[$i][1]) Then ; активация при наличии окна
      WinWaitActive($List[$i][1], "", 5) ; ожидание
      Send("1") ; нажатие клавиши
      MouseClick("left", 10, 10, 1, 0) ; клик мыши
    Else
      ConsoleWrite("Окно не найдено: " & $List[$i][1] & @CRLF) ; сообщение, если окно пропало
    EndIf
  Next
  Sleep(3000) ; частота опроса
Until 0

Func Stop()
  Exit
EndFunc
 
Автор
R

Redcut

Новичок
Сообщения
12
Репутация
0
InnI
Большое спасибо. Думал, что уже никто не поможет.

Засунул ваш код в две функции, но есть маленькие нюансы:
1) Из 32 окон было пройдено 31. Это из-за $i = 1? Сейчас проверю с 0.
2) Можно сделать чтобы когда "массив всех окон с заданным заголовком" был пройден (т.е. прошлись по всем окнам и сделали то, что нам нужно) скрипт функция засыпала на N-ное время (допустим, 20 минут) и начиналась снова, и т.д..

Вот как я планирую использовать скриптец:
Код:
Opt("MouseCoordMode", 2) ; опция клика в клиентской области

HotKeySet("{END}", "Stop") ; выход при нажатии ESC
HotKeySet("{ESC}", "Pause") ; пауза при нажатии ESC
HotKeySet("{TAB}", "Stage1") ; вызов первой фазы
HotKeySet("{HOME}", "Stage2") ; вызов второй фазы

While 1 ; начинаем цикл
   Sleep(100); пауза между действием
WEnd ; заканчиваем цикл

Func Stage1()
$Title = "[[hide]] My title 2 [[/hide]]" ; заголовок окон
$List = WinList("[TITLE:" & $Title & "]") ; массив всех окон с заданным заголовком
If Not $List[0][0] Then ; выход при отсутствии окон
  MsgBox(0, "Ошибка", "Окна не найдены: " & $Title)
  Exit
EndIf

  For $i = 1 To $List[0][0] ; для каждого окна из массива
    If WinActivate($List[$i][1]) Then ; активация при наличии окна
      WinWaitActive($List[$i][1], "", 5) ; ожидание
	  Send("{ENTER}")
	  Sleep(1500)
	  Send("{ENTER}")
	  Sleep(1500)
      $sRand = Random(1, 9, 1)
	  Send("($sRand)")
	  Sleep(1500)
    Else
      ConsoleWrite("Окно не найдено: " & $List[$i][1] & @CRLF) ; сообщение, если окно пропало
    EndIf
  Next
  Sleep(3000) ; частота опроса
EndFunc

Func Stage2()
$Title = "[[hide]] My title 2 [[/hide]]" ; заголовок окон
$List = WinList("[TITLE:" & $Title & "]") ; массив всех окон с заданным заголовком
If Not $List[0][0] Then ; выход при отсутствии окон
  MsgBox(0, "Ошибка", "Окна не найдены: " & $Title)
  Exit
EndIf

  For $i = 1 To $List[0][0] ; для каждого окна из массива
    If WinActivate($List[$i][1]) Then ; активация при наличии окна
      WinWaitActive($List[$i][1], "", 5) ; ожидание
	  Send("{SPACE}")
	  Sleep(1500)	   
    Else
      ConsoleWrite("Окно не найдено: " & $List[$i][1] & @CRLF) ; сообщение, если окно пропало
    EndIf
  Next
  Sleep(3000) ; частота опроса
EndFunc

Func Pause()
While 1 ; начинаем цикл
   Sleep(100) ; пауза между действием
WEnd ; заканчиваем цикл
EndFunc

Func Stop()
   Exit ; выход
EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Redcut [?]
Из 32 окон было пройдено 31. Это из-за $i = 1?
Нет, не из-за этого. Проверьте заголовки окон и убедитесь, что их действительно 32.
функция засыпала
Какая из двух?

И оформите код в обоих своих сообщениях тэгами [ autoit ], а не [ code ]
 
Автор
R

Redcut

Новичок
Сообщения
12
Репутация
0
InnI

Нужно чтобы после прохождения всего массива засыпала на минут 20 вторая функция, Stage2, а после начиналась заново.

Код:
Opt("MouseCoordMode", 2) ; опция клика в клиентской области

HotKeySet("{END}", "Stop") ; выход при нажатии END
HotKeySet("{ESC}", "Pause") ; пауза при нажатии ESC
HotKeySet("{TAB}", "Stage1") ; вызов первой фазы
HotKeySet("{HOME}", "Stage2") ; вызов второй фазы

While 1 ; начинаем цикл
   Sleep(100); пауза между действием
WEnd ; заканчиваем цикл

Func Stage1()
$Title = "[[hide]] My title 5 [[/hide]]" ; заголовок окон
$List = WinList("[TITLE:" & $Title & "]") ; массив всех окон с заданным заголовком
If Not $List[0][0] Then ; выход при отсутствии окон
  MsgBox(0, "Ошибка", "Окна не найдены: " & $Title)
  Exit
EndIf

  For $i = 0 To $List[0][0] ; для каждого окна из массива
    If WinActivate($List[$i][1]) Then ; активация при наличии окна
      WinWaitActive($List[$i][1], "", 5) ; ожидание
	  Send("{ENTER}")
	  Sleep(1500)
	  Send("{ENTER}")
	  Sleep(1500)
      $sRand = Random(1, 9, 1)
	  Send("($sRand)")
	  Sleep(1500)
    Else
      ConsoleWrite("Окно не найдено: " & $List[$i][1] & @CRLF) ; сообщение, если окно пропало
    EndIf
  Next
  Sleep(3000) ; частота опроса
EndFunc

Func Stage2()
$Title = "[[hide]] My title 5 [[/hide]]" ; заголовок окон
$List = WinList("[TITLE:" & $Title & "]") ; массив всех окон с заданным заголовком
If Not $List[0][0] Then ; выход при отсутствии окон
  MsgBox(0, "Ошибка", "Окна не найдены: " & $Title)
  Exit
EndIf

  For $i = 1 To $List[0][0] ; для каждого окна из массива
    If WinActivate($List[$i][1]) Then ; активация при наличии окна
      WinWaitActive($List[$i][1], "", 5) ; ожидание
	  Send("{SPACE}")	  
	  Sleep(300000)	   
    Else
      ConsoleWrite("Окно не найдено: " & $List[$i][1] & @CRLF) ; сообщение, если окно пропало
    EndIf
  Next
  Sleep(3000) ; частота опроса
EndFunc

Func Pause()
While 1 ; начинаем цикл
   Sleep(100) ; пауза между действием
WEnd ; заканчиваем цикл
EndFunc

Func Stop()
   Exit ; выход
EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Redcut, проверяйте
Код:
Opt("MouseCoordMode", 2) ; опция клика в клиентской области

HotKeySet("{END}", "Stop") ; выход при нажатии END
HotKeySet("{TAB}", "Stage1") ; вызов первой фазы
HotKeySet("{HOME}", "Stage2") ; вызов второй фазы

AdlibRegister("Stage2", 1000*60*20) ; автовызов второй фазы каждые 20 минут

While 1
  Sleep(1000)
WEnd

Func Stage1()
  Main(1) ; первая фаза
EndFunc

Func Stage2()
  Main(2) ; вторая фаза
EndFunc

Func Main($Stage)
  $Title = "[[hide]] My title 5 [[/hide]]" ; заголовок окон
  $List = WinList("[TITLE:" & $Title & "]") ; массив всех окон с заданным заголовком
  If Not $List[0][0] Then ; выход при отсутствии окон
    MsgBox(0, "Ошибка", "Окна не найдены: " & $Title)
    Exit
  EndIf
  For $i = 1 To $List[0][0] ; для каждого окна из массива
    If WinActivate($List[$i][1]) Then ; активация при наличии окна
      WinWaitActive($List[$i][1], "", 5) ; ожидание
      Switch $Stage
        Case 1 ; первая фаза
          Send("{ENTER}")
          Sleep(1500)
          Send("{ENTER}")
          Sleep(1500)
          $sRand = Random(1, 9, 1)
          Send($sRand)
        Case 2 ; вторая фаза
          Send("{SPACE}")
      EndSwitch
    Else
      ConsoleWrite("Окно не найдено: " & $List[$i][1] & @CRLF) ; сообщение, если окно пропало
    EndIf
  Next
EndFunc

Func Stop()
  Exit ; выход
EndFunc

И отредактируйте первые свои сообщения в тэги [ autoit ], иначе оба предупреждения получим.
 
Автор
R

Redcut

Новичок
Сообщения
12
Репутация
0
InnI
Работает, большое спасибо за затраченное время и приложенные усилия.
Мм, а прогресс бар перебора окон (мол, перебрано N из Y окон) и времени таймера до запуска второй стадии (до повторного запуска стадии 2 осталось X минут) реализовать будет совсем нереальной задачей (если они, конечно, не будут мешать ходу выполнения скрипта)? Извиняюсь за наглость.
 

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Redcut [url_ex=javascript:qq.OpenLink('http://autoit-script.ru/index.php/topic,14441.msg91075.html[hide]msg91075')][?][[/hide]url_ex]
прогресс бар перебора окон (мол, перебрано N из Y окон) и времени таймера до запуска второй стадии
Надеюсь, вы не будете против всплывающей подсказки? Можете разместить её, где вам будет удобней...
Код:
HotKeySet("{END}", "Stop") ; выход при нажатии END
HotKeySet("{TAB}", "Stage1") ; вызов первой фазы
HotKeySet("{HOME}", "Stage2") ; вызов второй фазы

Global $x = 1, $y = 1 ; экранные координаты всплывающей подсказки
Global $RestartTime = 20 ; время перезапуска второй фазы в минутах

Global $Counter = 0 ; счётчик
While 1
  If $Counter >= $RestartTime Then Stage2() ; перезапуск
  Sleep(1000)
WEnd

Func Stage1()
  Main(1) ; первая фаза
EndFunc

Func Stage2()
  Main(2) ; вторая фаза
  $Counter = -1 ; сброс счётчика
  Info() ; всплывающая подсказка
  AdlibRegister("Info", 60000) ; поминутный таймер
EndFunc

Func Info()
  $Counter += 1 ; добавляем минуту по таймеру
  ToolTip("До перезапуска " & $RestartTime - $Counter & " мин", $x, $y, "Фаза 2")
EndFunc

Func Main($Stage)
  $Title = "[[hide]] My title 5 [[/hide]]" ; заголовок окон
  $List = WinList("[TITLE:" & $Title & "]") ; массив всех окон с заданным заголовком
  If Not $List[0][0] Then ; выход при отсутствии окон
    MsgBox(0, "Ошибка", "Окна не найдены: " & $Title)
    Exit
  EndIf
  For $i = 1 To $List[0][0] ; для каждого окна из массива
    ToolTip("Окно " & $i & " из " & $List[0][0], $x, $y, "Фаза " & $Stage)
    If WinActivate($List[$i][1]) Then ; активация при наличии окна
      WinWaitActive($List[$i][1], "", 5) ; ожидание
      Switch $Stage
        Case 1 ; первая фаза
          Send("{ENTER}")
          Sleep(1500)
          Send("{ENTER}")
          Sleep(1500)
          $sRand = Random(1, 9, 1)
          Send($sRand)
        Case 2 ; вторая фаза
          Send("{SPACE}")
      EndSwitch
    Else
      ConsoleWrite("Окно не найдено: " & $List[$i][1] & @CRLF) ; сообщение, если окно пропало
    EndIf
  Next
  ToolTip("Завершено", $x, $y, "Фаза " & $Stage)
EndFunc

Func Stop()
  Exit ; выход
EndFunc
[/url_ex]
 
Верх