18using System.Collections.Generic;
19using System.Collections.ObjectModel;
20using System.Diagnostics;
23using System.Threading.Tasks;
24using System.Windows.Automation;
25using System.Windows.Automation.Peers;
30 internal static class AutomationElementExtension
32 public static ReadOnlyCollection<GPALAutomationElement> FindElements(
33 this AutomationElement element,
35 ConditionPropertyType conditionPropertyType,
40 throw new ArgumentNullException(nameof(element));
42 PropertyCondition condition =
null;
43 ControlType controlType =
null;
45 switch (conditionPropertyType)
47 case ConditionPropertyType.AutomationID:
48 condition =
new PropertyCondition(AutomationElement.AutomationIdProperty, findByString);
50 case ConditionPropertyType.ClassName:
51 condition =
new PropertyCondition(AutomationElement.ClassNameProperty, findByString);
53 case ConditionPropertyType.ControlType:
54 controlType = GetControlType(findByString);
55 condition =
new PropertyCondition(AutomationElement.ControlTypeProperty, controlType);
57 case ConditionPropertyType.Name:
58 condition =
new PropertyCondition(AutomationElement.NameProperty, findByString);
60 case ConditionPropertyType.Value:
61 condition =
new PropertyCondition(ValuePattern.ValueProperty, findByString);
64 throw new ArgumentException(
"Unsupported ConditionPropertyType");
67 TreeScope treeScope = isRoot ? TreeScope.Subtree : TreeScope.Children;
69 List<GPALAutomationElement> tmpElems =
new List<GPALAutomationElement>();
73 AutomationElement found = element.FindFirst(treeScope, condition);
75 tmpElems.Add(
new GPALAutomationElement(found));
80 List<AutomationElement> automationElements = GetAllChildren(element, idx, controlType);
81 foreach (AutomationElement elem
in automationElements)
82 tmpElems.Add(
new GPALAutomationElement(elem));
85 return new ReadOnlyCollection<GPALAutomationElement>(tmpElems);
155 private static List<AutomationElement> GetAllChildren(AutomationElement rootElement,
int idx, ControlType controlType)
157 Condition condition =
new PropertyCondition(AutomationElement.IsControlElementProperty,
true);
158 TreeWalker walker =
new TreeWalker(condition);
159 AutomationElement elementNode = walker.GetFirstChild(rootElement);
162 if (
null == elementNode)
return null;
164 List<AutomationElement> automationElements =
new List<AutomationElement>();
166 while (elementNode !=
null && cnt <= idx)
168 if (controlType == elementNode.Current.ControlType)
170 automationElements.Add(elementNode);
174 elementNode = walker.GetNextSibling(elementNode);
177 return automationElements;
186 public static string GetValue(
this AutomationElement element)
188 string retVal =
null;
190 if (element.TryGetCurrentPattern(ValuePattern.Pattern, out
object patternObj))
191 retVal = ((ValuePattern)patternObj).Current.Value;
196 public static string GetText(
this AutomationElement element)
216 if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj))
218 var textPattern = (TextPattern)patternObj;
219 retVal = textPattern.DocumentRange.GetText(-1).TrimEnd(
'\r');
220 answeredBy =
"TextPattern";
222 else if (element.TryGetCurrentPattern(ValuePattern.Pattern, out patternObj))
224 var valuePattern = (ValuePattern)patternObj;
225 retVal = valuePattern.Current.Value;
226 answeredBy =
"ValuePattern, which a provider may truncate";
230 retVal = element.Current.Name;
231 answeredBy =
"Name, because the control offers neither TextPattern nor ValuePattern";
236 GPAL.PublishSimpleEvent(GPALEventType.DEBUG, $
"[{element.Current.LocalizedControlType}] text of [{retVal?.Length ?? 0}] characters came from {answeredBy}.",
null, GPALObjectType.Application);
241 internal static ControlType GetControlType(
string controlTypeString)
243 if (
null == controlTypeString)
return null;
245 AutomationControlType typeEnum;
246 bool result = Enum.TryParse(controlTypeString,
true, out typeEnum);
247 if (result) typeEnum = (AutomationControlType)Enum.Parse(typeof(AutomationControlType), controlTypeString);
248 int enumId = (int)typeEnum + 50000;
249 ControlType controlType = ControlType.LookupById(enumId);