Что нового

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

Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Принцип понятен.
Как вариант
Код:
#include <UIAutomate.au3>

$oPage = _UIA_GetElementFromHandle(ControlGetHandle("AutoIt — Википедия - Google Chrome", "", "Chrome_RenderWidgetHostHWND1"))
$aText = _UIA_FindAllElements($oPage, "ControlType", $UIA_TextControlTypeId)
$aFrom = _UIA_FindElementsInArray($aText, "Name", "Класс языка", False, True)
$aTo   = _UIA_FindElementsInArray($aText, "Name", "Повлиял на" , False, True)
For $i = $aFrom[1] + 1 To $aTo[1] - 1
  ConsoleWrite(_UIA_ElementGetPropertyValue($aText[$i], "Name") & @CRLF)
Next
 

breakin

Новичок
Сообщения
4
Репутация
0
Надо кликнуть по строке в панели ($UIA_EditControlTypeId), куда
программа выводит и периодически обновляет текстовые данные.
Эти данные мой скрипт может считать и принять за юзера решение,
по какой строке кликать.
Первое, что пришло на ум - по координатам мыши. Но известен только размер
панели, и то, что там есть скроллбар. То есть невозможно определить, сколько
строк помещается в панель, чтобы высчитать координаты клика по нужной строке.
Какие еще есть варианты? В смысле не еще, а вообще, потому что тут тупик.
 
Последнее редактирование:
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Элемент Edit не поддерживает шаблоны работы с текстом. Всё, что можно от него получить - это весь текст и положение скролла. Количество строк, положение каретки, наличие выделения Edit не возвращает. Без "костылей" не обойтись.
Если Edit поддерживает выделение (Shift + Down) и копирование (Ctrl + C), то можно построчно выделять текст, копировать в буфер обмена, сравнивать с искомой подстрокой, при совпадении искать цвет выделения текста и кликать в координаты цвета.
 

breakin

Новичок
Сообщения
4
Репутация
0
Жажда неизведанного погнала в другую сторону - _UIA_ElementMouseClick.
Задаю координаты для клика - кликает по 6 строке.
Опускаю окно (без ресайза) строго по игреку вниз - кликает по 17й.
Во-1х, почему не по 6й.
Во-2х, почему по строке ниже, а не выше.
Думал, координаты мыши абсолютные (относительно границ экрана), видно не так.
Скроллинга нет, специально вывел текста где-то на 80% высоты панели.
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
@breakin
Посмотрите координаты элемента через _UIA_ElementGetBoundingRectangle() до смещения окна и после. И сравните с Inspect. Возможно, после перемещения окна нужно обновить элемент (заново найти/создать).

Вот пример для блокнота. Работает корректно без обновления элемента - выделяет ту же строку.
Код:
#include <UIAutomate.au3>

Run("notepad.exe")
$hWnd = WinWaitActive("[class:Notepad]")
WinMove($hWnd, "", 50, 50, 400, 300)
$hEdit = ControlGetHandle($hWnd, "", "Edit1")
For $i = 1 To 9
  ControlSend($hWnd, "", $hEdit, $i & @CR)
Next

$X = 80
$Y = 60
$oEdit = _UIA_GetElementFromHandle($hEdit)
_UIA_ElementMouseClick($oEdit, "", $X, $Y, 2)
Sleep(1111)
ControlSend($hWnd, "", $hEdit, "^{home}")
Sleep(1111)
WinMove($hWnd, "", 50, 300)
_UIA_ElementMouseClick($oEdit, "", $X, $Y, 2)
 

breakin

Новичок
Сообщения
4
Репутация
0
Дело оказалось в другом. Координаты в _UIA_ElementMouseClick относительные (относительно границ элемента),
а в _UIA_ElementGetBoundingRectangle - абсолютные (т.е. относительно границ экрана).
Просто не обратил внимания на слова "координата клика (по умолчанию середина ширины элемента)" в описании
функции. Из которых можно было бы догадаться об относительности.
Когда вычел из координат клика координаты границ элемента - заработало.
 

hexin

Новичок
Сообщения
32
Репутация
0
Плдскажите пожалуйста почему этот код не считывает ссылку из адресной строки Firefox?
Код:
#include "UIAutomate.au3"
Opt("WinTitleMatchMode", 2)

sleep(1000)
WinActivate("Mozilla Firefox")
sleep(5)
$hWnd = WinWait("Mozilla Firefox")
$oParent = _UIA_GetElementFromHandle($hWnd)
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "Адресная строка и строка поиска")
$URL = _UIA_ElementGetPropertyValue($oElement, "Value.Value")
MsgBox(0, "URL", $URL)
 
Последнее редактирование:

hexin

Новичок
Сообщения
32
Репутация
0
Запустите скрипт из SciTE по F5 и посмотрите в консоле ошибки.
две ошибки
!> _UIA_GetControlTypeElement : çíà÷åíèå óêàçàííîãî ñâîéñòâà íàéäåííûõ ýëåìåíòîâ íå ñîîòâåòñòâóåò çàäàííîìó
!> _UIA_ElementGetPropertyValue : ïåðâûé ïàðàìåòð íå ÿâëÿåòñÿ îáúåêòîì

Вы можете подсказать как устранить эти ошибки?
Интересно это только у меня этот код не работает?
Дело в том что это код изначально был сделан под хром, я только изменил титл с хрома на лису, в надежде что всё остальное должно подойти.
У меня нет SDK inspect так как на диске Ц нет свободных 2,6Гб чтобы его установить. Так что есть подозрение что не подходит какойто параметр
 
Последнее редактирование:
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Вы можете подсказать как устранить эти ошибки?
Для начала найдите на форуме способ исправить вывод кириллицы в консоль SciTE.

код изначально был сделан под хром, я только изменил титл с хрома на лису, в надежде что всё остальное должно подойти.
И не надейтесь. Это совершенно разные браузеры. Большинство примеров на этом форуме для хром нужно переделывать под лису.

У меня нет SDK inspect
А он и не нужен. Достаточно утилиты в архиве с UDF.

есть подозрение что не подходит какойто параметр
Верно. В данном случае имя панели адреса будет другим. У меня, например, работает так
Код:
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "Найдите в Яндекс или введите адрес")
 

hexin

Новичок
Сообщения
32
Репутация
0
А он и не нужен. Достаточно утилиты в архиве с UDF.
Спасибо!
С её помощью увидел что не так.
Но всё равно практически не работает!
Дело в том что браузер как бы замораживается на минуту и он вообще недоступен становится, через минуту размораживается и иногда ссылку считывает но чаще не считывает и выдает ошибки в консоле.. В этот период лиса на 40% повышает загрузку процессора.
Хром моментально всё выполняет.
Так что проблема именно с лисой. (у меня версия лисы 90,0,1 64-бит)
Из-за чего такое может быть?
Проверьте пожалуйста на своей лисе.

вот ошибки
!> _UIA_FindAllElementsEx : îøèáêà ñîçäàíèÿ îáúåêòà ìàññèâà
!> _UIA_FindAllElements : îøèáêà ñîçäàíèÿ ìàññèâà ýëåìåíòîâ (îáúåêòîâ)
!> _UIA_GetControlTypeElement : îøèáêà ñîçäàíèÿ ìàññèâà ýëåìåíòîâ (îáúåêòîâ)
!> _UIA_ElementGetPropertyValue : ïåðâûé ïàðàìåòð íå ÿâëÿåòñÿ îáúåêòîì

Код:
#include "UIAutomate.au3"
Opt("WinTitleMatchMode", 2)

sleep(1000)
WinActivate("Mozilla Firefox")
sleep(5)
$hWnd = WinWait("Mozilla Firefox")   ; копирует ссылку из адресной строки  лисы
$oParent = _UIA_GetElementFromHandle($hWnd)
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "Найдите в Google или введите адрес")
$URL = _UIA_ElementGetPropertyValue($oElement, "Value.Value")
MsgBox(0, "URL", $URL)
 
Последнее редактирование:
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Так что проблема именно с лисой
Верно. Они были и есть. Особенно при поиске массивов элементов.

Текст строки адреса можно получить так
Код:
#include "UIAutomate.au3"

$oParent = _UIA_GetElementFromHandle(WinWait("[RegexpTitle:.*Mozilla Firefox]"))
$oTypeCond = _UIA_CreatePropertyCondition("ControlType", $UIA_EditControlTypeId)
$oNameCond = _UIA_CreatePropertyCondition("Name", "Найдите в Google или введите адрес")
$oLogicCond = _UIA_CreateLogicalCondition($oTypeCond, "AND", $oNameCond)
$oElement = _UIA_GetElementFromCondition($oParent, $oLogicCond)
If IsObj($oElement) Then
  $URL = _UIA_ElementGetPropertyValue($oElement, "Value.Value")
  ConsoleWrite($URL & @CRLF)
Else
  ConsoleWrite("Элемент не найден" & @CRLF)
EndIf


Из-за чего такое может быть?
Возможно, из-за некорректной реализации метода FindAll интерфейса IUIAutomation.
 

Andrey_A

Продвинутый
Сообщения
319
Репутация
68
Текст строки адреса можно получить так
Код работает, но возник вопрос - с некоторых сайтов адрес возвращается не полностью, без приставки:
https://
http://
в некоторых случаях это:
Можно ли получить полный адрес ссылки из адресной строки?
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
получить полный адрес ссылки из адресной строки
about:config
browser.urlbar.trimURLs = false

Или так
Код:
WinActivate("[RegexpTitle:.*Mozilla Firefox]")
Send("{F6}^{ins}{F6}")
Sleep(111)
$URL = ClipGet()
ConsoleWrite($URL & @CRLF)
 

Andrey_A

Продвинутый
Сообщения
319
Репутация
68
Спасибо, сделал по другому - если нет протокола направляю полуссылку в скрытый браузер IE и получаю обратно через .LocationURL
Это работает для разных браузеров...
Сообщение автоматически объединено:

about:config
browser.urlbar.trimURLs = false
А для других браузеров случайно не подскажите где изменить подобную настройку?
 
Последнее редактирование:
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
для других браузеров
IE всегда показывает. Для хрома
Для включения режима полного отображения адреса достаточно кликнуть правой кнопкой мыши по адресной строке и выбрать опцию Always show full URLs. После этого, Chrome всегда будет показывать полные URL-адреса веб-страниц, в том числе протокол и поддомены www или m.
 

hexin

Новичок
Сообщения
32
Репутация
0
Может кому будет полезно знать чтобы часами не разбираться как я, пока не понял в чем дело.
А дело в том, что если скачиваете Firefox любой версии то при получении ссылки из адресной строки по примеру Inni (см. выше) всё работает.
Но если ваш браузер обновился автоматически до последней версии то ссылка из адресной строки не считывается а вместо этого зависает скрипт и браузер и отключать всё это приходится через диспетчер задач.
Так что, чтобы скрипт работал, нельзя допускать автоматическое обновление браузера, а нужно скачивать ручками новую версию.
Вот такую закономерность обнаружил.
Кстати, на обычных версиях не знаю, а вот на портейбл именно так.
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
@hexin
У меня сейчас последняя версия 91.0.1 (не портабл). Оба кода работают.
Убедитесь в правильном названии строки адреса - её текст зависит от поиска по умолчанию (Google, Яндекс и т.д.)
Также, попробуйте после запуска Firefox вызвать функцию _FirefoxAccessInit
Сообщение автоматически объединено:

А если у вас открыто более двух вкладок с "длинными" страницами, то метод FindAll лучше не использовать.
 
Последнее редактирование:
Верх