Автор Тема: UIAutomate - автоматизация нестандартных элементов GUI  (Прочитано 51761 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3035
  • Репутация: 810
    • Награды
  • Версия AutoIt: 3.3.14.0
AutoIt: 3.3.10.0 +

Категория: Автоматизация, Элементы GUI

Описание:
Набор функций, расширяющий возможности AutoIt по работе с нестандартными элементами GUI. При помощи данных функций возможна автоматизация элементов таких классов, как DirectUIHWND, NetUIHWND, UIRibbonWorkPane, а также автоматизация таких программ, как Google Chrome, Mozilla Firefox, программ, написанных на Delphi и т.д.

Для получения информации об элементе потребуется утилита Inspect. Если данная утилита при запуске сообщает об ошибке, значит на компьютере не установлен API UIAutomation. На Windows 7 и выше данный API предустановлен, на Vista и XP нужно устанавливать отдельно отсюда.

Функции:
(нажмите для показа/скрытия)

Пример:
(нажмите для показа/скрытия)

Файл: Полный комплект

История версий:
(нажмите для показа/скрытия)

Источник: autoit-script.ru
Автор: InnI
« Последнее редактирование: Декабрь 27, 2016, 18:07:55 от InnI »

Русское сообщество AutoIt


Оффлайн Shinoby [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 2
  • Пол: Мужской
    • Награды
Возник вопрос относительно определения отцовства...  :stars:
правильно ли я понимаю, что если в Инспекторе написано "Container has no children" - то использовать поинтер на этот объект для поиска внутри - нет смысла - их просто нет?

собственно столкнулся с проблемой: в вин7 ие10 не могу получить характеристику в "Сервис" -> "Во весь экран F11"
последний элемент пробовал искать у разных родителей, но ничего не вышло.

в этом примере не могу найти поинтер на "Контекст"
Код: AutoIt [Выделить]
Opt("WinTitleMatchMode", 2)
$oIE = _IEAttach("", "instance")
$hwie = _IEPropertyGet($oIE, "hwnd")
;;ControlClick ($hwie, "",40960, "left", 1, 360, 10)

$oParent = _UIA_ElementFromHandle($hwie)
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Сервис")
_UIA_ElementMouseClick($oElement)

$oMenuPa = _UIA_WaitControlTypeElement($oElement, "UIA_WindowControlTypeId", "Контекст")
MsgBox(0,"error меню отец?",@error)
$oMenu = _UIA_WaitControlTypeElement($oMenuPa, "UIA_MenuControlTypeId", "Контекст")
MsgBox(0,"error меню",@error)
$oPunkt = _UIA_GetControlTypeElement($oMenu, "UIA_MenuItemControlTypeId", "Во весь экран F11")
MsgBox(0,"error пункт меню",@error)
If IsObj($oPunkt) Then
    MsgBox(0,"",_UIA_ElementGetPropertyValue ($oPunkt, "LegacyIAccessible.State:"))

EndIf


"Контекст" - это я уже брал инфу из дерева в Инспекторе - думал он папа... но у него так же написано что детей не имеет и пункт меню поймать немогу. :(

что я упустил?
« Последнее редактирование: Май 18, 2014, 23:55:58 от Shinoby »

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3035

  • Автор темы
  • Репутация: 810
    • Награды
  • Версия AutoIt: 3.3.14.0
Shinoby
Всплывающие меню - это особый класс окон #32768. Родитель у них - рабочий стол. Сами эти окна легко определяются по классу, поэтому проще всего работать с ними "напрямую".
(нажмите для показа/скрытия)

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3035

  • Автор темы
  • Репутация: 810
    • Награды
  • Версия AutoIt: 3.3.14.0
Переименовал функции:
Код: AutoIt [Выделить]
; _UIA_ElementFromHandle() -> _UIA_GetElementFromHandle()
; _UIA_ElementFromPoint() -> _UIA_GetElementFromPoint()

Версию не менял.


Добавлено: Май 23, 2014, 23:38:56
Были внесены изменения в CUIAutomation2.au3 (не мной). На работу UDF версии 1.0 не влияют. Но всё равно ссылку исправил, архив полного комплекта обновил.
« Последнее редактирование: Май 23, 2014, 23:38:56 от InnI, Причина: Объединение сообщений »

Русское сообщество AutoIt

Re: UIAutomate - автоматизация нестандартных элементов GUI
« Ответ #3 Отправлен: Май 23, 2014, 16:06:36 »

Оффлайн Shinoby [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 2
  • Пол: Мужской
    • Награды
возник вопрос по _UIA_ElementTextSetValue

Код: AutoIt [Выделить]
WinActivate("Skype")

$hwSk = WinWaitActive("Skype")
    $oParent = _UIA_ElementFromHandle($hwSk)
    $oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "TAccessibleEdit", "ClassName")
    _UIA_ElementSetFocus($oElement)
    Sleep(1000)
    _UIA_ElementTextSetValue($oElement, "имя в скайпе")


окошко поиска фокусится - но в него ничего не вводится.
это не проблема - можно найти нужный элемент в листе, но на вкладке контакта где пишешь текст - писать его так же не получается. ошибки - не выдает.

сейчас обнаружил что поиск элемента - был не удачный. вернулся к исходному варианту:
Код: AutoIt [Выделить]
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "Найти")

но с текстом так же проблемы....
« Последнее редактирование: Июнь 13, 2014, 17:53:34 от Shinoby »

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3035

  • Автор темы
  • Репутация: 810
    • Награды
  • Версия AutoIt: 3.3.14.0
Shinoby  [?]
Цитировать
но с текстом так же проблемы
Да, есть такое... Многие элементы, хоть и имеют шаблон ValuePattern, но не реагируют на команду установки текста. В таком случае можно сделать так
Код: AutoIt [Выделить]
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "Найти")
_UIA_ElementMouseClick($oElement)
Send("имя в скайпе")


К счастью в вашем случае всё намного проще - даже UDF не нужна
Код: AutoIt [Выделить]
ControlSetText("Skype", "", "TAccessibleEdit1", "имя в скайпе")


Оффлайн Shinoby [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 2
  • Пол: Мужской
    • Награды
да, с send как в примере - сделал. но не люблю его, очень не предсказуемо бывает.

а вот за ControlSetText - спасибо. чутка поломал голову над 1, но все остальное пошло как по маслу.  :beer:

Оффлайн Большой огурец [?]

  • Новичок
  • *
  • Сообщений: 3
  • Репутация: 0
    • Награды
  • Версия AutoIt: 3.3.12.0
А как получить новые не прочитанные сообщения и Skype? Сейчас старый API закрыт. Остается вот с окнами делать.

Русское сообщество AutoIt

Re: UIAutomate - автоматизация нестандартных элементов GUI
« Ответ #7 Отправлен: Сентябрь 13, 2014, 23:12:16 »

Оффлайн alex33 [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1348
  • Репутация: 166
  • Пол: Мужской
    • alekssamos ВКонтакте
    • Награды
  • Версия AutoIt: 3.3.12.0
Большой огурец  [?]
Цитировать
Сейчас старый API закрыт.
У меня новый скайп и ничего не закрыто, всё работает...

Оффлайн Большой огурец [?]

  • Новичок
  • *
  • Сообщений: 3
  • Репутация: 0
    • Награды
  • Версия AutoIt: 3.3.12.0
Большой огурец  [?]
Цитировать
Сейчас старый API закрыт.
У меня новый скайп и ничего не закрыто, всё работает...
Skype еще в прошлом году всех уведомил о закрытии Desktop API по идее работать не должен уже? Поэтому ищу способ без него.

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3035

  • Автор темы
  • Репутация: 810
    • Награды
  • Версия AutoIt: 3.3.14.0
Большой огурец  [?]
Цитировать
получить новые не прочитанные сообщения из Skype
Получить можно только все сообщения. Далее можно сравнить с количеством предыдущих - разница и есть новые.
Код: AutoIt [Выделить]
#include "UIAutomate.au3"
$oWnd = _UIA_GetElementFromHandle(WinGetHandle("Skype"))
$oList = _UIA_GetControlTypeElement($oWnd, "UIA_ListControlTypeId", "Содержимое чата")
$aList = _UIA_FindAllElements($oList, $UIA_ControlTypePropertyId, $UIA_ListItemControlTypeId)
For $i = 1 To $aList[0]
  ConsoleWrite(_UIA_ElementGetPropertyValue($aList[$i], "Name") & @CRLF)
Next


Такой ещё вариант - через буфер обмена
Код: AutoIt [Выделить]
$i = 0
Do
  $i += 1
  $hChat = ControlGetHandle("Skype", "", "TChatContentControl" & $i)
Until ControlCommand("Skype", "", $hChat, "IsVisible")
ControlFocus("Skype", "", $hChat)
ControlSend("Skype", "", $hChat, "^a")
ControlSend("Skype", "", $hChat, "^{ins}")
ConsoleWrite(ClipGet() & @CRLF)


Оффлайн coolpunk [?]

  • Новичок
  • *
  • Сообщений: 7
  • Репутация: 2
    • Награды
Возможно данный вопрос не к вам, но вдруг кто столкнется. Почему-то Au3Stripper упорно вырезает функцию _UIA_FindElementsInArray(), даже если она используется, другие оставляет.
Помогает только
Код: AutoIt [Выделить]
#Au3Stripper_Off
#include <UIAutomate.au3>
#Au3Stripper_On


Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3035

  • Автор темы
  • Репутация: 810
    • Награды
  • Версия AutoIt: 3.3.14.0
coolpunk  [?]
Цитировать
упорно вырезает функцию _UIA_FindElementsInArray()
Давайте разбираться на примере. Ищем названия пунктов меню рабочего стола, содержащие подстроку "ов" (для русской Win7 это "Сортировка" и "Обновить")
Код: AutoIt [Выделить]
#AutoIt3Wrapper_Run_Au3Stripper=y
#include "UIAutomate.au3"
MouseClick("right", 0, 0, 1, 0)
$oParent = _UIA_GetElementFromHandle(WinWait("[class:#32768]"))
$oItems = _UIA_FindAllElements($oParent, $UIA_ControlTypePropertyId, $UIA_MenuItemControlTypeId)
$oArray = _UIA_FindElementsInArray($oItems, $UIA_NamePropertyId, "ов", True)
$str = ""
For $i = 1 To $oArray[0]
  $str &= _UIA_ElementGetPropertyValue($oArray[$i], $UIA_NamePropertyId) & @CRLF
Next
MsgBox(0, "", $str)

После компиляции в папке скрипта получим файл ScriptName_stripped.au3. Открываем его в SciTE и видим функцию _UIA_FindElementsInArray(), т.е. она НЕ вырезана. Запускаем на выполнение - скрипт работает. Скомпилированный также работает. НО... Если изменить скрипт следующим образом
Код: AutoIt [Выделить]
...
$oArray = _UIA_FindElementsInArray($oItems, "name", "ов", True)
$str = ""
For $i = 1 To $oArray[0]
  $str &= _UIA_ElementGetPropertyValue($oArray[$i], "name") & @CRLF
Next
...

и запустить "урезанный" вариант, то получим ошибку "C:\Scripts\test_stripped.au3" (148) : ==> Subscript used on non-accessible variable.:
For $i = 1 To $oArray[0]
For $i = 1 To $oArray^ ERROR
Дело в том, что в UDF преобразование строки "name" в идентификатор свойства $UIA_NamePropertyId происходит в функции __UIA_GetPropIdFromStr(), а константа $UIA_NamePropertyId вырезана стриппером, т.к. не используется. В результате _UIA_FindElementsInArray() возвращает ошибку №6 (неизвестный идентификатор свойства), что и приводит к проблемам.
« Последнее редактирование: Декабрь 02, 2014, 00:10:58 от InnI »

Оффлайн coolpunk [?]

  • Новичок
  • *
  • Сообщений: 7
  • Репутация: 2
    • Награды
Спасибо за разъяснения, я так глубоко не вникал.
Отличный набор функций, только мне не хватило методов "NextChild" и "PreviousChild" для моей задачи, приходится использовать так:
Код: AutoIt [Выделить]
    $oParent = _UIA_GetElementFromHandle($handle)
    $aAllElements = _UIA_FindAllElements($oParent)
    Local $sTime, $sName
    For $i = 1 To $aAllElements[0]
        If _UIA_ElementGetPropertyValue($aAllElements[$i], "Name") = "Начало через" Then
            $sName = _UIA_ElementGetPropertyValue($aAllElements[$i-1], "Name")
            $sTime = _UIA_ElementGetPropertyValue($aAllElements[$i+1], "Name")
            ExitLoop
        EndIf
    Next
 

Возможно, проще и не сделать.

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3035

  • Автор темы
  • Репутация: 810
    • Награды
  • Версия AutoIt: 3.3.14.0
coolpunk  [?]
Цитировать
не хватило методов "NextChild" и "PreviousChild"
Функция возвращает массив: $aArray[0] - предыдущий элемент (объект), $aArray[1] - следующий элемент (объект).
Если предыдущий/следующий элемент отсутствует, то соответствующим элементом массива будет НЕ объект.
Код: AutoIt [Выделить]
Func _UIA_ElementGetPreviousNext($oElement)
  If Not IsObj($oElement) Then Return SetError(1, 0, 0)
  Local $aPrevNext[2], $pPrevNext, $pRawWalker, $oRawWalker, $oUIAutomation = _UIA_ObjectCreate()
  $oUIAutomation.RawViewWalker($pRawWalker)
  $oRawWalker = ObjCreateInterface($pRawWalker, $sIID_IUIAutomationTreeWalker, $dtagIUIAutomationTreeWalker)
  If Not IsObj($oRawWalker) Then Return SetError(2, 0, 0)
  $oRawWalker.GetPreviousSiblingElement($oElement, $pPrevNext)
  $aPrevNext[0] = ObjCreateInterface($pPrevNext, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
  $oRawWalker.GetNextSiblingElement($oElement, $pPrevNext)
  $aPrevNext[1] = ObjCreateInterface($pPrevNext, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
  Return $aPrevNext
EndFunc


Русское сообщество AutoIt

Re: UIAutomate - автоматизация нестандартных элементов GUI
« Ответ #14 Отправлен: Декабрь 02, 2014, 16:52:16 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
0 Ответов
25566 Просмотров
Последний ответ Сентябрь 22, 2010, 22:13:33
от CreatoR
18 Ответов
11007 Просмотров
Последний ответ Сентябрь 18, 2011, 20:49:26
от Zalman1980
0 Ответов
2415 Просмотров
Последний ответ Ноябрь 20, 2011, 19:11:43
от ohos
9 Ответов
4305 Просмотров
Последний ответ Март 12, 2012, 00:33:05
от cobra2029
0 Ответов
1641 Просмотров
Последний ответ Май 07, 2012, 15:00:44
от Dedullika
18 Ответов
3706 Просмотров
Последний ответ Октябрь 17, 2012, 00:07:30
от Kaster
0 Ответов
1602 Просмотров
Последний ответ Декабрь 02, 2012, 10:15:22
от madmasles
6 Ответов
2758 Просмотров
Последний ответ Декабрь 10, 2012, 11:30:14
от Zergii
3 Ответов
1440 Просмотров
Последний ответ Декабрь 21, 2014, 19:24:21
от brain
8 Ответов
1514 Просмотров
Последний ответ Ноябрь 26, 2015, 17:54:56
от Garrett