public Window GetWindow(IntPtr handle) { var interopWindow = InteropWindowFactory.CreateFor(handle); interopWindow.Fill(InteropWindowCacheFlags.Info | InteropWindowCacheFlags.Text); var windowInfo = interopWindow.Info.Value; Dwm.GetExtendedFrameBounds(handle, out var nativeBounds); var innerBounds = (Rectangle)nativeBounds; var outerBounds = (Rectangle)windowInfo.Bounds; Rectangle bounds; Thickness border; if (outerBounds.Width > 0 || outerBounds.Height > 0) { var rawBorder = innerBounds.GetBorder(outerBounds); if (rawBorder.Left < 0 || rawBorder.Top < 0 || rawBorder.Right < 0 || rawBorder.Right < 0) { bounds = new Rectangle( innerBounds.Left - Math.Min(rawBorder.Left, 0), innerBounds.Top - Math.Min(rawBorder.Top, 0), innerBounds.Width - Math.Min(rawBorder.Left, 0) - Math.Min(rawBorder.Right, 0), innerBounds.Height - Math.Min(rawBorder.Top, 0) - Math.Min(rawBorder.Bottom, 0)); border = new Thickness( Math.Max(rawBorder.Left, 0), Math.Max(rawBorder.Top, 0), Math.Max(rawBorder.Right, 0), Math.Max(rawBorder.Bottom, 0)); } else { bounds = innerBounds; border = rawBorder; } } else { bounds = innerBounds; border = Thickness.Empty; } var dpi = (int)NativeDpiMethods.GetDpiForWindow(handle); return(new Window { Handle = handle, Title = interopWindow.Text, Bounds = bounds, Border = border, Dpi = new Point(dpi, dpi), }); }
/// <summary> /// Get the WindowInfo /// </summary> /// <param name="interopWindow">InteropWindow</param> /// <param name="forceUpdate">set to true to make sure the value is updated</param> /// <returns>WindowInfo</returns> public static WindowInfo GetInfo(this IInteropWindow interopWindow, bool forceUpdate = false) { if (interopWindow.Info.HasValue && !forceUpdate) { return(interopWindow.Info.Value); } var windowInfo = WindowInfo.Create(); User32Api.GetWindowInfo(interopWindow.Handle, ref windowInfo); // Now correct the bounds, for Windows 10 if (Dwm.IsDwmEnabled) { NativeRect extendedFrameBounds; bool gotFrameBounds = Dwm.GetExtendedFrameBounds(interopWindow.Handle, out extendedFrameBounds); if (gotFrameBounds && (interopWindow.IsApp() || WindowsVersion.IsWindows10OrLater && !interopWindow.IsMaximized())) { windowInfo.Bounds = extendedFrameBounds; } } interopWindow.Info = windowInfo; return(interopWindow.Info.Value); }
/// <summary> /// Get the WindowInfo /// </summary> /// <param name="interopWindow">InteropWindow</param> /// <param name="forceUpdate">set to true to make sure the value is updated</param> /// <param name="autoCorrect">enable auto correction, e,g, have the bounds cropped to the parent(s)</param> /// <returns>WindowInfo</returns> public static WindowInfo GetInfo(this IInteropWindow interopWindow, bool forceUpdate = false, bool autoCorrect = true) { if (interopWindow.Info.HasValue && !forceUpdate) { return(interopWindow.Info.Value); } var windowInfo = WindowInfo.Create(); User32Api.GetWindowInfo(interopWindow.Handle, ref windowInfo); // Test if we need to correct some values if (autoCorrect) { // Correct the bounds, for Windows 8+ if (Dwm.IsDwmEnabled) { // This only works for top level windows, otherwise a access denied is returned bool gotFrameBounds = Dwm.GetExtendedFrameBounds(interopWindow.Handle, out var extendedFrameBounds); if (gotFrameBounds && (interopWindow.IsApp() || WindowsVersion.IsWindows10OrLater && !interopWindow.IsMaximized())) { windowInfo.Bounds = extendedFrameBounds; } } var parentWindow = interopWindow.GetParentWindow(); if (interopWindow.HasParent) { var parentInfo = parentWindow.GetInfo(forceUpdate, true); windowInfo.Bounds = windowInfo.Bounds.Intersect(parentInfo.Bounds); windowInfo.ClientBounds = windowInfo.ClientBounds.Intersect(parentInfo.ClientBounds); } } interopWindow.Info = windowInfo; return(windowInfo); }