Что нового

[Автоматизация] DoDefaultAction - управление нестандартными элементами GUI

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
AutoIt: не ниже 3.3.10.0
Версия: 1.0
Категория: Автоматизация
Описание:
Практически у всех элементов GUI есть так называемое "действие по умолчанию" (default action). Узнать, какое действие выполняет элемент по умолчанию, можно кликнув по нему мышкой (за редким исключением). Так, кнопка "нажимается", ссылка "переходится", переключатель "устанавливается", а пункт меню "выполняется". Представленная вашему вниманию функция как раз и способствует выполнению элементом своего действия по умолчанию. А так как данная функция использует API UI Automation, то можно управлять как стандартными, так и нестандартными элементами GUI.

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

Прототип функции:
Код:
_DoDefaultAction($hWindow, $ControlTypeId, $Value, $PropertyId = Default, $InStr = False)


Первый параметр - это дескриптор элемента-контейнера, содержащего нужный нам элемент. Конечно, элементом-контейнером может быть и главное окно, но чем ближе мы будем к нужному элементу, тем точнее и быстрее будет поиск.
Второй параметр - это идентификатор типа элемента. Где его взять? После запуска Inspect и наведения курсора на нужный нам элемент, в списке утилиты отобразятся свойства элемента (слева) и значения свойств (справа). Нам нужно значение свойства ControlType. Чтобы превратить это значение в константу, нужно добавить $ и убрать числовой идентификатор: UIA_ButtonControlTypeId (0xC350) -> $UIA_ButtonControlTypeId, UIA_MenuItemControlTypeId (0xC35B) -> $UIA_MenuItemControlTypeId и т.д. Кстати, можно использовать и сам числовой идентификатор вместо описания константы.
Третий параметр - это значение свойства, которое выводится в правой части списка Inspect.
Четвёртый параметр - это идентификатор свойства. Как его получить? В левой части списка Inspect указаны свойства. Кроме первого "How found" и нескольких последних все остальные можно использовать. Для этого добавляем в начале $UIA_ , в конце PropertyId и убираем точку, если она есть: Name -> $UIA_NamePropertyId, LegacyIAccessible.ChildId -> $UIA_LegacyIAccessibleChildIdPropertyId, LegacyIAccessible.Name -> $UIA_LegacyIAccessibleNamePropertyId и т.д. По умолчанию поиск производится по значению свойства $UIA_NamePropertyId (см. "Name" в Inspect).
Пятый параметр - это переключатель полного или частичного совпадения поиска. По умолчанию - полное совпадение без учёта регистра.
Примечание: все константы (второй и четвёртый параметры) находятся в UDF CUIAutomation2.au3

Пример с пояснениями: нажатие кнопки WordPad, отвечающей за выравнивание текста по центру (Windows 7).
1. При помощи AutoIt Window Info находим элемент-контейнер: [CLASS:NetUIHWND; INSTANCE:1]
2. Запускаем Inspect, наводим курсор на кнопку. В списке находим ControlType: UIA_ButtonControlTypeId (0xC350) и преобразуем в константу: $UIA_ButtonControlTypeId
3. В списке Inspect находим Name: "Выровнять текст по центру". Это имя и будем использовать для поиска. А так как имя - это идентификатор по умолчанию, то преобразование в константу (Name -> $UIA_NamePropertyId) не требуется.
4. Пишем скрипт
Код:
#include "CUIAutomation2.au3"
$hCtrl = ControlGetHandle("[class:WordPadClass]", "", "NetUIHWND1")
_DoDefaultAction($hCtrl, $UIA_ButtonControlTypeId, "Выровнять текст по центру")

Пример: нажатие ссылки "AutoIt для новичков" в IE10 на открытой странице http://autoit-script.ru/ при частичном совпадении с использованием числового идентификатора типа элемента
Код:
#include "CUIAutomation2.au3"
$hWnd = WinGetHandle("[class:IEFrame]")
_DoDefaultAction($hWnd, 0xC364, "для новичков", Default, True) ; UIA_TextControlTypeId

Замечание:
Действие по умолчанию работает в неактивных окнах и часто (но не всегда) в свёрнутых.

И, наконец, код функции:
Код:
Func _DoDefaultAction($hWindow, $ControlTypeId, $Value, $PropertyId = Default, $InStr = False)

  If Not IsHWnd($hWindow) Then Return SetError(1, 0, 0)
  If $PropertyId = Default Then $PropertyId = $UIA_NamePropertyId

  ; Создание объекта UI Automation
  Local $oUIAutomation = ObjCreateInterface($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation)
  If Not IsObj($oUIAutomation) Then Return SetError(2, 0, 0)

  ; Создание элемента UI Automation
  Local $pWindow, $oWindow
  $oUIAutomation.ElementFromHandle($hWindow, $pWindow)
  $oWindow = ObjCreateInterface($pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
  If Not IsObj($oWindow) Then Return SetError(3, 0, 0)

  ; Создание условий поиска
  Local $pCondition
  $oUIAutomation.CreatePropertyCondition($UIA_ControlTypePropertyId, $ControlTypeId, $pCondition)
  If Not $pCondition Then Return SetError(4, 0, 0)

  ; Создание массива элементов
  Local $pUIElementArray, $oUIElementArray, $iElements
  $oWindow.FindAll($TreeScope_Descendants, $pCondition, $pUIElementArray)
  $oUIElementArray = ObjCreateInterface($pUIElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray)
  $oUIElementArray.Length($iElements)
  If Not $iElements Then Return SetError(5, 0, 0)

  ; Поиск элемента по свойству
  Local $pUIElement, $oUIElement, $ValuePropId
  For $i = 0 To $iElements - 1
    $oUIElementArray.GetElement($i, $pUIElement)
    $oUIElement = ObjCreateInterface($pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
    $oUIElement.GetCurrentPropertyValue($PropertyId, $ValuePropId)
    If $InStr Then
      If StringInStr($ValuePropId, $Value) Then ExitLoop
    Else
      If $ValuePropId = $Value Then ExitLoop
    EndIf
  Next
  If $i = $iElements Then Return SetError(6, 0, 0)

  ; Применение действия к элементу
  Local $pIAccess, $oIAccess
  $oUIElement.GetCurrentPattern($UIA_LegacyIAccessiblePatternId, $pIAccess)
  $oIAccess = ObjCreateInterface($pIAccess, $sIID_IUIAutomationLegacyIAccessiblePattern, $dtagIUIAutomationLegacyIAccessiblePattern)
  If Not IsObj($oIAccess) Then Return SetError(7, 0, 0)
  $oIAccess.DoDefaultAction()

  Return 1

EndFunc

Источники:
Источник вдохновения: http://www.autoitscript.com/forum/topic/153520-iuiautomation-ms-framework-automate-chrome-ff-ie
Пример, взятый за основу: http://www.autoitscript.com/forum/topic/160519-click-on-item-of-a-standard-context-menu/?p=1165367
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Дальнейшие исследования функционала UIAutomation привели к созданию UDF UIAutomate, в которой также присутствует задание элементу действия по умолчанию.
 
Верх