Obtaining UI Automation Elements
This topic describes various ways to obtain IUIAutomationElement interfaces for UI elements. It contains the following sections:
- Root Element
- Search Scope
- Finding a Known Element
- Finding Elements in a Subtree
- Walking a Subtree
- Other Ways to Retrieve an Element
- Related topics
Although elements can be retrieved directly by using methods, such as IUIAutomation::GetFocusedElement, some client applications require a view of the hierarchical structure of elements, known as the UI Automation tree. The root element of this hierarchy is the desktop. You can obtain this element by using the IUIAutomation::GetRootElement method or the IUIAutomation::GetRootElementBuildCache method. Both these methods retrieve an IUIAutomationElement interface pointer. You can search for descendant elements by using methods, such as IUIAutomationElement::FindFirst and FindAll.
Note In general, you should try to obtain only direct children of the root element. A search for descendants may iterate through hundreds or thousands of elements. If you are attempting to obtain a specific element at a lower level, you should start your search from the application window or from a container at a lower level.
For most techniques you use to retrieve UI Automation elements, you must specify a condition. A condition is a set of criteria that defines the elements that you want to retrieve. A condition is represented by the IUIAutomationCondition interface.
The simplest condition is the true condition, which is a predefined object that specifies that all elements in the search scope are to be returned. The false condition is the inverse of the true condition and is less useful, because it would prevent any elements from being found. You can obtain an interface to the true condition by using IUIAutomation::CreateTrueCondition.
Three other predefined conditions, available as properties on the IUIAutomation object, can be used alone or in combination with other conditions: IUIAutomation::ContentViewCondition, ControlViewCondition, and RawViewCondition. RawViewCondition, used by itself, is equivalent to the true condition, because it does not filter elements by the IUIAutomationElement::CurrentIsControlElement or CurrentIsContentElement properties.
Other conditions are built from condition objects, each of which specifies a property value. For example, a property condition might specify that the element is enabled or that it supports a certain control pattern.
The scope defines the space around the starting place that is to be searched. This might include the element itself, its siblings, its parent, its immediate children, and its descendants. Be aware that the Find methods do not support searching up the Microsoft UI Automation tree; that is, searching for ancestor elements is not supported.
The scope of a search is defined by a bitwise combination of values from the TreeScope enumerated type.
To find a known element that is identified by name, automation ID, or some other property or combination of properties, it is easiest to use the IUIAutomationElement::FindFirst method. If the element sought is an application window, the starting point of the search can be the root element.
This way of finding UI Automation elements is most useful in automated testing scenarios.
For a code example that shows how to find a know element, see Finding an Element by Name.
To find all elements that meet specific criteria and are related to a known element, you can call IUIAutomationElement::FindAll on the known element. For example, use this method to retrieve list items or menu items from a list or menu, or to identify all controls in a dialog box.
For a code example that shows how to find elements in a subtree, see Finding Related Elements.
If you have no prior knowledge of the applications that your client may be used with, you can construct a subtree of all elements of interest by using IUIAutomationTreeWalker. Your client might do this, for example, in response to a focus-changed event; that is, when an application or control receives input focus, the UI Automation client examines children and perhaps all descendants of the focused element.
You can define your own tree walker by passing a custom condition to IUIAutomation::CreateTreeWalker, or you can use one of the following predefined objects that are defined as properties of the base IUIAutomation.
|ContentViewWalker||Finds only elements whose IUIAutomationElement::CurrentIsContentElement property is TRUE.|
|ControlViewWalker||Finds only elements whose IUIAutomationElement::CurrentIsControlElement property is TRUE.|
|RawViewWalker||Finds all elements.|
After you obtain an IUIAutomationTreeWalker, call the IUIAutomationTreeWalker::GetXxx methods to navigate elements of the subtree, passing in the element from which to start walking.
The IUIAutomationTreeWalker::Normalize method can be used for navigating to an element in the subtree from another element that is not part of the view. For example, suppose you create a view of a subtree by using IUIAutomation::ContentViewWalker. Your application receives notification that a scroll bar has received the input focus. Because a scroll bar is not a content element, it is not present in your view of the subtree. However, you can pass the IUIAutomationElement that represents the scroll bar to IUIAutomationTreeWalker::Normalize and retrieve the nearest ancestor that is in the content view.
In addition to searches and navigation, you can retrieve an IUIAutomationElement in the following ways.
When your application receives a UI Automation event, the source object passed to your event handler is represented by an IUIAutomationElement. For example, if you subscribe to focus-changed events, the source passed to your IUIAutomationFocusChangedEventHandler is the element that received the focus. For more information, see Subscribing to UI Automation Events.