/*************************************************************************************************
*
* File: ClientForm.cs
*
* Description: Miscellaneous snippets illustrating client UIA functionality
*
*
*************************************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Windows.Automation;
using System.Windows;
using System.Diagnostics;
namespace CustomElementClient
{
public partial class Form1 : Form
{
//
public struct CursorPoint
{
public int X;
public int Y;
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
internal static extern bool GetPhysicalCursorPos(ref CursorPoint lpPoint);
private bool ShowUsage()
{
CursorPoint cursorPos = new CursorPoint();
try
{
return GetPhysicalCursorPos(ref cursorPos);
}
catch (EntryPointNotFoundException) // Not Windows Vista
{
return false;
}
}
//
AutomationElement RootElement = null;
AutomationElement MainWindowElement = null;
AutomationElement ListElement = null;
AutomationEventHandler OnEvent = null;
///
/// Constructor.
///
public Form1()
{
InitializeComponent();
}
//
private AutomationElement ElementFromCursor()
{
// Convert mouse position from System.Drawing.Point to System.Windows.Point.
System.Windows.Point point = new System.Windows.Point(Cursor.Position.X, Cursor.Position.Y);
AutomationElement element = AutomationElement.FromPoint(point);
return element;
}
//
//
///
/// Walks the UI Automation tree and adds the control type of each element it finds
/// in the control view to a TreeView.
///
/// The root of the search on this iteration.
/// The node in the TreeView for this iteration.
///
/// This is a recursive function that maps out the structure of the subtree beginning at the
/// UI Automation element passed in as rootElement on the first call. This could be, for example,
/// an application window.
/// CAUTION: Do not pass in AutomationElement.RootElement. Attempting to map out the entire subtree of
/// the desktop could take a very long time and even lead to a stack overflow.
///
private void WalkControlElements(AutomationElement rootElement, TreeNode treeNode)
{
// Conditions for the basic views of the subtree (content, control, and raw)
// are available as fields of TreeWalker, and one of these is used in the
// following code.
AutomationElement elementNode = TreeWalker.ControlViewWalker.GetFirstChild(rootElement);
while (elementNode != null)
{
TreeNode childTreeNode = treeNode.Nodes.Add(elementNode.Current.ControlType.LocalizedControlType);
WalkControlElements(elementNode, childTreeNode);
elementNode = TreeWalker.ControlViewWalker.GetNextSibling(elementNode);
}
}
//
//
///
/// Walks the UI Automation tree and adds the control type of each enabled control
/// element it finds to a TreeView.
///
/// The root of the search on this iteration.
/// The node in the TreeView for this iteration.
///
/// This is a recursive function that maps out the structure of the subtree beginning at the
/// UI Automation element passed in as rootElement on the first call. This could be, for example,
/// an application window.
/// CAUTION: Do not pass in AutomationElement.RootElement. Attempting to map out the entire subtree of
/// the desktop could take a very long time and even lead to a stack overflow.
///
private void WalkEnabledElements(AutomationElement rootElement, TreeNode treeNode)
{
Condition condition1 = new PropertyCondition(AutomationElement.IsControlElementProperty, true);
Condition condition2 = new PropertyCondition(AutomationElement.IsEnabledProperty, true);
TreeWalker walker = new TreeWalker(new AndCondition(condition1, condition2));
AutomationElement elementNode = walker.GetFirstChild(rootElement);
while (elementNode != null)
{
TreeNode childTreeNode = treeNode.Nodes.Add(elementNode.Current.ControlType.LocalizedControlType);
WalkEnabledElements(elementNode, childTreeNode);
elementNode = walker.GetNextSibling(elementNode);
}
}
//
//
///
/// Find a UI Automation child element by ID.
///
/// Name of the control, such as "button1"
/// Parent element, such as an application window, or the
/// AutomationElement.RootElement when searching for the application window.
/// The UI Automation element.
private AutomationElement FindChildElement(String controlName, AutomationElement rootElement)
{
if ((controlName == "") || (rootElement == null))
{
throw new ArgumentException("Argument cannot be null or empty.");
}
// Set a property condition that will be used to find the main form of the
// target application. In the case of a WinForms control, the name of the control
// is also the AutomationId of the element representing the control.
Condition propCondition = new PropertyCondition(
AutomationElement.AutomationIdProperty, controlName, PropertyConditionFlags.IgnoreCase);
// Find the element.
return rootElement.FindFirst(TreeScope.Element | TreeScope.Children, propCondition);
}
//
///
/// Initializes the UIAutomation system by finding the root element and the element
/// for the window of the provider application.
///
/// true if successful; otherwise false.
private bool InitializeUIAutomation()
{
try
{
RootElement = AutomationElement.RootElement;
}
catch (Exception e)
{
MessageBox.Show("Could not initialize UIAutomation: " + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
MainWindowElement = FindChildElement("UIAFragmentProviderForm", RootElement);
if (MainWindowElement == null)
{
MessageBox.Show("Could not find the main form of the provider application.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
else
{
Condition cond2 =
new PropertyCondition(AutomationElement.NameProperty, "FlowerList");
ListElement = MainWindowElement.FindFirst(TreeScope.Children, cond2);
if (ListElement == null)
{
MessageBox.Show("Could not find custom control in the provider application.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
}
// Subscribe to ElementSelected events, which are raised each time a list item is selected.
// The events are raised by the list items, not the list, so the scope is set to Descendants.
OnEvent = new AutomationEventHandler(OnSelect);
Automation.AddAutomationEventHandler(SelectionItemPattern.ElementSelectedEvent, ListElement,
TreeScope.Descendants, OnEvent);
return true;
}
//
///
/// Handles ElementSelected events by showing a message.
///
/// Object that raised the event; in this case, a list item.
/// Event arguments.
private void OnSelect(object src, AutomationEventArgs e)
{
// Get the name of the item, which is equivalent to its text.
AutomationElement element = src as AutomationElement;
if (element != null)
{
Console.WriteLine(element.Current.Name + " was selected.");
}
}
//
///
/// Shuts down UI Automation.
///
/// Object that raised the event.
/// Event arguments.
//private void Form1_FormClosing(object sender, FormClosingEventArgs e)
//{
// try
// {
// Automation.RemoveAutomationEventHandler(SelectionItemPattern.ElementSelectedEvent,
// elementList, OnEvent);
// }
// catch
// {
// return;
// }
//}
///
/// Handles a button click by selecting an item in the list box.
///
/// Object that raised the event.
/// Information about the event.
private void button1_Click(object sender, EventArgs e)
{
try
{
SelectListItem(ListElement, "Daffodil");
}
catch
{
label1.Text = "No UIAutomation target found.";
return;
}
AutomationElement ae = ElementFromCursor();
if (ae != null)
{
Console.WriteLine(ae.Current.Name);
}
else
{
Console.WriteLine("no element there");
}
}
private void Form1_Load(object sender, EventArgs e)
{
if (false == InitializeUIAutomation())
{
Application.Exit();
}
}
#region Event handling
//
// Member variables.
AutomationElement ElementSubscribeButton;
AutomationEventHandler UIAeventHandler;
///
/// Register an event handler for InvokedEvent on the specified element.
///
/// The automation element.
public void SubscribeToInvoke(AutomationElement elementButton)
{
if (elementButton != null)
{
Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent,
elementButton, TreeScope.Element,
UIAeventHandler = new AutomationEventHandler(OnUIAutomationEvent));
ElementSubscribeButton = elementButton;
}
}
//
///
/// AutomationEventHandler delegate.
///
/// Object that raised the event.
/// Event arguments.
private void OnUIAutomationEvent(object src, AutomationEventArgs e)
{
// Make sure the element still exists. Elements such as tooltips
// can disappear before the event is processed.
AutomationElement sourceElement;
try
{
sourceElement = src as AutomationElement;
}
catch (ElementNotAvailableException)
{
return;
}
if (e.EventId == InvokePattern.InvokedEvent)
{
// TODO Add handling code.
}
else
{
// TODO Handle any other events that have been subscribed to.
}
}
//
private void ShutdownUIA()
{
if (UIAeventHandler != null)
{
Automation.RemoveAutomationEventHandler(InvokePattern.InvokedEvent,
ElementSubscribeButton, UIAeventHandler);
}
}
//
// NOTE: ABOVE SHOULD NOT BE CALLED ON THE UI THREAD
///
/// Shutdown code.
///
/// Object that raised the event.
/// Event arguments.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// NOTE This should not be done on the UI thread
ShutdownUIA();
}
//
AutomationFocusChangedEventHandler focusHandler = null;
///
/// Create an event handler and register it.
///
public void SubscribeToFocusChange()
{
focusHandler = new AutomationFocusChangedEventHandler(OnFocusChange);
Automation.AddAutomationFocusChangedEventHandler(focusHandler);
}
///
/// Handle the event.
///
/// Object that raised the event.
/// Event arguments.
private void OnFocusChange(object src, AutomationFocusChangedEventArgs e)
{
// TODO Add event handling code.
// The arguments tell you which elements have lost and received focus.
}
///
/// Cancel subscription to the event.
///
public void UnsubscribeFocusChange()
{
if (focusHandler != null)
{
Automation.RemoveAutomationFocusChangedEventHandler(focusHandler);
}
}
//
#endregion Event handling
#region Selection and SelectionItem pattern
//
///
/// Sets the focus to a list and selects a string item in that list.
///
/// The list element.
/// The text to select.
///
/// This deselects any currently selected items. To add the item to the current selection
/// in a multiselect list, use AddToSelection instead of Select.
///
public void SelectListItem(AutomationElement listElement, String itemText)
{
if ((listElement == null) || (itemText == ""))
{
throw new ArgumentException("Argument cannot be null or empty.");
}
listElement.SetFocus();
Condition cond = new PropertyCondition(
AutomationElement.NameProperty, itemText, PropertyConditionFlags.IgnoreCase);
AutomationElement elementItem = listElement.FindFirst(TreeScope.Children, cond);
if (elementItem != null)
{
SelectionItemPattern pattern;
try
{
pattern = elementItem.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.Message); // Most likely "Pattern not supported."
return;
}
pattern.Select();
}
}
//
//
///
/// Retrieves the selection container for a selection item.
///
///
/// An element that supports SelectionItemPattern.
///
AutomationElement GetListItemParent(AutomationElement listItem)
{
if (listItem == null) throw new ArgumentException();
SelectionItemPattern pattern = listItem.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;
if (pattern == null)
{
return null;
}
else
{
SelectionItemPattern.SelectionItemPatternInformation properties = pattern.Current;
return properties.SelectionContainer;
}
}
//
//
void AddListItemToSelection(AutomationElement listItem)
{
if (listItem == null) throw new ArgumentException();
SelectionItemPattern pattern = listItem.GetCurrentPattern(SelectionItemPattern.Pattern)
as SelectionItemPattern;
if (pattern != null)
{
pattern.AddToSelection();
}
}
//
#endregion Selection and SelectionItem pattern
#region Property retrieval and caching
/* Following snippet shows various aspects of caching and should be used in general discussion of the topic. */
// TODO Show use of TreeScope, GetUpdatedCache
//
///
/// Caches and retrieves properties for a list item by using CacheRequest.Activate.
///
/// Element from which to retrieve a child element.
///
/// This code demonstrates various aspects of caching. It is not intended to be
/// an example of a useful method.
///
private void CachePropertiesByActivate(AutomationElement elementList)
{
AutomationElement elementListItem;
// Set up the request.
//
CacheRequest cacheRequest = new CacheRequest();
cacheRequest.Add(AutomationElement.NameProperty);
cacheRequest.Add(AutomationElement.IsEnabledProperty);
cacheRequest.Add(SelectionItemPattern.Pattern);
cacheRequest.Add(SelectionItemPattern.SelectionContainerProperty);
//
// Obtain an element and cache the requested items.
using (cacheRequest.Activate())
{
Condition cond = new PropertyCondition(AutomationElement.IsSelectionItemPatternAvailableProperty, true);
elementListItem = elementList.FindFirst(TreeScope.Children, cond);
}
// The CacheRequest is now inactive.
// Retrieve the cached property and pattern.
SelectionItemPattern pattern;
String itemName;
try
{
itemName = elementListItem.Cached.Name;
pattern = elementListItem.GetCachedPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;
}
catch (InvalidOperationException)
{
Console.WriteLine("Object was not in cache.");
return;
}
// Alternatively, you can use TryGetCachedPattern to retrieve the cached pattern.
object cachedPattern;
if (true == elementListItem.TryGetCachedPattern(SelectionItemPattern.Pattern, out cachedPattern))
{
pattern = cachedPattern as SelectionItemPattern;
}
// Specified pattern properties are also in the cache.
AutomationElement parentList = pattern.Cached.SelectionContainer;
// The following line will raise an exception, because the HelpText property was not cached.
/*** String itemHelp = elementListItem.Cached.HelpText; ***/
// Similarly, pattern properties that were not specified in the CacheRequest cannot be
// retrieved from the cache. This would raise an exception.
/*** bool selected = pattern.Cached.IsSelected; ***/
// This is still a valid call, even though the property is in the cache.
// Of course, the cached value and the current value are not guaranteed to be the same.
itemName = elementListItem.Current.Name;
}
//
//
///
/// Caches and retrieves properties for a list item by using CacheRequest.Push.
///
/// Element from which to retrieve a child element.
///
/// This code demonstrates various aspects of caching. It is not intended to be
/// an example of a useful method.
///
private void CachePropertiesByPush(AutomationElement elementList)
{
//
// Set up the request.
CacheRequest cacheRequest = new CacheRequest();
// Do not get a full reference to the cached objects, only to their cached properties and patterns.
cacheRequest.AutomationElementMode = AutomationElementMode.None;
//
// Cache all elements, regardless of whether they are control or content elements.
cacheRequest.TreeFilter = Automation.RawViewCondition;
// Property and pattern to cache.
cacheRequest.Add(AutomationElement.NameProperty);
cacheRequest.Add(SelectionItemPattern.Pattern);
// Activate the request.
cacheRequest.Push();
// Obtain an element and cache the requested items.
Condition cond = new PropertyCondition(AutomationElement.IsSelectionItemPatternAvailableProperty, true);
AutomationElement elementListItem = elementList.FindFirst(TreeScope.Children, cond);
// At this point, you could call another method that creates a CacheRequest and calls Push/Pop.
// While that method was retrieving automation elements, the CacheRequest set in this method
// would not be active.
// Deactivate the request.
cacheRequest.Pop();
// Retrieve the cached property and pattern.
String itemName = elementListItem.Cached.Name;
SelectionItemPattern pattern = elementListItem.GetCachedPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;
// The following is an alternative way of retrieving the Name property.
itemName = elementListItem.GetCachedPropertyValue(AutomationElement.NameProperty) as String;
// This is yet another way, which returns AutomationElement.NotSupported if the element does
// not supply a value. If the second parameter is false, a default name is returned.
object objName = elementListItem.GetCachedPropertyValue(AutomationElement.NameProperty, true);
if (objName == AutomationElement.NotSupported)
{
itemName = "Unknown";
}
else
{
itemName = objName as String;
}
// The following call raises an exception, because only the cached properties are available,
// as specified by cacheRequest.AutomationElementMode. If AutomationElementMode had its
// default value (Full), this call would be valid.
/*** bool enabled = elementListItem.Current.IsEnabled; ***/
}
//
// *** Simple property retrieval ***
void MiscPropertyCalls(AutomationElement elementList)
{
//
// elementList is an AutomationElement.
// The following two calls are equivalent.
string name = elementList.Current.Name;
name = elementList.GetCurrentPropertyValue(AutomationElement.NameProperty) as string;
//
//
// elementList is an AutomationElement representing a list box.
// Error-checking is omitted. Assume that elementList is known to support SelectionPattern.
SelectionPattern selectPattern =
elementList.GetCurrentPattern(SelectionPattern.Pattern) as SelectionPattern;
bool isMultipleSelect = selectPattern.Current.CanSelectMultiple;
// The following call is equivalent to the one above.
isMultipleSelect = (bool)
elementList.GetCurrentPropertyValue(SelectionPattern.CanSelectMultipleProperty);
//
//
// elementList is an AutomationElement.
object help = elementList.GetCurrentPropertyValue(AutomationElement.HelpTextProperty, true);
if (help == AutomationElement.NotSupported)
{
help = "No help available";
}
string helpText = (string)help;
//
//
// elementList is an AutomationElement.
string helpString =
elementList.GetCurrentPropertyValue(AutomationElement.HelpTextProperty) as string;
//
}
// Following is similar to above, but without the redundant comments -- better for a how-to
//
void PropertyCallsExample(AutomationElement elementList)
{
// The following two calls are equivalent.
string name = elementList.Current.Name;
name = elementList.GetCurrentPropertyValue(AutomationElement.NameProperty) as string;
// The following shows how to ignore the default property, which
// would probably be an empty string if the property is not supported.
// Passing "false" as the second parameter is equivalent to using the overload
// that does not have this parameter.
object help = elementList.GetCurrentPropertyValue(AutomationElement.HelpTextProperty, true);
if (help == AutomationElement.NotSupported)
{
help = "No help available";
}
string helpText = (string)help;
}
//
/*** *** Updating the cache *** ***/
//
CacheRequest comboCacheRequest;
AutomationEventHandler selectHandler;
AutomationElement elementCombo;
AutomationElement selectedItem;
///
/// Retrieves a combo box automation element, caches a pattern and a property,
/// and registers the event handler.
///
/// The element for the parent window.
private void SetupComboElement(AutomationElement elementAppWindow)
{
// Set up the CacheRequest.
comboCacheRequest = new CacheRequest();
comboCacheRequest.Add(SelectionPattern.Pattern);
comboCacheRequest.Add(SelectionPattern.SelectionProperty);
comboCacheRequest.Add(AutomationElement.NameProperty);
comboCacheRequest.TreeScope = TreeScope.Element | TreeScope.Descendants;
// Activate the CacheRequest and get the element.
using (comboCacheRequest.Activate())
{
// Load the combo box element and cache the specified properties and patterns.
Condition propCondition = new PropertyCondition(
AutomationElement.AutomationIdProperty, "comboBox1", PropertyConditionFlags.IgnoreCase);
elementCombo = elementAppWindow.FindFirst(TreeScope.Descendants, propCondition);
}
// Get the list from the combo box.
//
Condition propCondition1 = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.List);
AutomationElement listElement = elementCombo.FindFirst(TreeScope.Children, propCondition1);
//
// Register for ElementSelectedEvent on list items.
if (listElement != null)
{
Automation.AddAutomationEventHandler(SelectionItemPattern.ElementSelectedEvent, listElement,
TreeScope.Children, selectHandler = new AutomationEventHandler(OnListItemSelect));
}
}
///
/// Handle ElementSelectedEvent on items in the combo box.
///
/// Object that raised the event.
/// Event arguments.
private void OnListItemSelect(object src, AutomationEventArgs e)
{
// Update the cache.
AutomationElement updatedElement = elementCombo.GetUpdatedCache(comboCacheRequest);
// Retrieve the pattern and the selected item from the cache. This code is here only to
// demonstrate that the current selection can now be retrieved from the cache. In an application,
// this would be done only when the information was needed.
SelectionPattern pattern = updatedElement.GetCachedPattern(SelectionPattern.Pattern) as SelectionPattern;
AutomationElement[] selectedItems = pattern.Cached.GetSelection();
selectedItem = selectedItems[0];
}
//
//
///
/// Gets a list box element and caches the Name property of its children (the list items).
///
/// The UI Automation element for the parent window.
void CachePropertiesWithScope(AutomationElement elementMain)
{
AutomationElement elementList;
// Set up the CacheRequest.
CacheRequest cacheRequest = new CacheRequest();
cacheRequest.Add(AutomationElement.NameProperty);
cacheRequest.TreeScope = TreeScope.Element | TreeScope.Children;
// Activate the CacheRequest and get the element. Note that the scope of the CacheRequest
// is in relation to the object being retrieved: the list box and its children are
// cached, not the main window and its children.
using (cacheRequest.Activate())
{
// Load the list element and cache the specified properties for its descendants.
Condition cond = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.List);
elementList = elementMain.FindFirst(TreeScope.Children, cond);
}
if (elementList == null) return;
// The following illustrates that the children of the list are in the cache.
foreach (AutomationElement listItem in elementList.CachedChildren)
{
Console.WriteLine(listItem.Cached.Name);
}
// The following call raises an exception, because the IsEnabled property was not cached.
/*** Console.WriteLine(listItem.Cached.IsEnabled); ***/
// The following illustrates that because the list box itself was cached, it is now
// available as the CachedParent of each list item.
AutomationElement child = elementList.CachedChildren[0];
Console.WriteLine(child.CachedParent.Cached.Name);
}
//
#endregion Property retrieval and caching
#region Miscellaneous calls
//
///
/// Retrieves an element in a list, using TreeWalker.
///
/// The list element.
/// The index of the element to find.
/// The list item.
AutomationElement FindChildAt(AutomationElement parent, int index)
{
if (index < 0)
{
throw new ArgumentOutOfRangeException();
}
TreeWalker walker = TreeWalker.ControlViewWalker;
AutomationElement child = walker.GetFirstChild(parent);
for (int x = 1; x <= index; x++)
{
child = walker.GetNextSibling(child);
if (child == null)
{
throw new ArgumentOutOfRangeException();
}
}
return child;
}
///
/// Retrieves an element in a list, using FindAll.
///
/// The list element.
/// The index of the element to find.
/// The list item.
AutomationElement FindChildAtB(AutomationElement parent, int index)
{
Condition findCondition = new PropertyCondition(AutomationElement.IsControlElementProperty, true);
AutomationElementCollection found = parent.FindAll(TreeScope.Children, findCondition);
if ((index < 0) || (index >= found.Count))
{
throw new ArgumentOutOfRangeException();
}
return found[index];
}
//
//
///
/// Finds all enabled buttons in the specified window element.
///
/// An application or dialog window.
/// A collection of elements that meet the conditions.
AutomationElementCollection FindByMultipleConditions(
AutomationElement elementWindowElement)
{
if (elementWindowElement == null)
{
throw new ArgumentException();
}
Condition conditions = new AndCondition(
new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty,
ControlType.Button)
);
// Find all children that match the specified conditions.
AutomationElementCollection elementCollection =
elementWindowElement.FindAll(TreeScope.Children, conditions);
return elementCollection;
}
//
void MiscellaneousCalls(AutomationElement element)
{
String s = element.Current.Name;
//
// element is an AutomationElement.
int[] id = element.GetRuntimeId();
//
//
// element is an AutomationElement.
System.Windows.Point pt;
bool clickable = element.TryGetClickablePoint(out pt);
//
//
// element is an AutomationElement.
System.Windows.Point clickablePoint = element.GetClickablePoint();
System.Windows.Forms.Cursor.Position =
new System.Drawing.Point((int)clickablePoint.X, (int)clickablePoint.Y);
//
//
// element is an AutomationElement.
AutomationPattern[] patterns = element.GetSupportedPatterns();
foreach (AutomationPattern pattern in patterns)
{
Console.WriteLine("ProgrammaticName: " + pattern.ProgrammaticName);
Console.WriteLine("PatternName: " + Automation.PatternName(pattern));
}
//
//
AutomationProperty[] properties = element.GetSupportedProperties();
foreach (AutomationProperty prop in properties)
{
Console.WriteLine(prop.ProgrammaticName);
Console.WriteLine(Automation.PropertyName(prop));
}
//
//
// element is an AutomationElement.
object objPattern;
SelectionPattern selPattern;
if (true == element.TryGetCurrentPattern(SelectionPattern.Pattern, out objPattern))
{
selPattern = objPattern as SelectionPattern;
}
//
AutomationElementCollection elementCollection =
FindByMultipleConditions(MainWindowElement);
//
// elementCollection is an AutomationElementCollection.
AutomationElement[] elementArray = new AutomationElement[elementCollection.Count];
elementCollection.CopyTo(elementArray, 0);
//
//
// elementCollection is an AutomationElementCollection.
object[] elementUntypedArray = new object[elementCollection.Count];
elementCollection.CopyTo(elementUntypedArray, 0);
//
AutomationElement elementElement = elementCollection[0];
//
AutomationElementCollection desktopChildren =
AutomationElement.RootElement.FindAll(
TreeScope.Children, Condition.TrueCondition);
//
//
// desktopChildren is a collection of AutomationElement objects.
AutomationElement firstWindow;
try
{
firstWindow = desktopChildren[0];
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("No AutomationElement at that index.");
}
//
}
#endregion Miscellaneous calls
// this should all be done on a non-UI thread
private void btnMisc_Click(object sender, EventArgs e)
{
Condition cond = new PropertyCondition(AutomationElement.NameProperty, "Tulip");
AutomationElement elementListItem = ListElement.FindFirst(TreeScope.Children, cond);
ShowUsage();
// VISTAONLY GetPhysicalCursorPos(ref pt);
/* Test for a WPF listbox in the window under the cursor.
System.Windows.Point pt = new System.Windows.Point(Cursor.Position.X, Cursor.Position.Y);
AutomationElement wpfListSample = AutomationElement.FromPoint(pt);
Condition cond1 = new PropertyCondition(AutomationElement.ClassNameProperty, "ListBox");
AutomationElement wpfList = wpfListSample.FindFirst(TreeScope.Children, cond1);
Stopwatch watch = new Stopwatch();
watch.Start();
AutomationElement childAt = FindChildAt(wpfList, 9); // way faster
watch.Stop();
Debug.WriteLine(watch.Elapsed.Ticks.ToString());
watch.Reset();
watch.Start();
AutomationElement childAt1 = FindChildAtB(wpfList, 9);
watch.Stop();
Debug.WriteLine(watch.Elapsed.Ticks.ToString());
*/
cond = new PropertyCondition(AutomationElement.AutomationIdProperty, "button1");
AutomationElement elementButton = MainWindowElement.FindFirst(TreeScope.Subtree, cond);
SubscribeToInvoke(elementButton);
//InvokePattern invoker = elementButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
//invoker.Invoke();
// AutomationElement elementList = GetListItemParent(elementListItem);
String s = ListElement.Current.Name;
//SetupComboElement(MainWindowElement);
//MiscellaneousCalls(ListElement);
//AddListItemToSelection(elementListItem);
//CachePropertiesByActivate(elementList);
//CachePropertiesWithScope(MainWindowElement);
//CachePropertiesByPush(elementList);
ConditionSnips cs = new ConditionSnips();
cs.GetTreeWalkerCondition();
//cs.ConditionExamples(MainWindowElement);
//cs.AndConditionExample(MainWindowElement);
//cs.NotConditionExample(MainWindowElement);
//cs.StaticConditionExamples(MainWindowElement);
//MiscPropertyCalls(elementList);
PropertySnips ps = new PropertySnips();
ps.GetAllProperties(elementListItem);
TreeNode treeNode = treeView1.Nodes.Add("Root node");
//WalkControlElements(MainWindowElement, treeNode);
//WalkEnabledElements(MainWindowElement, treeNode);
// Property changes
//cond = new PropertyCondition(AutomationElement.AutomationIdProperty, "btnDisable");
//elementButton = MainWindowElement.FindFirst(TreeScope.Subtree, cond);
// ps.SubscribePropertyChange(elementButton);
}
} // end class
} // end namespace