private IUIAutomationElement GetNearbyElement(GetElementDelegate getNextElement) { var currentElement = GetCurrentElement(); if (currentElement == null) { return(null); } var treeWalker = A11yAutomation.GetTreeWalker(this.TreeViewMode); var retVal = getNextElement?.Invoke(treeWalker, currentElement); // make sure that we skip an element from current process while walking tree. // this code should be hit only at App level. but for sure. if (DesktopElement.IsFromCurrentProcess(retVal)) { var tmp = retVal; retVal = getNextElement?.Invoke(treeWalker, retVal); // since element is not in use, release. Marshal.ReleaseComObject(tmp); } Marshal.ReleaseComObject(treeWalker); return(retVal); }
/// <summary> /// Call this function to find a nearby element and update SelectAction if successful. /// This function is the starting point for the navigation logic of this class. /// </summary> /// <param name="getElementMethod"> /// a delegate used to find the next nearby element. /// </param> private void MoveTo(GetElementDelegate getElementMethod) { lock (this) { _MoveTo(getElementMethod); } }
/// <summary> /// Call this function to find a nearby element and update SelectAction if successful. /// This function is the starting point for the navigation logic of this class. /// </summary> /// <param name="getElementMethod"> /// a delegate used to find the next nearby element. /// </param> private void MoveTo(GetElementDelegate getElementMethod) { lock (_movementLock) { _MoveTo(getElementMethod); } }
/// <summary> /// Do not call this function directly. Instead, call MoveTo(). /// </summary> /// <param name="getElementMethod"></param> private void _MoveTo(GetElementDelegate getElementMethod) { var element = GetNearbyElement(getElementMethod); if (element == null) { throw new TreeNavigationFailedException(); } #pragma warning disable CA2000 // Call IDisposable.Dispose() var desktopElement = new DesktopElement(element, true, false); #pragma warning restore CA2000 desktopElement.PopulateMinimumPropertiesForSelection(); if (desktopElement.IsRootElement() == false) { this.SelectAction?.SetCandidateElement(desktopElement); this.SelectAction?.Select(); } else { // if it is desktop, release it. desktopElement.Dispose(); throw new TreeNavigationFailedException(); } }
static JSCompileOptions() { GetElement = getElement; GetElementAttributeName = getElementAttributeName; GetIntroductionScript = getIntroductionScript; DefaultVTable = new VTable { element = Marshal.GetFunctionPointerForDelegate(GetElement), elementAttributeName = Marshal.GetFunctionPointerForDelegate(GetElementAttributeName), introductionScript = Marshal.GetFunctionPointerForDelegate(GetIntroductionScript), }; pDefaultVTable = Marshal.AllocHGlobal(Marshal.SizeOf(DefaultVTable)); Marshal.StructureToPtr(DefaultVTable, pDefaultVTable, false); Default = new JSCompileOptions(); }