bool IEnumerator.MoveNext() { if (_cancellationToken.IsCancellationRequested) { return(false); } if (_elementQueue.Count == 0) { return(false); } _current = _elementQueue.Dequeue(); AutomationElement childAutomationElement = TreeWalker.ControlViewWalker.GetFirstChild(_current, _cancellationToken); while (childAutomationElement != null) { if (_cancellationToken.IsCancellationRequested) { return(false); } if (_controlType.CanBeNestedUnder(childAutomationElement)) { _elementQueue.Enqueue(childAutomationElement); } childAutomationElement = TreeWalker.ControlViewWalker.GetNextSibling(childAutomationElement); } return(true); }
public ChildIterator(string name, AutomationElement automationElement, CancellationToken cancellationToken) { _automationElement = automationElement; _cancellationToken = cancellationToken; // tree walker is used instead of FindAll, FindAll cannot be "interrupted" _treeWalker = TreeWalker.ControlViewWalker; /* using "plain" ControlViewWalker because the advanced one with conditions is taking too long to complete * and sometimes it returns elements that are coming from a different subtree - which can be avoided by comparing parent * of the element with automationElement, but that will reduce speed * overall the reason is unknown * new TreeWalker(new AndCondition( * Automation.ControlViewCondition, * // treewalker was jumping around to another windows * new PropertyCondition(AutomationElement.ProcessIdProperty, automationElement.Current.ProcessId), * // return only the elements that are visible * //new PropertyCondition(AutomationElement.IsOffscreenProperty, false), * condition));* */ var automationId = automationElement.Current.AutomationId; var condition = Condition.TrueCondition; if (name != null) { controlType = name.AsControlType(); condition = new PropertyCondition(AutomationElement.ControlTypeProperty, controlType); if (!controlType.CanBeNestedUnder(automationElement.Current.ControlType)) { condition = Condition.FalseCondition; _empty = true; } } }
bool IEnumerator.MoveNext() { if (_cancellationToken.IsCancellationRequested) { return(false); } /*if (_matching.Any()) * { * Current = _matching.Dequeue(); * return true; * }*/ if (_elementQueue.Count == 0) { return(false); } _current = _elementQueue.Dequeue(); AutomationElement childAutomationElement = TreeWalker.ControlViewWalker.GetFirstChild(_current); /*var children = _current.FindAll(TreeScope.Children, Condition.TrueCondition).Cast<AutomationElement>() * .OrderBy(c => c.Current.BoundingRectangle.TopLeft, new PointComparer()) * .ToList();*/ //System.Diagnostics.Debug.WriteLine($"FindElements by type {_controlType.ProgrammaticName}, root {_current.ToDiagString()} ... ({children.Count()})"); while (childAutomationElement != null) { if (_cancellationToken.IsCancellationRequested) { return(false); } if (_controlType.CanBeNestedUnder(childAutomationElement)) { _elementQueue.Enqueue(childAutomationElement); } childAutomationElement = TreeWalker.ControlViewWalker.GetNextSibling(childAutomationElement); } /* * foreach (AutomationElement automationElement in children) * { * if (_cancellationToken.IsCancellationRequested) * { * return false; * } * * if (!_controlType.CanBeNestedUnder(automationElement)) * { * continue; * } * * _elementQueue.Enqueue(automationElement); * }*/ return(true); }
bool IEnumerator.MoveNext() { if (_cancellationToken.IsCancellationRequested) { return(false); } if (_elementQueue.Count == 0) { return(false); } _current = _elementQueue.Dequeue(); AutomationElement childAutomationElement = TreeWalker.ControlViewWalker.GetFirstChild(_current, _cancellationToken); while (childAutomationElement != null) { if (_cancellationToken.IsCancellationRequested) { return(false); } if (_controlType.CanBeNestedUnder(childAutomationElement)) { _elementQueue.Enqueue(childAutomationElement); } // sometimes the app can stop responding when performing long operation thanks to poor designed // try to wait for the response in a loop while (true) { if (_cancellationToken.IsCancellationRequested) { return(false); } try { childAutomationElement = TreeWalker.ControlViewWalker.GetNextSibling(childAutomationElement); break; } catch (System.Runtime.InteropServices.COMException comEx) when(comEx.IsTimeout()) { // retry after a short sleep Thread.Sleep(TimeSpan.FromMilliseconds(250)); // childAutomationElement = TreeWalker.ControlViewWalker.GetNextSibling(childAutomationElement); } } } return(true); }