Hier ein kleines Beispiel von mir. Du musst so gesehen hierarchisch dort von Anfang an dorthin navigieren, kannst dir aber bestimmte Bereiche als $Parent speichern um von dort in eine andere Richtung zu suchen. Sprich wenn du ein Tree-Item möchtest, musst du erst mal das 1. Fenster referenzieren vom Desktop oder der Anwendung an sich heraus. Dann das darin liegende Fenster in dem der Tree liegt und dann vom Tree aus in die Zeilen und dort dann erst das finale Item suchen. Du kannst auch direkt vom Parent bis zum Item in einer Build condition und search condition suchen, das verursacht aber unnötigen Headspace da er alles scannen muss weil er das was du willst im $Parent nicht kennt und er vom angegebenen Parent aus dann solange Childs untersucht bis er es hat. Daher lieber den richtigen Referer bereits lokalisieren und nutzen, sprich hierarchich dorthin navigieren, siehe Beispiel 2.
Das Program UIA_Spy hilft dir dabei fast alles auszulesen, es kann auch Code erstellen, finde ich aber nicht so effizient gestaltet.
Hier noch ein paar Beispiele mit Builder-Funktionen von mir selbst, schon lange her das ich diese benutzt hatte:
Sorry für die Unordnung, grade schnell alles hier zusammengefügt zum präsentieren. Vlt. verstehst du es so.
Global $oParent = init_uia("Microsoft Dynamics Navision")
main_test()
Func main_test()
; Suche Fenster Umfüllauftragskarte anhand ID und 2 weiteren checkups
Local $aConditions = [[$UIA_AutomationIdPropertyId, "{004EED9C-0000-0000-0108-0000836BD2D2}"], _
[$UIA_ClassNamePropertyId, "WindowsForms10.Window.8.app.0.2004eee"], _
[$UIA_ControlTypePropertyId, $UIA_WindowControlTypeId]]
$parent_datagrid = build_condition($oParent, $aConditions)
If Not IsObj($parent_datagrid) Then Return -1
; Extrahiere die UF-Nummer
Local $result_UF_nr = get_propertie_value($parent_datagrid, $UIA_LegacyIAccessibleNamePropertyId)
$result_UF_nr = StringSplit($result_UF_nr, " ")
If Not IsArray($result_UF_nr) Then Return -1
return $result_UF_nr
Endfunc
Func init_uia($handleName)
; Create UI Automation object
Global $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF )
Local $mainwindow
$UIA_oUIAutomation.ElementFromHandle(WinGetHandle($handleName), $mainwindow)
Global $hwnd = ObjCreateInterface($mainwindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
If Not IsObj( $hwnd ) Then Return ConsoleWrite( "$hwnd ERR" & @CRLF )
Return $hwnd
EndFunc
Func build_condition($oParent, $aConditions)
If Not IsArray($aConditions) Then Return False
If Not IsObj($oParent) Then Return False
Local $iParts = Ubound($aConditions)
Local $pCondition0, $pCondition1, $pAndCondition1
; Build first condition
$oUIAutomation.CreatePropertyCondition($aConditions[0][0], $aConditions[0][1], $pAndCondition1 )
If Not $pAndCondition1 Then Return ConsoleWrite( "$pAndCondition1 ERR" & @CRLF )
; create variables and build next conditions by array
If $iParts > 1 Then
For $i = 1 To $iParts-1
$oUIAutomation.CreatePropertyCondition($aConditions[$i][0], $aConditions[$i][1], $pCondition1)
If Not $pCondition1 Then Return ConsoleWrite(String($aConditions[$i][0]) & " -> " & $aConditions[$i][1] & "$pCondition ERR" & @CRLF )
$oUIAutomation.CreateAndCondition($pCondition1, $pAndCondition1, $pAndCondition1)
If Not $pAndCondition1 Then Return ConsoleWrite( "$pAndCondition1 ERR" & @CRLF )
Next
EndIf
Local $pObj1, $oObj1
$oParent.FindFirst( $TreeScope_Descendants, $pAndCondition1, $pObj1 )
$oObj1 = ObjCreateInterface( $pObj1, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
If Not IsObj( $oObj1 ) Then Return ConsoleWrite( "$oObj1 ERR" & @CRLF )
Return $oObj1
EndFunc
Func get_propertie_value($oElement, $iPropertie)
If Not IsObj($oElement) Then Return False
Local $sValueValue2
$oElement.GetCurrentPropertyValue($iPropertie, $sValueValue2)
Return $sValueValue2
EndFunc
Alles anzeigen
- UIAWrappers.au3
- UIA_Functions.au3
; UIA variablen wie benötigt setzen
_UIA_setVar("Global.Debug", false)
_UIA_setVar("Global.Debug.File", false)
_UIA_setVar("Global.Highlight", true)
; Hilft beim Navigieren mit UIA anhand Titelnamen falls mehrere Fenster simultan offen sein können.
Opt("WinTitleMatchMode", 2)
; Main:
WinActivate("Microsoft Dynamics NAV") ; Beispiel für MS Navision
Local $mainwindow
$UIA_oUIAutomation.ElementFromHandle(WinGetHandle("Microsoft Dynamics NAV"), $mainwindow)
Global $hwnd = ObjCreateInterface( $mainwindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
_navigatemenuitem("Startseite") ; Beispiel Klick auf Startseite
Func _navigatemenuitem($menuitemname)
WinActivate("Microsoft Dynamics NAV")
WinWaitActive("Microsoft Dynamics NAV")
; Create UI Automation object
Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation)
If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF )
ConsoleWrite( "$oUIAutomation OK" & @CRLF )
; Get Desktop element
Local $pDesktop, $oDesktop
$oUIAutomation.GetRootElement( $pDesktop )
$oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "$oDesktop ERR" & @CRLF )
ConsoleWrite( "$oDesktop OK" & @CRLF )
; --- Find window/control ---
ConsoleWrite( "--- Build check conditions ---" & @CRLF )
; $UIA_AutomationIdPropertyId needs to be "{DF1AA864-6D25-4f2a-8620-C078B7B4CA17}" and will be saved as $pCondition0
; $UIA_ControlTypePropertyId needs to be $UIA_PaneControlTypeId and will be saved as $pCondition1
; CreateAndCondition concatenates $pCondition0 and $pCondition1 which results in $pAndCondition1
Local $pCondition0, $pCondition1, $pAndCondition1
$oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "{DF1AA864-6D25-4f2a-8620-C078B7B4CA17}", $pCondition0 )
$oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_PaneControlTypeId, $pCondition1 )
$oUIAutomation.CreateAndCondition( $pCondition0, $pCondition1, $pAndCondition1 )
If Not $pAndCondition1 Then Return ConsoleWrite( "$pAndCondition1 ERR" & @CRLF )
ConsoleWrite( "$pAndCondition1 OK" & @CRLF )
; With the $pAndCondition1 we have been build up, we now look for the Pane element
; Search in the root $hwnd the Pane with the conditions we setup
Local $pPane1, $oPane1
$hwnd.FindFirst( $TreeScope_Descendants, $pAndCondition1, $pPane1 )
$oPane1 = ObjCreateInterface( $pPane1, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
If Not IsObj( $oPane1 ) Then Return ConsoleWrite( "$oPane1 ERR" & @CRLF )
ConsoleWrite( "$oPane1 OK" & @CRLF )
; --- Find window/control ---
ConsoleWrite( "--- Build next check conditions ---" & @CRLF )
; we build up the next condition to look for the final element we need from the $oPane Object we referenced -> the CustomControl.
Local $pCondition4, $pCondition5, $pAndCondition5
$oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_CustomControlTypeId, $pCondition4 )
$oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, $menuitemname, $pCondition5 )
$oUIAutomation.CreateAndCondition( $pCondition4, $pCondition5, $pAndCondition5 )
If Not $pAndCondition5 Then Return ConsoleWrite( "$pAndCondition5 ERR" & @CRLF )
ConsoleWrite( "$pAndCondition5 OK" & @CRLF )
; With the condition, search in the Pane1 for the
Local $pCustom1, $oCustom1
$oPane1.FindFirst( $TreeScope_Descendants, $pAndCondition5, $pCustom1 )
$oCustom1 = ObjCreateInterface( $pCustom1, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
If Not IsObj( $oCustom1 ) Then Return ConsoleWrite( "$oCustom1 ERR" & @CRLF )
ConsoleWrite( "$oCustom1 OK" & @CRLF )
; --- Element Properties (information) ---
; click coordinates extracted from the final item in simple way
Local $asBoundingRectangle1
$oCustom1.GetCurrentPropertyValue( $UIA_BoundingRectanglePropertyId, $asBoundingRectangle1 )
MouseClick("left", $asBoundingRectangle1[0]+$asBoundingRectangle1[2]/2, $asBoundingRectangle1[1]+$asBoundingRectangle1[3]/2, 1 , 0)
WinWaitActive("Microsoft Dynamics NAV")
EndFunc
Alles anzeigen