Что нового

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

Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
SuperSonic
Проблема некорректной работы с координатами при изменении DPI - это не проблема данной UDF. Это проблема AutoIt. Для правильной работы добавьте в начало скрипта
Код:
DllCall("User32.dll", "bool", "SetProcessDPIAware")


Теперь по поводу Inspect. Проверьте её работу на рабочем столе, в блокноте, калькуляторе, IE... а затем в Chrome. Почувствуйте разницу ;)
Чтобы Chrome корректно возвращал координаты элементов, его нужно запускать с параметром
Код:
--force-device-scale-factor=1
 

SuperSonic

Новичок
Сообщения
25
Репутация
1
Благодарю с ответом, буду тестить )


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

Такой вопрос. Мне нужно дождаться отображения элемента используя только такой параметр - LegacyIAccessible.Role: dialog (0x12) и вот что-то не пойму ф-я _UIA_WaitControlTypeElement годится для этого или нет? Ей нужно передать параметр $vControlType, а у элемента такой параметр, судя по тому, что показывает Inspect, нет.


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

А все сам разобрался:
Код:
Local $condition = _UIA_CreatePropertyCondition("LegacyIAccessible.Role", 18)
_UIA_WaitElementFromCondition($obj_h, $condition, Default, 20)
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Переименовал три константы.
Было
Код:
Global Const $Off = 0
Global Const $Polite = 1
Global Const $Assertive = 2

Стало
Код:
Global Const $LiveSetting_Off = 0
Global Const $LiveSetting_Polite = 1
Global Const $LiveSetting_Assertive = 2

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

Radik

Новичок
Сообщения
71
Репутация
1
Я уже писал про таблицу, где все строки - дети. Строк 100 шт., хочу их собрать в массив:
Код:
#include <UIAutomate.au3>

$hWnd = WinActivate("Программа")
$oParent = _UIA_GetElementFromHandle($hWnd)
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_TableControlTypeId", "ultraGrid1")
$oAllElements = _UIA_FindAllElementsEx($oElement, Default, $TreeScope_Children)

Нажимаю F5, скрипт вылетает с ошибкой:
>"C:\Program Files (x86)\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "D:\AutoIt\001.au3"

!> _UIA_FindAllElementsEx : ошибка создания объекта массива
!> _UIA_FindAllElements : ошибка создания массива элементов (объектов)
!> _UIA_GetControlTypeElement : ошибка создания массива элементов (объектов)
!> _UIA_FindAllElementsEx : первый параметр не является объектом
"D:\AutoIt\001.au3" (14) : ==> Subscript used on non-accessible variable.:
For $i = 4 To $oAllElements[0] - 1
For $i = 4 To $oAllElements^ ERROR
>Exit code: 1 Time: 5.082
Не пойму, массив из 100 строк!!!
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Radik [?]
массив из 100 строк
До массива вы не доходите. У вас не создаётся $oElement. Подозреваю, что "ultraGrid1" - это не имя таблицы.


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

Попробуйте этот код
Код:
#include <UIAutomate.au3>

$hWnd = WinActivate("Программа")
$oParent = _UIA_GetElementFromHandle($hWnd)
$oCond1 = _UIA_CreatePropertyCondition("Name", "ultraGrid1")
$oCond2 = _UIA_CreatePropertyCondition("ControlType", $UIA_TableControlTypeId)
$oCond = _UIA_CreateLogicalCondition($oCond1, "AND", $oCond2)
$oElement = _UIA_GetElementFromCondition($oParent, $oCond)
If IsObj($oElement) Then ConsoleWrite("Найден" & @CRLF)
Если напишет ошибку 0х80004005, то ничего сделать не получится. Слишком большое количество элементов в окне.
 

Radik

Новичок
Сообщения
71
Репутация
1
InnI сказал(а):
Radik [?]
массив из 100 строк
До массива вы не доходите. У вас не создаётся $oElement. Подозреваю, что "ultraGrid1" - это не имя таблицы.


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

Попробуйте этот код
Код:
#include <UIAutomate.au3>

$hWnd = WinActivate("Программа")
$oParent = _UIA_GetElementFromHandle($hWnd)
$oCond1 = _UIA_CreatePropertyCondition("Name", "ultraGrid1")
$oCond2 = _UIA_CreatePropertyCondition("ControlType", $UIA_TableControlTypeId)
$oCond = _UIA_CreateLogicalCondition($oCond1, "AND", $oCond2)
$oElement = _UIA_GetElementFromCondition($oParent, $oCond)
If IsObj($oElement) Then ConsoleWrite("Найден" & @CRLF)
Если напишет ошибку 0х80004005, то ничего сделать не получится. Слишком большое количество элементов в окне.




Спасибо! Помогло!
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Убрал лишнее создание объекта UIAutomation в функции _UIA_FindAllElements (соответственно и вывод ошибки).
Версию не менял.
 

Hikari

Новичок
Сообщения
22
Репутация
0
Inni, в функции _UIA_FindAllElements создается по два объекта для каждой ссылки
Вот простенький код для проверки в уже запущенном браузере с нужными ключами
Код:
Func Check()
MsgBox(0,"","check")
;WaitFullLoad()
Local $testarray = _UIA_FindAllElements($BROWSER,"ControlType",50005)
For $in = 1 to $testarray[0]
MsgBox(0,"",_UIA_ElementGetPropertyValue($testarray[$in],"Name"))
Next



EndFunc

на любом html-файле(даже на составленном мной лично) выдает по два раза каждую ссылку
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Hikari [?]
создается по два объекта для каждой ссылки
Искать нужно не от главного окна, а от элемента отображения страницы
Код:
$BROWSER = _UIA_GetElementFromHandle(ControlGetHandle("[RegexpTitle: - Opera]", "", "Chrome_RenderWidgetHostHWND1"))
Check()
 

Hikari

Новичок
Сообщения
22
Репутация
0
Скажите, пожалуйста, как сделать функцию , которая будет дожидаться полной прогрузки страницы в браузере?
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Если содержимое страницы известно, то ждать последнего элемента. В противном случае, можно отслеживать изменения кнопки "обновить/остановить" в панели браузера.
 

tryinfinity

Новичок
Сообщения
40
Репутация
0
Столкнулся с проблемой, Inspect не видит в приложении объекты, пишет "Отказано в доступе".
hWnd находится, но даже Send("{ENTER}") не работает.
Может кто сталкивался с подобным?
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
tryinfinity [?]
пишет "Отказано в доступе"
Вероятно, приложение запущено с правами администратора. Если так, то и Inspect и скрипт должны иметь такие же права.
 

roma351234567890

Новичок
Сообщения
20
Репутация
0
Имеется вот такой элемент меню, как по нему кликнуть, и вообще, реально ли это? Родительский, дочерний элемент не обнаружен.


How found: Focus [o:0xFFFFFFFC,c:0x1]
hwnd=0x033602E8 32bit class="TCustomActionPopupMenuEx" style=0x96000000 ex=0x10088
ChildId: 0
Interfaces:
Impl: Remote native IAccessible
Name: "[LG] webOS TV LJ594V - [192.168.1.105:1152]"
Value: [null]
Role: элемент меню (0xC)
State: с фокусом ввода,фокусируемое (0x100004)
Location: {l:961, t:947, w:300, h:21}
Selection: [Error: calling getter for this property: hr=0x80020003 - Член группы не найден.]
Description: "[LG] webOS TV LJ594V - [192.168.1.105:1152] menu"
Kbshortcut: [null]
DefAction: [Error: hr=0x80020003 - Член группы не найден.]
Help: [Error: hr=0x80020003 - Член группы не найден.]
HelpTopic: ""
ChildCount: 0
Window: 0x33602E8
FirstChild: [Error: hr=0x80020003 - Член группы не найден.]
LastChild: [Error: hr=0x80020003 - Член группы не найден.]
Next: [Error: hr=0x80020003 - Член группы не найден.]
Previous: [Error: hr=0x80020003 - Член группы не найден.]
Left: [Error: hr=0x80020003 - Член группы не найден.]
Up: [Error: hr=0x80020003 - Член группы не найден.]
Right: [Error: hr=0x80020003 - Член группы не найден.]
Down: [Error: hr=0x80020003 - Член группы не найден.]
Other Props: Object has no additional properties
Children: Container has no children
Ancestors: none : строка меню : с фокусом ввода,фокусируемое
[ No Parent ]


How found: Mouse move (1002,964)
hwnd=0x030F03A8 32bit class="TCustomActionPopupMenuEx" style=0x96000000 ex=0x10088
RuntimeId: "[42.51315624]"
BoundingRectangle: {l:959 t:945 r:1263 b:994}
ProcessId: 1900
ControlType: UIA_PaneControlTypeId (0xC371)
LocalizedControlType: "панель"
Name: ""
AccessKey: ""
HasKeyboardFocus: false
IsKeyboardFocusable: true
IsEnabled: true
ClassName: "TCustomActionPopupMenuEx"
HelpText: ""
IsPassword: false
NativeWindowHandle: 0x30F03A8
IsOffscreen: false
FrameworkId: "Win32"
ProviderDescription: "[pid:5088,hwnd:0x30F03A8 Main:Nested [pid:1900,hwnd:0x30F03A8 Annotation(parent link):Microsoft: Annotation Proxy (unmanaged:uiautomationcore.dll); Main:Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]; Nonclient:Microsoft: Non-Client Proxy (unmanaged:uiautomationcore.dll); Hwnd(parent link):Microsoft: HWND Proxy (unmanaged:uiautomationcore.dll)]"
IsDockPatternAvailable: false
IsExpandCollapsePatternAvailable: false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable: false
IsMultipleViewPatternAvailable: false
IsRangeValuePatternAvailable: false
IsScrollPatternAvailable: false
IsScrollItemPatternAvailable: false
IsSelectionItemPatternAvailable: false
IsSelectionPatternAvailable: false
IsTablePatternAvailable: false
IsTableItemPatternAvailable: false
IsTextPatternAvailable: false
IsTogglePatternAvailable: false
IsTransformPatternAvailable: false
IsValuePatternAvailable: false
IsWindowPatternAvailable: false
IsItemContainerPatternAvailable: false
IsVirtualizedItemPatternAvailable: false
FirstChild: [null]
LastChild: [null]
Next: "Inspect (HWND: 0x020F03A2)" окно
Previous: [null]
Other Props: Object has no additional properties
Children: Container has no children
Ancestors: "Рабочий стол" панель
[ No Parent ]
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
roma351234567890 [?]
Имеется вот такой элемент меню
UIA_PaneControlTypeId - это панель, просто вы воспринимаете её, как меню. А кликать в панель можно по координатам. Т.к. у этого элемента есть класс (TCustomActionPopupMenuEx), то можно попробовать ControlClick (информацию смотрите в Au3Info). Но если вам нужно через UIAutomate, то попробуйте так
Код:
#include <UIAutomate.au3>

; координаты относительно левого верхнего угла панели
Global $X = 100, $Y = 10

; дескриптор панели меню - данные получаем из Au3Info
$hCtrl = WinGetHandle("[class:TCustomActionPopupMenuEx]")
; $hCtrl = ControlGetHandle("Заголовок окна", "", "TCustomActionPopupMenuEx1")

; элемент на основе дескриптора панели
$oPanel = _UIA_GetElementFromHandle($hCtrl)

; клик по координатам панели
_UIA_ElementMouseClick($oPanel, "", $X, $Y)
 

roma351234567890

Новичок
Сообщения
20
Репутация
0
Мне нужно вывести значение 188.225.7.119, оно может быть разным. То есть нужно вывести как-то массив на фильтр, либо подобрать по предыдущему элементу массива, но не знаю, как собственно этот массив вывести.
How found: Mouse move (892,452)
hwnd=0x00650362 32bit class="Internet Explorer_Server" style=0x56000000 ex=0x0
BoundingRectangle: {l:850 t:441 r:929 b:456}
ProcessId: 3724
ControlType: UIA_EditControlTypeId (0xC354)
LocalizedControlType: поле
Name: 188.225.7.119
AccessKey:
HasKeyboardFocus: false
IsKeyboardFocusable: false
IsEnabled: true
IsPassword: false
IsOffscreen: false
ProviderDescription: [pid:3724,hwnd:0x0 Main(parent link):Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]
Value.IsReadOnly: true
IsDockPatternAvailable: false
IsExpandCollapsePatternAvailable: false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable: false
IsMultipleViewPatternAvailable: false
IsRangeValuePatternAvailable: false
IsScrollPatternAvailable: false
IsScrollItemPatternAvailable: false
IsSelectionItemPatternAvailable: false
IsSelectionPatternAvailable: false
IsTablePatternAvailable: false
IsTableItemPatternAvailable: false
IsTextPatternAvailable: false
IsTogglePatternAvailable: false
IsTransformPatternAvailable: false
IsValuePatternAvailable: true
IsWindowPatternAvailable: false
IsItemContainerPatternAvailable: false
IsVirtualizedItemPatternAvailable: false
FirstChild: [null]
LastChild: [null]
Next: [null]
Previous: [null]
Other Props: Object has no additional properties
Children: Container has no children
Ancestors:
таблицу
ADSL Router Status панель

Router панель
панель
панель
панель
Веб-браузер своими руками окно
Рабочий стол панель
[ No Parent ]
 
Автор
I

InnI

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

$oParent = _UIA_GetElementFromHandle(ControlGetHandle("[class:IEFrame]", "", "Internet Explorer_Server1"))

; если элемент один
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", True, "Value.IsReadOnly")
ConsoleWrite(_UIA_ElementGetPropertyValue($oElement, "Name") & @CRLF)

; если элементов несколько, то найдите его по индексу
$aElems = _UIA_FindAllElements($oParent, "ControlType", $UIA_EditControlTypeId)
For $i = 1 To $aElems[0]
  ConsoleWrite(_UIA_ElementGetPropertyValue($aElems[$i], "Name") & @CRLF)
Next
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
Узнал программный способ включения доступа к содержимому страниц Google Chrome для работы с IUIAutomation. Способ заключается в отправке элементу отображения страницы специального сообщения, при получении которого Google Chrome включает доступ к содержимому всех страниц (в том числе уже открытых). Фактически работает аналогично запуску с параметром --force-renderer-accessibility
Код:
#include <SendMessage.au3>
#include <WindowsConstants.au3>

$hWnd = ControlGetHandle("[RegexpTitle: - Google Chrome]", "", "Chrome_RenderWidgetHostHWND1")
_SendMessage($hWnd, $WM_GETOBJECT, 0, 1)


Как вариант, можно отправлять данное сообщение "по запросу". Дело в том, что Google Chrome при запуске и при открытии новой вкладки рассылает системное уведомление EVENT_SYSTEM_ALERT, в ответ на которое и отправляется сообщение о включении доступа к содержимому страниц. Если Google Chrome уже работает в режиме доступа, то уведомление рассылаться не будет
Код:
#include <WinAPISys.au3>

OnAutoItExitRegister("__UIA_Answer_OnAutoItExit")

Global $UIA_AnswerEventProc = DllCallbackRegister("__UIA_AnswerEventProc", "none", "ptr;dword;hwnd;long;long;dword;dword")
Global $UIA_AnswerEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_ALERT, $EVENT_SYSTEM_ALERT, DllCallbackGetPtr($UIA_AnswerEventProc))

Func __UIA_AnswerEventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadID, $iEventTime)
  If $iEvent = $EVENT_SYSTEM_ALERT And $iObjectID = 1 Then _SendMessage($hWnd, 0x003D, 0, 1) ; $WM_GETOBJECT = 0x003D
EndFunc  ;==> __UIA_AnswerEventProc

Func __UIA_Answer_OnAutoItExit()
  _WinAPI_UnhookWinEvent($UIA_AnswerEventHook)
  DllCallbackFree($UIA_AnswerEventProc)
EndFunc  ;==> __UIA_AnswerOnAutoItExit
Данный код можно добавить в начало скрипта или подключить, как UDF.

Проверено на Google Chrome 67, запущенном без параметра --force-renderer-accessibility. С большой долей вероятности будет работать и в других chromium-based браузерах и приложениях.
 
Верх