private static Rect GetBoundingRect(User32.HWND owningWindow, Rect windowBounds, AutomationElement automationElement) { var boundingRectObject = automationElement.GetCurrentPropertyValue(AutomationElement.BoundingRectangleProperty, true); if (boundingRectObject == AutomationElement.NotSupported) { // Not supported return(Rect.Empty); } var boundingRect = (Rect)boundingRectObject; if (boundingRect.IsEmpty) { // Not currently displaying UI return(Rect.Empty); } // Convert the bounding rect to logical coords var logicalRect = boundingRect.PhysicalToLogicalRect(owningWindow); if (!logicalRect.IsEmpty) { var windowCoords = boundingRect.ScreenToWindowCoordinates(windowBounds); return(windowCoords); } return(Rect.Empty); }
/// <summary> /// Enumerate the available hints for the given window /// </summary> /// <param name="hWnd">The window handle of window to enumerate hints in</param> /// <returns>The hint session containing the available hints</returns> public HintSession EnumHints(User32.HWND hWnd) { var sw = new Stopwatch(); sw.Start(); var elements = EnumElements(hWnd); sw.Stop(); Console.WriteLine(sw.Elapsed); // Window bounds var rawWindowBounds = new RECT(); User32.GetWindowRect(hWnd, ref rawWindowBounds); Rect windowBounds = rawWindowBounds; sw.Reset(); sw.Start(); var result = new List <Hint>(); foreach (AutomationElement element in elements) { result.Add(new UiAutomationHint(hWnd, windowBounds, element)); } sw.Stop(); Console.WriteLine(sw.Elapsed); return(new HintSession { Hints = result.Where(hint => !hint.BoundingRectangle.IsEmpty).ToList(), OwningWindow = hWnd, OwningWindowBounds = windowBounds, }); }
/// <summary> /// Enumerates the automation elements from the given window /// </summary> /// <param name="hWnd">The window handle</param> /// <returns>All of the automation elements found</returns> private AutomationElementCollection EnumElements(User32.HWND hWnd) { var automationElement = AutomationElement.FromHandle(hWnd.DangerousGetHandle()); var condition = new AndCondition(new PropertyCondition(AutomationElement.IsOffscreenProperty, false), new PropertyCondition(AutomationElement.IsEnabledProperty, true), // Filter out non-invoke patterns to speed this up as this can be slow for large windows new PropertyCondition(AutomationElement.IsInvokePatternAvailableProperty, true) ); return(automationElement.FindAll(TreeScope.Descendants, condition)); }
/// <summary> /// Converts physical screen to logical screen coordinates given a rectangle /// </summary> /// <param name="source">The source rectangle</param> /// <param name="hWnd">The window handle to use for conversion</param> /// <returns>The rectangle in logical coordinates, else an empty rectangle</returns> public static Rect PhysicalToLogicalRect(this Rect source, User32.HWND hWnd) { POINT tl = source.TopLeft; POINT br = source.BottomRight; if (User32.PhysicalToLogicalPoint(hWnd, out tl) && User32.PhysicalToLogicalPoint(hWnd, out br)) { return(new Rect(tl, br)); } return(Rect.Empty); }
private IntPtr?HandleWindowMessage(User32.HWND hWnd, uint msg, IntPtr wparam, IntPtr lparam) { if (msg == Constants.WM_HOTKEY) { var e = new HotKeyEventArgs(lparam); if (e.Key == _hotKey.Keys && e.Modifiers == _hotKey.Modifier) { OnHotKeyActivated?.Invoke(this, new EventArgs()); } } return(null); }
public UiAutomationHint(User32.HWND owningWindow, Rect windowBounds, AutomationElement automationElement) : base(owningWindow, GetBoundingRect(owningWindow, windowBounds, automationElement)) { AutomationElement = automationElement; if (BoundingRectangle.IsEmpty) { return; } _invokePattern = new Lazy <InvokePattern>(() => TryGetInvokePattern(automationElement)); _accessKey = new Lazy <string>( () => automationElement.GetCurrentPropertyValue(AutomationElement.AccessKeyProperty, true) as string); }
/// <summary> /// Forces the window to the foreground by attaching to the foreground window thread /// </summary> private void ForceForeground() { // This is required as there's a few restrictions on when this can be called // Per https://msdn.microsoft.com/en-us/library/windows/desktop/ms633539%28v=vs.85%29.aspx var targetThread = User32.GetWindowThreadProcessId(User32.GetForegroundWindow(), IntPtr.Zero); var appThread = Kernel32.GetCurrentThreadId(); var attached = false; try { if (targetThread == appThread) { // already attached return; } attached = User32.AttachThreadInput(targetThread, appThread, true); if (!attached) { // hmm Close(); return; } var ourHandle = new User32.HWND(new WindowInteropHelper(this).Handle); // force us to the forground User32.BringWindowToTop(ourHandle); User32.SetFocus(ourHandle); } finally { if (attached) { // unattach User32.AttachThreadInput(targetThread, appThread, false); } } }
/// <summary> /// Ctor /// </summary> /// <param name="owningWindow">The owning window</param> /// <param name="boundingRectangle">The bounding rectangle of the hint in owner window coordinates</param> protected Hint(User32.HWND owningWindow, Rect boundingRectangle) { OwningWindow = owningWindow; BoundingRectangle = boundingRectangle; }