示例#1
0
        /// <summary>
        /// Get an App element from uia
        /// it is trace back to the top most ancestor with same process Id.
        /// </summary>
        /// <param name="e">A11yElement</param>
        /// <returns></returns>
        public static A11yElement GetAppElement(A11yElement e)
        {
            var walker = GetTreeWalker(TreeViewMode.Control);
            var tree   = new DesktopElementAncestry(TreeViewMode.Control, e);

            Marshal.ReleaseComObject(walker);
            A11yElement app = tree.First;

            // make sure that we have an app first
            if (app != null)
            {
                // get first item under Desktop. if app is not Desktop, then it is ok to take it as is.
                if (app.IsRootElement())
                {
                    app = app.Children.First();
                }

                tree.Items.Remove(app);

                tree.Items.ForEach(el => el.Dispose());

                // make sure that Unique ID is set to 0 since this element will be POI.
                app.UniqueId = 0;
            }

            return(app);
        }
示例#2
0
 /// <summary>
 /// Select the specified element if it meets all eligibilty requirements
 /// </summary>
 /// <param name="element">The potential element to select</param>
 /// <returns>true if the element was selected</returns>
 protected bool SelectElementIfItIsEligible(A11yElement element)
 {
     if (element != null && !element.IsRootElement() &&
         !element.IsSameUIElement(SelectedElementRuntimeId, SelectedBoundingRectangle, SelectedControlTypeId, SelectedName))
     {
         SelectedElementRuntimeId  = element.RuntimeId;
         SelectedBoundingRectangle = element.BoundingRectangle;
         SelectedControlTypeId     = element.ControlTypeId;
         SelectedName = element.Name;
         SetElement?.Invoke(element);
         return(true);
     }
     return(false);
 }
示例#3
0
 /// <summary>
 /// Set element for Next selection call
 /// it is for internal use.
 /// </summary>
 /// <param name="el"></param>
 public void SetCandidateElement(A11yElement el)
 {
     lock (this)
     {
         if (el != null)
         {
             if (el.IsRootElement() == false)
             {
                 this.CandidateEC?.Dispose();
                 this.CandidateEC = new ElementContext(el);
             }
             else
             {
                 el.Dispose();
             }
         }
     }
 }
        /// <summary>
        /// Set Parent to build ancestry tree
        /// </summary>
        /// <param name="e"></param>
        /// <param name="uniqueId"></param>
        private void SetParent(A11yElement e, int uniqueId)
        {
            if (e == null || e.PlatformObject == null || e.IsRootElement())
            {
                return;
            }

            try
            {
                var puia = this.TreeWalker.GetParentElement((IUIAutomationElement)e.PlatformObject);
                if (puia == null)
                {
                    return;
                }

#pragma warning disable CA2000 // Call IDisposable.Dispose()
                var parent = new DesktopElement(puia, true, SetMembers);
                parent.PopulateMinimumPropertiesForSelection();

                // we need to avoid infinite loop of self reference as parent.
                // it is a probably a bug in UIA or the target app.
                if (e.IsSameUIElement(parent) == false)
                {
                    parent.IsAncestorOfSelected = true;
                    parent.Children.Add(e);
                    e.Parent = parent;
                    this.Items.Add(parent);
                    parent.UniqueId = uniqueId;

                    SetParent(parent, uniqueId - 1);
                }
#pragma warning restore CA2000
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
            {
                ex.ReportException();
                // ignore to show the best efforts.
                System.Diagnostics.Trace.WriteLine(ex);
            }
#pragma warning restore CA1031 // Do not catch general exception types
        }
        /// <summary>
        /// Gets window that is eventual parent of element. If there is no window parent, get
        /// highest element that isn't desktop and has a bounding rectangle
        /// </summary>
        /// <param name="el"></param>
        /// <returns></returns>
        public static A11yElement GetParentWindow(this A11yElement el)
        {
            A11yElement prev = null;
            A11yElement curr = el;

            while (curr != null && curr.Parent != null && curr.ControlTypeId != ControlType.UIA_WindowControlTypeId && !curr.IsRootElement())
            {
                prev = curr;
                curr = curr.Parent;
            }

            if (curr.ControlTypeId != ControlType.UIA_WindowControlTypeId && prev != null)
            {
                curr = prev;
                while (curr.UniqueId < -1 && curr.Children?[0].BoundingRectangle == null)
                {
                    if (curr.Children.Count > 0)
                    {
                        curr = curr.Children[0];
                    }
                    else
                    {
                        // if no elements have bounding rectangles, give up
                        break;
                    }
                }
            }
            return(curr);
        }