Что нового

UIAutomate - автоматизация нестандартных элементов GUI

paa13

Новичок
Сообщения
44
Репутация
1
Перебрать 300 строк - это пара десятков миллисекунд. Либо вы не всё видите. Либо у программы проблемы совместимости с IUIAutomation. Либо вы не там замеры делаете.

Спасибо, этот вариант гораздо быстрее сканирует!
Без галочек моментально (1 сек) , с 20-30ю примерно около 3сек.

Либо у программы проблемы совместимости с IUIAutomation. Либо вы не там замеры делаете.

программа Гугл хром 58
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
OffTopic:
paa13
программа Гугл хром 58
По моим замерам _UIA_GetControlTypeElement обрабатывает примерно одну строку за миллисекунду (300 строк за 290 мс, 1500 строк за 1400 мс). Использование _UIA_GetElementFromCondition в три раза быстрее (100 мс и 450 мс соответственно). Но так и должно быть, т.к. _UIA_GetControlTypeElement содержит цикл сравнения значений найденных элементов.
 

paa13

Новичок
Сообщения
44
Репутация
1

Спасибо еще раз, опять загвоздка :(
Не могу понять как теперь искать совпадения не полного имени, а части его...

Например:
Краска Empis - белая
Краска Empis - красная

поиск тока названия Краска Empis, чтобы и ту и ту надпись находил
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
paa13
как теперь искать совпадения не полного имени
Во-о-от. Теперь мы понимаем, почему медленно работает функция _UIA_GetControlTypeElement ;)
А если использовать условия, то пробуйте так
Код:
$oCond1 = _UIA_CreatePropertyCondition("Name", "Краска Empis - белая")
        $oCond2 = _UIA_CreatePropertyCondition("Name", "Краска Empis - красная")
        $oCondOr = _UIA_CreateLogicalCondition($oCond1, "OR", $oCond2)
        $oCond3 = _UIA_CreatePropertyCondition("ControlType", $UIA_TextControlTypeId)
        $oCondAnd = _UIA_CreateLogicalCondition($oCondOr, "AND", $oCond3)
        $oneElement = _UIA_GetElementFromCondition($oParent, $oCondAnd)
Если эти названия только у текстов, то можно сразу искать по $oCondOr.

Кстати. Ещё немного ускорить поиск в Chrome можно, если искать не от главного окна, а от элемента отображения страницы
Код:
$oParent = _UIA_GetElementFromHandle(ControlGetHandle("[RegexpTitle:- Google Chrome]", "", "Chrome_RenderWidgetHostHWND1"))
 

paa13

Новичок
Сообщения
44
Репутация
1
Код:
$oParent = _UIA_GetElementFromHandle(ControlGetHandle("[RegexpTitle:- Google Chrome]", "", "Chrome_RenderWidgetHostHWND1"))
Спасибо! Даже визуально ускорила сканирование

Код:
$oCond1 = _UIA_CreatePropertyCondition("Name", "Краска Empis - белая")
$oCond2 = _UIA_CreatePropertyCondition("Name", "Краска Empis - красная")

ведь эти названия и так объявляются в массиве
Код:
Global $lists[7] = [6, $text1, $text2, $text3, $text4, $text5, $text6]
$oCond2 = _UIA_CreatePropertyCondition("Name", $lists[$i])


да и функция _UIA_CreateLogicalCondition как я понимаю поддерживает только два условия, это просто кода будет на две страницы.....

Красок их порядка 40-50 наименований, а вот цветов может еще 10 каждой и это получается очень много условий, еслиб был вариант искать тока по части названия
Код:
Global $lists[7] = [6, "Краска Empis", "Краска ЛАКРА", $text3, $text4, $text5, $text6]
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
paa13
ведь эти названия и так объявляются в массиве
И я должен был об этом догадаться?! :stars:

еслиб был вариант искать тока по части названия
Так он есть. У функции _UIA_GetControlTypeElement за это отвечает последний параметр. Но для вас она медленная.
Ещё поиск по частичному совпадению есть у функций _UIA_ElementFindInArray и _UIA_FindElementsInArray. Но предварительно нужно найти все необходимые элементы через _UIA_FindAllElements или _UIA_FindAllElementsEx.


Добавлено:
Сообщение автоматически объединено:

Но это всё "рукописные" функции. Поддержка частичного совпадения значений свойств на уровне интерфейса UIAutomation отсутствует.
 

1alexeev

Новичок
Сообщения
1
Репутация
0
Вопрос по поводу функции _UIA_WaitElementFromCondition
Можно пример какой-нибудь?
Цель:
Скрипт который дожидается когда у элемента X Value.Value будет равен 100 (прогресс бар)
После чего будет выполнено следующее действие.
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
1alexeev
Скрипт который дожидается когда у элемента X Value.Value будет равен 100 (прогресс бар)
Если вы уже нашли элемент и хотите дождаться, когда его значение станет 100, то можно просто организовать цикл
Код:
While _UIA_ElementGetPropertyValue($oElement, "RangeValue.Value") <> 100
  Sleep(111)
WEnd
Если же у вас несколько элементов и нужен тот, который быстрее достигнет значение 100, то можно так
Код:
$oElement = _UIA_WaitControlTypeElement($oParent, "UIA_ProgressBarControlTypeId", 100, "RangeValue.Value", False, 0)
 

paa13

Новичок
Сообщения
44
Репутация
1
Так он есть. У функции _UIA_GetControlTypeElement за это отвечает последний параметр. Но для вас она медленная.
Ещё поиск по частичному совпадению есть у функций _UIA_ElementFindInArray и _UIA_FindElementsInArray. Но предварительно нужно найти все необходимые элементы через _UIA_FindAllElements или _UIA_FindAllElementsEx.

День добрый!
Попробовал поискать этими функциями, но похоже заблудился в трех соснах. что-то не так делаю

Код:
While 1
	
Global $checksys[6] = [5, $Checkbox1_1, $Checkbox1_2, $Checkbox1_3, $Checkbox1_4, $Checkbox1_5]

$aText = _UIA_FindAllElements($oParent, "ControlType", $UIA_TextControlTypeId)
$aType = _UIA_FindElementsInArray($aText, "LocalizedControlType", "текстовый")
$aVisible = _UIA_FindElementsInArray($aType, "Name", "Краска Empis", True)

For $i = 1 To $aVisible[0]
   $sName = _UIA_ElementGetPropertyValue($aVisible[$i], "Name")
   $serRectA = _UIA_ElementGetBoundingRectangle($aVisible[$i])
   ConsoleWrite("List 1 - " & $sName & @CRLF) ; тут находит все совпадения
Next

For $i = 1 To $checksys[0]
    ConsoleWrite("List 2 - " & $sName & @CRLF) ; тут только последняя найденная позиция
	If GUICtrlRead($checksys[$i]) = 1 And $sName = GUICtrlRead($checksys[$i]) Then ConsoleWrite("Найдено - " & GUICtrlRead($checksys[$i], 1) & @CRLF)
Next

WEnd


И как быть если добавить еще несколько вариантов совпадения. Например:

Код:
$aVisible = _UIA_FindElementsInArray($aType, "Name", "Краска Empis", True)
$aVisible = _UIA_FindElementsInArray($aType, "Name", "Краска ЛАКРА", True)
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
paa13
Просто лень мне дорабатывать ваш фрагмент до рабочего состояния, поэтому выложу непроверенный код, описывающий логику, насколько я её понял
Код:
Global $checksys[6] = [5, $Checkbox1_1, $Checkbox1_2, $Checkbox1_3, $Checkbox1_4, $Checkbox1_5]

$aText = _UIA_FindAllElements($oParent, "ControlType", $UIA_TextControlTypeId) ; все текстовые элементы
For $i = 1 To $checksys[0] ; цикл по всем checkbox
  If GUICtrlRead($checksys[$i]) = 1 Then ; если отмечен
    $aElem = _UIA_FindElementsInArray($aText, "Name", GUICtrlRead($checksys[$i], 1), True) ; все элементы, частично совпадающие с именем checkbox
    If Not @error Then
      For $j = 1 To $aElem[0] ; цикл по всем найденным элементам
        ConsoleWrite(_UIA_ElementGetPropertyValue($aElem[$j], "Name") & @CRLF) ; полное имя элемента
      Next
    EndIf
  EndIf
Next
Дальше можете фильтровать массив $aElem по наличию "белая", затем полученный массив по "матовая" и т.д.
 

paa13

Новичок
Сообщения
44
Репутация
1
Просто лень мне дорабатывать ваш фрагмент до рабочего состояния, поэтому выложу непроверенный код, описывающий логику, насколько я её понял
Дальше можете фильтровать массив $aElem по наличию "белая", затем полученный массив по "матовая" и т.д.

Спасибо! самое то! работает прекрасно и что самое главное быстро!
но................... тока я обрадовался, возникла другая проблема...
Примерно через минут 20-30 сканирования скрипт выдает ошибку по памяти, разумеется недостатка в памяти нет
, пробовал ставить sleep не помогло...
 

Вложения

  • Снимок.PNG
    Снимок.PNG
    2.4 КБ · Просмотры: 10
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
paa13
скрипт выдает ошибку по памяти
Если вы уверены, что это связано с UIAutomate, то укажите функцию, в которой или после которой это происходит. Я с подобным поведением в этой UDF не сталкивался. Единственное, что могу предложить, обнуляйте принудительно переменные после использования.
 

paa13

Новичок
Сообщения
44
Репутация
1
Если вы уверены, что это связано с UIAutomate, то укажите функцию, в которой или после которой это происходит. Я с подобным поведением в этой UDF не сталкивался. Единственное, что могу предложить, обнуляйте принудительно переменные после использования.

Код:
While 1
$aText = _UIA_FindAllElements($oParent, "ControlType", $UIA_TextControlTypeId) ; все текстовые элементы

For $i = 1 To $checksys[0] ; цикл по всем checkbox
  If GUICtrlRead($checksys[$i]) = 1 Then ; если отмечен
    $aElem = _UIA_FindElementsInArray($aText, "Name", GUICtrlRead($checksys[$i], 1), True) ; все элементы, частично совпадающие с именем checkbox
  EndIf
Next
Wend


Пожирание памяти происходит в этой строке, прибавляет примерно 200кб за цикл :
Код:
$aElem = _UIA_FindElementsInArray($aText, "Name", GUICtrlRead($checksys[$i], 1), True) ; все элементы, частично совпадающие с именем checkbox

Если ее закоментировать, память не растет, пока пробую по разному, как это исправить
 

paa13

Новичок
Сообщения
44
Репутация
1
Не могу повторить. У меня утечек нет. Проверил на Win7x86 и Win10x64.

Я пробовал на 7х64 и 8.1х64, одинаково..

Вроде удалось остановить утечку обнулением переменной $aText после поиска элементов в массиве

Код:
While 1
$aText = _UIA_FindAllElements($oParent, "ControlType", $UIA_TextControlTypeId) ; все текстовые элементы

For $i = 1 To $checksys[0] ; цикл по всем checkbox
  If GUICtrlRead($checksys[$i]) = 1 Then ; если отмечен
    $aElem = _UIA_FindElementsInArray($aText, "Name", GUICtrlRead($checksys[$i], 1), True) ; все элементы, частично совпадающие с именем checkbox
    $aText = 0
  EndIf
Next
Wend
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
paa13
удалось остановить утечку
Вы хоть понимаете, что сделали? Вы обнулили исходный массив, не закончив перебирать checkbox'ы. После первого прохода вы уже ничего не найдёте.


Добавлено:
Сообщение автоматически объединено:

paa13
Я пробовал на 7х64 и 8.1х64
Если вы запускаете скрипт, как х64, то попробуйте запустить, как х86. Или наоборот.
 

paa13

Новичок
Сообщения
44
Репутация
1
Вы хоть понимаете, что сделали? Вы обнулили исходный массив, не закончив перебирать checkbox'ы. После первого прохода вы уже ничего не найдёте.
Да, действительно. поспешил...

Если вы запускаете скрипт, как х64, то попробуйте запустить, как х86. Или наоборот.
Эффекта не дало :(
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
paa13
Попробуйте обнулять перед каждой итерацией
Код:
While 1
  $aText = 0
  $aElem = 0
...
 

paa13

Новичок
Сообщения
44
Репутация
1
Попробуйте обнулять перед каждой итерацией
Код:
While 1
  $aText = 0
  $aElem = 0
...
Это я сразу попробовал, эффекта нет

Может дело в том что страница каждый цикл обновляется, вот более подробный код..
Код:
While 1

	$oParent = _UIA_GetElementFromHandle(ControlGetHandle("[RegexpTitle:- Google Chrome]", "", "Chrome_RenderWidgetHostHWND1"))
	$Element = _UIA_GetControlTypeElement($oParent, "UIA_TextControlTypeId", "Обновить")
	_UIA_ElementDoDefaultAction($Element)
	
	Global $checksys[6] = [5, $Checkbox1_1, $Checkbox1_2, $Checkbox1_3, $Checkbox1_4, $Checkbox1_5]

	$aText = _UIA_FindAllElements($oParent, "ControlType", $UIA_TextControlTypeId) ; все текстовые элементы

For $i = 1 To $checksys[0] ; цикл по всем checkbox
  If GUICtrlRead($checksys[$i]) = 1 Then ; если отмечен
    $aElem = _UIA_FindElementsInArray($aText, "Name", GUICtrlRead($checksys[$i], 1), True) ; все элементы, частично совпадающие с именем checkbox
  EndIf
Next
WEnd

WEnd
 
Верх