Что нового

[Автоматизация] Вызов контекстного меню по его AutomationId, в свёрнутом приложении

IvanChai

Новичок
Сообщения
7
Репутация
0
Имеем тестовый модифицированный пример http://autoit-script.ru/index.php?topic=23446.0 , который сейчас работает через непосредственный вызов контекстного меню right-кликом и горячей клавишей, удаляя первый пункт истории (чтобы работало, нужно включить режим истории канала руками - стрелка вправо):

Код:
#include <UIAutomate.au3>
#include "MSActiveAccessibility.au3"

Global Const $sIID_IAccessible = "{618736E0-3C3D-11CF-810C-00AA00389B71}"
Global $dtagIAccessible = "GetTypeInfoCount hresult(uint*);" & _
"GetTypeInfo hresult(uint;int;ptr*);" & _
"GetIDsOfNames hresult(struct*;wstr;uint;int;int);" & _
"Invoke hresult(int;struct*;int;word;ptr*;ptr*;ptr*;uint*);" & _
"get_accParent hresult(ptr*);" & _
"get_accChildCount hresult(long*);" & _
"get_accChild hresult(variant;idispatch*);" & _
"get_accName hresult(variant;bstr*);" & _
"get_accValue hresult(variant;bstr*);" & _
"get_accDescription hresult(variant;bstr*);" & _
"get_accRole hresult(variant;variant*);" & _
"get_accState hresult(variant;variant*);" & _
"get_accHelp hresult(variant;bstr*);" & _
"get_accHelpTopic hresult(bstr*;variant;long*);" & _
"get_accKeyboardShortcut hresult(variant;bstr*);" & _
"get_accFocus hresult(struct*);" & _
"get_accSelection hresult(variant*);" & _
"get_accDefaultAction hresult(variant;bstr*);" & _
"accSelect hresult(long;variant);" & _
"accLocation hresult(long*;long*;long*;long*;variant);" & _
"accNavigate hresult(long;variant;variant*);" & _
"accHitTest hresult(long;long;variant*);" & _
"accDoDefaultAction hresult(variant);" & _
"put_accName hresult(variant;bstr);" & _
"put_accValue hresult(variant;bstr);"

Const $ZC_REMOVE_MESSAGE = 32798 ; "удалить выделенные" из истории SysListView326

HotKeySet('{ESC}', '_exit')

$hWnd = WinWait("[CLASS:d8348ccb68a1]", "", 10)
WinActivate($hWnd)

$hCtrl = ControlGetHandle($hWnd, "", "SysListView326") ; история

While 1
	 Local $oParent = _UIA_GetElementFromHandle($hCtrl)
	 Local $aItems = _UIA_FindAllElements($oParent, "ControlType", $UIA_ListItemControlTypeId) ; все пункты списка

	 If IsArray($aItems) And $aItems[0] > 0 Then
		 Local $sNames = _GetNames($hCtrl)
		 Local $oElement = $aItems[1]
		 ConsoleWrite("Name: " & $sNames[1] & @CRLF)
		 _UIA_ElementScrollIntoView($oElement)
		 _UIA_ElementMouseClick($oElement, "right")
		 Send("у{ENTER}")
		 ControlListView($hWnd,"",$hCtrl,"SelectClear")
                 Sleep(1000)
	 Else
		 Sleep(2000)
	 EndIf
WEnd

Func _GetNames($hWnd)
	 If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
	 Local $pWindow, $oWindow, $iChildCount, $sText
	 AccessibleObjectFromWindow($hWnd, $OBJID_CLIENT, $tIID_IAccessible, $pWindow)
	 $oWindow = ObjCreateInterface($pWindow, $sIID_IAccessible, $dtagIAccessible)
	 If Not IsObj($oWindow) Then Return  SetError(2, 0, 0)
	 If $oWindow.get_accChildCount($iChildCount) Or Not $iChildCount Then Return SetError(3, 0, 0)
	 Local $res[$iChildCount+1]
	 For $iChild = 1 To $iChildCount
		 $oWindow.get_accName($iChild, $sText)
		 $res[$iChild] = $sText;
	 Next
	 Return $res
EndFunc

Func _exit()
	 Exit
EndFunc


Каким образом можно проверить доступность и послать команду из контекстного меню по заданному AutomationId объекту $oElement, без непосредственного клика на элементе?

То есть хочется заменить:
Код:
_UIA_ElementScrollIntoView($oElement)
_UIA_ElementMouseClick($oElement, "right")
Send("у{ENTER}")
ControlListView($hWnd,"",$hCtrl,"SelectClear")

чем-то, что может работать в фоне, используя AutomationId пункта контекстного меню $ZC_REMOVE_MESSAGE и не мешая пользователю работать с другим софтом.
 

sngr

AutoIT Гуру
Сообщения
985
Репутация
392
С помощью этого смотришь что происходит при нажатии нужных кнопок, затем с помощью _SendMessage ты увиденное отсылаешь окну.
 
Автор
IvanChai

IvanChai

Новичок
Сообщения
7
Репутация
0
Кусок рабочего итога:
Код:
ControlListView($hWnd,"",$hCtrl,"SelectClear")
ControlListView($hWnd,"",$hCtrl,"Select",$index-1)
_SendMessage($mCtrl,0x0111, $ZC_HISTORY_REMOVE_SELECTED_MESSAGES)

Где:
$hCtrl - handle SysListView32
$mCtrl - handle элемента, получающего события вычисленный с помощью MS Spy++, он же родитель $hCtrl
$ZC_HISTORY_REMOVE_SELECTED_MESSAGES - AutomationId пункта контекстного меню, полученный с помощью Inspect_W7
0x0111 - WM_COMMAND, так же вытащенный из MS Spy++

snqr, спасибо :ok:
 
Верх