Skip to content

06. TreeWalker

Descolada edited this page Feb 4, 2023 · 5 revisions

Introduction

So far we've looked at FindElement(s) methods, which can return elements from "underneath" the starting element, which means it can search its children and descendants. But FindElement(s) cannot travel "laterally" in the tree nor "upwards", which means it cannot return any sibling elements nor parents. To access these other elements we need to use either the WalkTree method, or TreeWalkers.

ElementFromPath

ElementFromPath(path1[, path2, ...])

ElementFromPath gets an element by a relative "path" from a starting element. This path can go only "downwards". If no element is found at the path, then an IndexError is thrown.

Paths can be:

  1. Comma-separated numeric path that defines which path to travel down the tree. In addition to integer values, or TypeN which selects the nth occurrence of Type. Eg. Element.ElementFromPath("3,2") => selects Elements third childs second child Element.ElementFromPath("Button3,2") => selects Elements third child of type Button, then its second child
  2. UIA path copied from UIAViewer. Eg. Element.ElementFromPath("bAx3")
  3. A condition or conditions. In this case the provided conditions define the route of tree-traversal, by default with Scope Children. Eg. Element.ElementFromPath({Type:"Button"}, {Type:"List"}) => finds the first Button type child of Element, then the first List type child of that element

ElementFromPathExist

ElementFromPathExist(path1[, path2, ...])

This is the same as ElementFromPath, but if no element is found at the path then 0 is returned instead of throwing an IndexError.

WalkTree

WalkTree(searchPath, filterCondition?)

Traverses the tree purely using a TreeWalker that is created with an optional filter-condition (default is TrueCondition)

searchPath is a comma-separated path that defines the route of tree traversal:

n: gets the nth child (using GetFirstChildElement and GetNextSiblingElement)
+n: gets the nth next sibling
-n: gets the nth previous sibling
pn: gets the nth parent
"n": normalizes the element (returns the first parent or the element itself matching the filterCondition)

filterCondition can optionally be provided: a condition for tree traversal that selects only elements that match the condition.

Example: Element.ElementFromPath("p,+2,1") => gets the parent of Element, then the second sibling of the parent, then that siblings first child.

TreeWalkers

A TreeWalker is used to "walk" the UIA tree step by step in any direction by giving it a starting point element and a condition for selecting elements. WalkTree is just a simple way to use TreeWalkers, it uses them in the backend.

Getting TreeWalkers

Built-in TreeWalkers

TreeWalkerTrue

UIA.TreeWalkerTrue matches every element.

RawViewWalker

UIA.RawViewWalker matches all UIAutomation elements and is functionally equivalent to TreeWalkerTrue.

ControlViewWalker

UIA.ControlViewWalker matches only elements that are controls.

ContentViewWalker

UIA.ControlViewWalker matches only elements that contain content.

Creating a new TreeWalker

UIA.CreateTreeWalker(condition) takes in a condition and returns a new IUIAutomationTreeWalker object.

TreeWalker properties

TreeWalker.Condition returns the condition the TreeWalker was created with.

TreeWalker methods

GetParentElement

TreeWalker.GetParentElement(e) takes an element e and returns the parent element (using the condition the TreeWalker was created with).

GetFirstChildElement

TreeWalker.GetFirstChildElement(e) takes an element e and returns the first child element (using the condition the TreeWalker was created with).

GetLastChildElement

TreeWalker.GetLastChildElement(e) takes an element e and returns the last child element (using the condition the TreeWalker was created with).

GetNextSiblingElement

TreeWalker.GetNextSiblingElement(e) takes an element e and returns the next sibling element (using the condition the TreeWalker was created with).

GetPreviousSiblingElement

TreeWalker.GetPreviousSiblingElement(e) takes an element e and returns the previous sibling element (using the condition the TreeWalker was created with).

NormalizeElement

TreeWalker.NormalizeElement(e) takes an element e and first checks if e matches the condition, otherwise returns the first parent element that matches the condition. The difference between this and GetParentElement is that NormalizeElement can return the original element as well.

Example

Using TreeWalkerTrue to get the next sibling element.

#Include <UIA>
Run "notepad.exe"
WinWaitActive "ahk_exe notepad.exe"
npEl := UIA.ElementFromHandle("ahk_exe notepad.exe") ; Get the element for the Notepad window
editEl := npEl.FindElement({Name:"Edit"}) ; Should return the "Edit" menuitem
MsgBox "Next sibling from `"Edit`" menu item: " UIA.TreeWalkerTrue.GetNextSiblingElement(editEl).Dump()
ExitApp

A TreeWalker can be used multiple times in a row as well. For example getting the second sibling: TreeWalkerTrue.GetNextSiblingElement(TreeWalkerTrue.GetNextSiblingElement(Element)). This is equivalent to Element.WalkTree("+2")