Что нового

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

lettterssino

Знающий
Сообщения
109
Репутация
10
Код:
_UIA_ElementDoDefaultAction()



Интерфейс UIAutomation не работает со скрытыми элементами. Он их просто не находит.
Я не так выразился, неактивный сеанс пользователя, в этом случае любые маусклики не работают, а первая функция почему то не делает клики, а лишь завершается со статусом 0.
Код:
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "|LongDelayItem_NewItemButton", "AutomationId")
_UIA_ElementDoDefaultAction($oElement)

Или может я не так что-то делаю, хочу сделать нажатие элемента, но без команды
Код:
_UIA_ElementMouseClick($oElement)

А вот весь кусок кода может так легче будет понять
Код:
Run(@ComSpec & " /c " & $Dir, "", @SW_HIDE)
$ssc = WinWait($DistroTitle, 'mdihost')
$hwie = WinGetHandle($ssc)
$oParent = _UIA_GetElementFromHandle($hwie)

_UIA_WaitControlTypeElement($oParent, "UIA_MenuItemControlTypeId", "Файл", "LegacyIAccessible.Name", "", 60)

$oElement = _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "|LongDelayItem_NewItemButton", "AutomationId")
_UIA_ElementDoDefaultAction($oElement)
;_UIA_ElementMouseClick($oElement)

_UIA_WaitControlTypeElement($oParent, "UIA_MenuItemControlTypeId", "Чертеж", "LegacyIAccessible.Name", "", 45)

$oElement = _UIA_GetControlTypeElement($oParent, "UIA_MenuItemControlTypeId", "Чертеж")
_UIA_ElementMouseClick($oElement)
 
Последнее редактирование:
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
неактивный сеанс пользователя
Вы имеете в виду подключение по RDP с последующим закрытием окна RDP? То есть аналог блокировки по Win+L?
Если да, то я проверил DoDefaultAction в блокноте на заблокированном компьютере. Работает без проблем.
К тому же вы пишите, что "завершается со статусом 0". Следовательно, метод отрабатывает без ошибок. Вероятно, сам контрол не реагирует.

Попробуйте эту функцию. Аналог DoDefaultAction уровнем выше. Но она у меня зависает при заблокированном компьютере. Вероятно из-за того, что пытается активировать окно.
Код:
Func _UIA_ElementInvoke($oElement)
  If Not IsObj($oElement) Then Return SetError(1, __UIA_ConsoleWriteError("_UIA_ElementInvoke : параметр не является объектом"), 0)
  Local $pInvoke, $oInvoke
  $oElement.GetCurrentPattern($UIA_InvokePatternId, $pInvoke)
  $oInvoke = ObjCreateInterface($pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern)
  If Not IsObj($oInvoke) Then Return SetError(2, __UIA_ConsoleWriteError("_UIA_ElementInvoke : ошибка создания объекта на основе шаблона Invoke"), 0)
  Local $iErrorCode = $oInvoke.Invoke()
  If $iErrorCode Then Return SetError(3, __UIA_ConsoleWriteError("_UIA_ElementInvoke : ошибка выполнения метода (0x" & Hex($iErrorCode) & ")"), 0)
  Return 1
EndFunc ; _UIA_ElementInvoke
 

SharkyEXE

Новичок
Сообщения
134
Репутация
0
Всем здравствуйте.

Пожалуйста, научите, как сделать "один раз щелчок левой кнопкой мышки" на таком элементе

Этот текст получен утилитой Inspect_W7.exe

Спасибо.
 

Вложения

  • Info.txt
    2.2 КБ · Просмотры: 9
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
"один раз щелчок левой кнопкой мышки" на таком элементе
Я так понимаю - это включение/отключение защиты? Если да, то так
Код:
#include <UIAutomate.au3>
$hWnd = WinGetHandle("AdGuard")
WinSetState($hWnd, "", @SW_RESTORE)
WinMove($hWnd, "", Default, Default, 840, 640)
$oParent = _UIA_GetElementFromHandle($hWnd)
$oElem = _UIA_GetControlTypeElement($oParent, "UIA_CustomControlTypeId", "InnerDialogContent", "ClassName")
_UIA_ElementMouseClick($oElem, "", 430, 150)
 

SharkyEXE

Новичок
Сообщения
134
Репутация
0

[B]InnI[/B]


Здравствуйте

Я так понимаю - это включение/отключение защиты?

Ага, в самую точку. Именно выключить и включить защиту. Сидел искал, есть или нет возможность через cmd, bat - выключить/включить защиту, так и не нашел.

Наверное, как-то можно еще через контекстное меню, в трее, выбрать пункт Отключить защиту, Отключить защиту на 30 секунд - не поможете?
Может в другой теме на форуме...

Так сказать, кому через вызов главного окна
А кому через контекстное меню в трее
 

Вложения

  • 2023-04-03_0002.png
    2023-04-03_0002.png
    50.7 КБ · Просмотры: 7
Последнее редактирование:
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Примеры клика по иконке в трее есть на форуме. Например, здесь

А переключить защиту можно так
Код:
#include <UIAutomate.au3>
$hWnd = WinWait("[REGEXPCLASS:WindowsForms10.Window.20808]", "", 3)
$oMenu = _UIA_GetElementFromHandle($hWnd)
$oItem = _UIA_GetControlTypeElement($oMenu, "UIA_MenuItemControlTypeId", "Включить защиту")
If _UIA_ElementGetPropertyValue($oItem, "IsEnabled") Then
  _UIA_ElementDoDefaultAction($oItem)
Else
  _UIA_ElementDoDefaultAction(_UIA_GetControlTypeElement($oMenu, "UIA_MenuItemControlTypeId", "Отключить защиту"))
EndIf

Кстати, у меня на Win11 этот код работает без повторного вызова меню. Вероятно, после первого вызова (создания) меню не уничтожается, а скрывается.
 

SharkyEXE

Новичок
Сообщения
134
Репутация
0

InnI


Здравствуйте

1) по поводу трея в меню - попробую, может получиться и через трей в меню добрать до опций "Отключить защиту, Отключить защиту на 30 секунд"
2) по поводу "после первого вызова (создания) меню" - там суть в чём - в верхнем правом углу кнопка "Закрыть" - если на нее навести курсор мышки, там будет писаться "Скрыть", то есть по факту - кнопка в верхнем правом углу кнопка "Закрыть" - работает как кнопка "Скрыть"
После нажатия на кнопку - главное окно пропадает, но по факту окно в фоне продолжает работать, программа так сказать не закрывается, в Диспетчер задач процесс висит, но на экране окна нету
Я Вас очень прошу - Вы сделали замечательную фишку
мол, нажать на кнопку по координатам
_UIA_ElementMouseClick($oElem, "", 430, 150)

А можете сделать после строки
_UIA_ElementMouseClick($oElem, "", 430, 150)
нажатие по координатам в верхнем правом углу на кнопку "Закрыть" (по факту "Скрыть")

Типа такое

...
_UIA_ElementMouseClick($oElem, "", 430, 150)
_UIA_ElementMouseClick("Скрыть", "", 0, 0)
где 0,0 - координаты кнопки в верхнем правом углу "Закрыть" (по факту "Скрыть")

Прилагаю информацию о "в верхнем правом углу кнопка "Закрыть" (по факту "Скрыть")" из утилиты Inspect_W7.exe

Спасибо.
 

Вложения

  • Info.txt
    2.3 КБ · Просмотры: 1

lettterssino

Знающий
Сообщения
109
Репутация
10

InnI


Здравствуйте

1) по поводу трея в меню - попробую, может получиться и через трей в меню добрать до опций "Отключить защиту, Отключить защиту на 30 секунд"
2) по поводу "после первого вызова (создания) меню" - там суть в чём - в верхнем правом углу кнопка "Закрыть" - если на нее навести курсор мышки, там будет писаться "Скрыть", то есть по факту - кнопка в верхнем правом углу кнопка "Закрыть" - работает как кнопка "Скрыть"
После нажатия на кнопку - главное окно пропадает, но по факту окно в фоне продолжает работать, программа так сказать не закрывается, в Диспетчер задач процесс висит, но на экране окна нету
Я Вас очень прошу - Вы сделали замечательную фишку
мол, нажать на кнопку по координатам
_UIA_ElementMouseClick($oElem, "", 430, 150)

А можете сделать после строки
_UIA_ElementMouseClick($oElem, "", 430, 150)
нажатие по координатам в верхнем правом углу на кнопку "Закрыть" (по факту "Скрыть")

Типа такое

...
_UIA_ElementMouseClick($oElem, "", 430, 150)
_UIA_ElementMouseClick("Скрыть", "", 0, 0)
где 0,0 - координаты кнопки в верхнем правом углу "Закрыть" (по факту "Скрыть")

Прилагаю информацию о "в верхнем правом углу кнопка "Закрыть" (по факту "Скрыть")" из утилиты Inspect_W7.exe

Спасибо.
Зачем тебе вообще использовать координаты, если ты используешь эту библиотеку?
Код:
$oElement = _UIA_GetControlTypeElement($oElem, "UIA_ButtonControlTypeId", "Скрыть", "LegacyIAccessible.Name")
_UIA_ElementMouseClick($oElement)
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
по поводу "после первого вызова (создания) меню" - там суть в чём - в верхнем правом углу кнопка "Закрыть"
Я написал не про главное окно, а про окно с меню, которое появляется при клике ПКМ по иконке в трее.

кнопка в верхнем правом углу кнопка "Закрыть" - работает как кнопка "Скрыть"
Вот и используйте
Код:
WinClose("AdGuard")
 

SharkyEXE

Новичок
Сообщения
134
Репутация
0

InnI


Здравствуйте

1) По поводу трея - получиться, сообщу Вам. Только предвкушая, значок в трее может быть в скрытом меню, может отображаться открыто - много телодвижений. А не то, что вызвал запуском ехе файла главное окно программы - и сделал отключение/включение защиты

2) По поводу координат кнопки " в верхнем правом углу "Закрыть" (по факту "Скрыть")" - просто для спортивного интереса, хочется понять, откуда берутся координаты, как высчитываются

При этом координаты ползунка защиты
_UIA_ElementMouseClick($oElem, "", 430, 150)
нажимаются 100%но отлично и стабильно, вне зависимости, в каком месте монитора расположено главное окно программы

lettterssino


Здравствуйте

Спасибо Вам за Ваш способ.

Написал выше, очень интересно, откуда берутся координаты, как высчитываются
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
откуда берутся координаты, как высчитываются
Код:
_UIA_ElementGetBoundingRectangle()

Посмотрите в файле UIAutomate.au3 реализацию функции _UIA_ElementMouseClick(). Там рассчитываются координаты середины элемента (когда координаты не указаны).
 

SharkyEXE

Новичок
Сообщения
134
Репутация
0

InnI


Здравствуйте

1) Ой, спасибо Вам за информацию большое, знаний никогда много НЕ бывает

В файле \Include\UIAutomate.au3 есть блок

Код:
; ============================================================================================
; Имя функции : _UIA_ElementMouseClick
; Описание    : Выполняет клик мыши по элементу
; Синтаксис   : _UIA_ElementMouseClick($oElement[, $sButton = ""[, $iX = Default[, $iY = Default[, $iClicks = 1[, $fSetFocus = True]]]]])
; Параметры   : $oElement - элемент (объект)
;             : $sButton  - кнопка мыши (по умолчанию левая)
;             : $iX       - X координата клика (по умолчанию середина ширины элемента)
;             : $iY       - Y координата клика (по умолчанию середина высоты элемента)
;             : $iClicks  - количество кликов (по умолчанию 1)
;             : $SetFocus - активация элемента перед кликом (по умолчанию True)
; Возвращает  : Успех   - 1
;             : Неудача - 0 и устанавливает @error
;             :         @error = 1 - первый параметр не является объектом
;             :         @error = 2 - ошибка создания массива координат прямоугольной области
;             :         @error = 3 - координаты клика выходят за пределы элемента
;             :         @error = 4 - ошибка выполнения функции MouseClick
; Автор       : InnI
; Примечание  : Используются экранные координаты относительно левого верхнего угла элемента
; ============================================================================================


то есть нужно вычислить размеры кнопки "в верхнем правом углу "Закрыть" (по факту "Скрыть")"

Размеры кнопки "в верхнем правом углу "Закрыть" (по факту "Скрыть")" для AdGuard 7.12:
ширина (по горизонтали, х-ось) 35 пикселей
высота (по вертикали, у-ось) 25 пикселей

Центр кнопки "в верхнем правом углу "Закрыть" (по факту "Скрыть")" для AdGuard 7.12:
ширина (по горизонтали, х-ось) 35 пикселей делить на 2 = 17,5 ~ 18 пикселей
высота (по вертикали, у-ось) 25 пикселей делить на 2 = 12,5 ~ 13 пикселей

Чуть, для меня, изменив код

Код:
#include <UIAutomate.au3>
$hWnd = WinGetHandle("AdGuard")
# WinSetState($hWnd, "", @SW_RESTORE)
WinMove($hWnd, "", Default, Default, 840, 640)
$oParent = _UIA_GetElementFromHandle($hWnd)
$oElem = _UIA_GetControlTypeElement($oParent, "UIA_CustomControlTypeId", "InnerDialogContent", "ClassName")
_UIA_ElementMouseClick($oElem, "", 430, 150)
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Скрыть", "LegacyIAccessible.Name")
_UIA_ElementMouseClick($oElement, "", 18, 13)


на выходе отлично

Прилагаю картинки+видео

В плане, может есть возможно лучше, красивше сделать, но хотя бы научился при помощи мышки на центр кнопки "в верхнем правом углу "Закрыть" (по факту "Скрыть")" нажать!

2) По поводу
Код:
_UIA_ElementGetBoundingRectangle()


В файле \Include\UIAutomate.au3 есть блок

Код:
; ============================================================================================
; Имя функции : _UIA_ElementGetBoundingRectangle
; Описание    : Определяет прямоугольную область, ограничивающую элемент
; Синтаксис   : _UIA_ElementGetBoundingRectangle($oElement)
; Параметры   : $oElement - элемент (объект)
; Возвращает  : Успех   - массив
;             :         $aArray[0] - X координата верхнего левого угла элемента
;             :         $aArray[1] - Y координата верхнего левого угла элемента
;             :         $aArray[2] - X координата нижнего правого угла элемента
;             :         $aArray[3] - Y координата нижнего правого угла элемента
;             : Неудача - 0 и устанавливает @error
;             :         @error = 1 - параметр не является объектом
;             :         @error = 2 - ошибка создания массива координат
; Автор       : InnI
; Примечание  : Координаты прямоугольника - экранные
; ============================================================================================


А как вывести информацию, полученную таким способом?

А то при запуске кода ниже
Код:
#include <UIAutomate.au3>
$hWnd = WinGetHandle("AdGuard")
# WinSetState($hWnd, "", @SW_RESTORE)
WinMove($hWnd, "", Default, Default, 840, 640)
$oParent = _UIA_GetElementFromHandle($hWnd)
$oElem = _UIA_GetControlTypeElement($oParent, "UIA_CustomControlTypeId", "InnerDialogContent", "ClassName")
_UIA_ElementMouseClick($oElem, "", 430, 150)
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Скрыть", "LegacyIAccessible.Name")
# _UIA_ElementMouseClick($oElement, "", 18, 13)
 _UIA_ElementGetBoundingRectangle($oElement)


никакой массив данных (что касаемо кнопки " в верхнем правом углу "Закрыть" (по факту "Скрыть")") НЕ выводится
 

Вложения

  • 2023-04-05_0001.png
    2023-04-05_0001.png
    71.4 КБ · Просмотры: 6
  • Запись_2023_04_05_01_53_43_852.mp4_20230405_015432.903.jpg
    Запись_2023_04_05_01_53_43_852.mp4_20230405_015432.903.jpg
    247 КБ · Просмотры: 6
  • Запись_2023_04_05_01_53_43_852.mp4_20230405_015425.507.jpg
    Запись_2023_04_05_01_53_43_852.mp4_20230405_015425.507.jpg
    252.1 КБ · Просмотры: 6
  • Запись_2023_04_05_01_53_43_852.mp4.zip
    557.4 КБ · Просмотры: 2
Последнее редактирование:

lettterssino

Знающий
Сообщения
109
Репутация
10

InnI


Здравствуйте

1) По поводу трея - получиться, сообщу Вам. Только предвкушая, значок в трее может быть в скрытом меню, может отображаться открыто - много телодвижений. А не то, что вызвал запуском ехе файла главное окно программы - и сделал отключение/включение защиты

2) По поводу координат кнопки " в верхнем правом углу "Закрыть" (по факту "Скрыть")" - просто для спортивного интереса, хочется понять, откуда берутся координаты, как высчитываются

При этом координаты ползунка защиты
_UIA_ElementMouseClick($oElem, "", 430, 150)
нажимаются 100%но отлично и стабильно, вне зависимости, в каком месте монитора расположено главное окно программы

lettterssino


Здравствуйте

Спасибо Вам за Ваш способ.

Написал выше, очень интересно, откуда берутся координаты, как высчитываются
Вам не надо искать координаты, вам достаточно найти саму кнопку и остальное уже автоматически находится и нажимается.
Точнее какой смысл указывать координаты элемента, если он по факту в любой точке будет реагировать?
 

SharkyEXE

Новичок
Сообщения
134
Репутация
0

lettterssino


Здравствуйте

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

Типа, шрифт обычный, координаты, куда нажимать, например 100,100
Шрифт 125%, координаты, куда нажимать, например 110,110
...

Бред не бред, но с того времени, когда мышкой, курсором нажимать - всегда планирую в центр кнопки, например, кнопка размером 50 пикс*50 пикс, я планирую нажимать 25 пикс*25 пикс (в центр+середину кнопки)

Как-то так...
 

lettterssino

Знающий
Сообщения
109
Репутация
10

lettterssino


Здравствуйте

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

Типа, шрифт обычный, координаты, куда нажимать, например 100,100
Шрифт 125%, координаты, куда нажимать, например 110,110
...

Бред не бред, но с того времени, когда мышкой, курсором нажимать - всегда планирую в центр кнопки, например, кнопка размером 50 пикс*50 пикс, я планирую нажимать 25 пикс*25 пикс (в центр+середину кнопки)

Как-то так...
Ну и где же тогда логичная составляющая? Вы определяете координаты внутри элемента, зачем вам указывать их. Если по умолчанию будет нажатие в центр элемента. Вне зависимости от его масштаба.
; : $iX - X координата клика (по умолчанию середина ширины элемента)
; : $iY - Y координата клика (по умолчанию середина высоты элемента)
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
как вывести информацию, полученную таким способом?
Код:
#include <UIAutomate.au3>
$oParent = _UIA_GetElementFromHandle(WinGetHandle("AdGuard"))
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Скрыть", "LegacyIAccessible.Name")
$aRect = _UIA_ElementGetBoundingRectangle($oElement)
ConsoleWrite("left   " & $aRect[0] & @CRLF & _
             "top    " & $aRect[1] & @CRLF & _
             "right  " & $aRect[2] & @CRLF & _
             "bottom " & $aRect[3] & @CRLF & _
             "width  " & $aRect[2] - $aRect[0] & @CRLF & _
             "height " & $aRect[3] - $aRect[1] & @CRLF)
; или так
#include <Array.au3>
_ArrayDisplay($aRect)


курсором нажимать - всегда планирую в центр кнопки
Правильно сказал @lettterssino Если в функцию _UIA_ElementMouseClick() не передавать координаты, то она сама вычислит середину элемента и кликнет по этим координатам. Для элемента "InnerDialogContent" нужно передавать координаты, потому что переключатель находится не в середине элемента. Для кнопки "Закрыть" (по факту "Скрыть") передавать координаты нет необходимости.

И вообще. Нет необходимости кликать по кнопкам.
Большинство элементов имеют так называемое действие по умолчанию (DefaultAction). Это действие, которое выполняет элемент при клике по нему ЛКМ. Утилита Inspect отображает это действие, как значение параметра LegacyIAccessible.DefaultAction. Данное действие не зависит ни от размеров, ни от положения, ни от видимости элемента. Поэтому "кликнуть" кнопку можно так
Код:
#include <UIAutomate.au3>
$oParent = _UIA_GetElementFromHandle(WinGetHandle("AdGuard"))
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Скрыть", "LegacyIAccessible.Name")
_UIA_ElementDoDefaultAction($oElement)

Этот код работает даже при свёрнутом окне AdGuard.
 
Последнее редактирование:

lettterssino

Знающий
Сообщения
109
Репутация
10
И вообще. Нет необходимости кликать по кнопкам.
Большинство элементов имеют так называемое действие по умолчанию (DefaultAction). Это действие, которое выполняет элемент при клике по нему ЛКМ. Утилита Inspect отображает это действие, как значение параметра LegacyIAccessible.DefaultAction. Данное действие не зависит ни от размеров, ни от положения, ни от видимости элемента. Поэтому "кликнуть" кнопку можно так
Правильно понимаю, что если так, то действия на элемент нет?
LegacyIAccessible.DefaultAction: ""
А при этом, будет работать DefaulAction:
LegacyIAccessible.DefaultAction: "Нажать"
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
если так, то действия на элемент нет
Верно. И это легко проверить утилитой Inspect: выделяете элемент, в утилите раскрываете меню Action и выбираете пункт LegacyIAccessible.DoDefaultAction. Если действие есть, оно будет выполнено, если нет - ничего не изменится.
 

SharkyEXE

Новичок
Сообщения
134
Репутация
0

InnI


Здравствуйте

Спасибо Вам большое за подробное объяснение, хоть немного въехать, разобраться, понять
 

lettterssino

Знающий
Сообщения
109
Репутация
10
Верно. И это легко проверить утилитой Inspect: выделяете элемент, в утилите раскрываете меню Action и выбираете пункт LegacyIAccessible.DoDefaultAction. Если действие есть, оно будет выполнено, если нет - ничего не изменится.
Столкнулся с такой ситуацией, что срабатывает только мышью
Код:
$oElement=  _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "|LongDelayItem_StartPageButton", "AutomationId", True)
_UIA_ElementMouseClick($oElement)

А это не срабатывает
Код:
$oElement=  _UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "|LongDelayItem_StartPageButton", "AutomationId", True)
_UIA_ElementDoDefaultAction($oElement)
 

Вложения

  • 1680781047571.png
    1680781047571.png
    76.7 КБ · Просмотры: 7
Верх