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

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

Оффлайн InnI [?]

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

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

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

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

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

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

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

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

Источник: autoit-script.ru
Автор: InnI
« Последнее редактирование: Вчера в 12:59:16 от 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 Гуру
  • *****
  • Сообщений: 3332

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

Оффлайн InnI [?]

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

  • Автор темы
  • Репутация: 875
    • Награды
  • Версия 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 Гуру
  • *****
  • Сообщений: 3332

  • Автор темы
  • Репутация: 875
    • Награды
  • Версия 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 Гуру
  • *****
  • Сообщений: 1359
  • Репутация: 170
  • Пол: Мужской
    • alekssamos ВКонтакте
    • Награды
  • Версия AutoIt: 3.3.12.0
Большой огурец  [?]
Цитировать
Сейчас старый API закрыт.
У меня новый скайп и ничего не закрыто, всё работает...

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

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

Оффлайн InnI [?]

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

  • Автор темы
  • Репутация: 875
    • Награды
  • Версия 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 Гуру
  • *****
  • Сообщений: 3332

  • Автор темы
  • Репутация: 875
    • Награды
  • Версия 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 Гуру
  • *****
  • Сообщений: 3332

  • Автор темы
  • Репутация: 875
    • Награды
  • Версия 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 Ответов
50625 Просмотров
Последний ответ Сентябрь 22, 2010, 22:13:33
от CreatoR
18 Ответов
12056 Просмотров
Последний ответ Сентябрь 18, 2011, 20:49:26
от Zalman1980
9 Ответов
4843 Просмотров
Последний ответ Март 12, 2012, 00:33:05
от cobra2029
0 Ответов
1778 Просмотров
Последний ответ Май 07, 2012, 15:00:44
от Dedullika
18 Ответов
4285 Просмотров
Последний ответ Октябрь 17, 2012, 00:07:30
от Kaster
0 Ответов
1796 Просмотров
Последний ответ Декабрь 02, 2012, 10:15:22
от madmasles
6 Ответов
3031 Просмотров
Последний ответ Декабрь 10, 2012, 11:30:14
от Zergii
3 Ответов
1690 Просмотров
Последний ответ Декабрь 21, 2014, 19:24:21
от brain
8 Ответов
1857 Просмотров
Последний ответ Ноябрь 26, 2015, 17:54:56
от Garrett
22 Ответов
1590 Просмотров
Последний ответ Июнь 09, 2017, 01:12:34
от Alofa