private void _ExtendGlassFrame() { if (Utility.IsOSVistaOrNewer && IntPtr.Zero != _hwnd) { if (!NativeMethods.DwmIsCompositionEnabled()) { _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { _hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; var point = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Left, _chromeInfo.GlassFrameThickness.Top)); var point2 = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Right, _chromeInfo.GlassFrameThickness.Bottom)); var pMarInset = new MARGINS { cxLeftWidth = (int)Math.Ceiling(point.X), cxRightWidth = (int)Math.Ceiling(point2.X), cyTopHeight = (int)Math.Ceiling(point.Y), cyBottomHeight = (int)Math.Ceiling(point2.Y) }; NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref pMarInset); } } }
public static void ShowSystemMenu(Window window, Point screenLocation) { Verify.IsNotNull <Window>(window, "window"); DpiScale dpi = window.GetDpi(); SystemCommands.ShowSystemMenuPhysicalCoordinates(window, DpiHelper.LogicalPixelsToDevice(screenLocation, dpi.DpiScaleX, dpi.DpiScaleY)); }
private void _ExtendGlassFrame() { if (!Utility.IsOSVistaOrNewer) { return; } if (IntPtr.Zero == this._hwnd) { return; } if (!NativeMethods.DwmIsCompositionEnabled()) { this._hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; return; } this._hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; Point point = DpiHelper.LogicalPixelsToDevice(new Point(this._chromeInfo.GlassFrameThickness.Left, this._chromeInfo.GlassFrameThickness.Top)); Point point2 = DpiHelper.LogicalPixelsToDevice(new Point(this._chromeInfo.GlassFrameThickness.Right, this._chromeInfo.GlassFrameThickness.Bottom)); MARGINS margins = new MARGINS { cxLeftWidth = (int)Math.Ceiling(point.X), cxRightWidth = (int)Math.Ceiling(point2.X), cyTopHeight = (int)Math.Ceiling(point.Y), cyBottomHeight = (int)Math.Ceiling(point2.Y) }; NativeMethods.DwmExtendFrameIntoClientArea(this._hwnd, ref margins); }
/// <summary>Display the system menu at a specified location.</summary> /// <param name="window">The MetroWindow</param> /// <param name="screenLocation">The location to display the system menu, in logical screen coordinates.</param> public static void ShowSystemMenu(Window window, Point screenLocation) { Verify.IsNotNull(window, "window"); // Using fixed dpi scaling here because the menu gets placed way off otherwise ShowSystemMenuPhysicalCoordinates(window, DpiHelper.LogicalPixelsToDevice(screenLocation, 1, 1)); }
public static Rect LogicalRectToDevice(Rect logicalRectangle) { Point point = DpiHelper.LogicalPixelsToDevice(new Point(logicalRectangle.Left, logicalRectangle.Top)); Point point2 = DpiHelper.LogicalPixelsToDevice(new Point(logicalRectangle.Right, logicalRectangle.Bottom)); return(new Rect(point, point2)); }
private void _ExtendGlassFrame() { if (!Utility.IsOSVistaOrNewer) { return; } if (IntPtr.Zero == this._hwnd) { return; } if (!Standard.NativeMethods.DwmIsCompositionEnabled()) { this._hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; return; } this._hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; double left = this._chromeInfo.GlassFrameThickness.Left; Thickness glassFrameThickness = this._chromeInfo.GlassFrameThickness; Point device = DpiHelper.LogicalPixelsToDevice(new Point(left, glassFrameThickness.Top)); double right = this._chromeInfo.GlassFrameThickness.Right; glassFrameThickness = this._chromeInfo.GlassFrameThickness; Point point = DpiHelper.LogicalPixelsToDevice(new Point(right, glassFrameThickness.Bottom)); MARGINS mARGIN = new MARGINS() { cxLeftWidth = (int)Math.Ceiling(device.X), cxRightWidth = (int)Math.Ceiling(point.X), cyTopHeight = (int)Math.Ceiling(device.Y), cyBottomHeight = (int)Math.Ceiling(point.Y) }; MARGINS mARGIN1 = mARGIN; Standard.NativeMethods.DwmExtendFrameIntoClientArea(this._hwnd, ref mARGIN1); }
public static void ShowSystemMenu(Visual visual, Point elementPoint) { Verify.IsNotNull(visual, "visual"); var screenLocation = visual.PointToScreen(elementPoint); var dpi = visual.GetDpi(); ShowSystemMenuPhysicalCoordinates(visual, DpiHelper.LogicalPixelsToDevice(screenLocation, dpi.DpiScaleX, dpi.DpiScaleY)); }
/// <summary> /// Create a Device Margins struct from a (DPI-aware) Logical Thickness /// </summary> /// <param name="t">The Thickness to convert</param> public Margins(System.Windows.Thickness t) { t = DpiHelper.LogicalPixelsToDevice(t); Left = (int)Math.Ceiling(t.Left); Right = (int)Math.Ceiling(t.Right); Top = (int)Math.Ceiling(t.Top); Bottom = (int)Math.Ceiling(t.Bottom); }
public static Size LogicalSizeToDevice(Size logicalSize) { Point point = DpiHelper.LogicalPixelsToDevice(new Point(logicalSize.Width, logicalSize.Height)); return(new Size { Width = point.X, Height = point.Y }); }
private IntPtr _WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch ((WM)msg) { case WM.SIZE: const int SIZE_MAXIMIZED = 2; // No, you didn't. Even if you think you did, you didn't. if (wParam.ToInt32() == SIZE_MAXIMIZED) { NativeMethods.PostMessage(hwnd, WM.SYSCOMMAND, new IntPtr((int)SC.RESTORE), IntPtr.Zero); } break; case WM.NCACTIVATE: handled = true; // Need to do this to prevent the chrome from flickering on deactivate. return(NativeMethods.DefWindowProc(hwnd, WM.NCACTIVATE, wParam, new IntPtr(-1))); case WM.GETMINMAXINFO: // We have WS_THICKFRAME to enable the glass frame but really this should be a fixed size. var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); Point devSize = DpiHelper.LogicalPixelsToDevice(new Point(ActualWidth, ActualHeight)); var pt = new POINT { x = (int)devSize.X, y = (int)devSize.Y }; mmi.ptMinTrackSize = pt; mmi.ptMaxTrackSize = pt; mmi.ptMaxSize = pt; Marshal.StructureToPtr(mmi, lParam, false); handled = true; return(IntPtr.Zero); case WM.NCCALCSIZE: // WM_NCCALCSIZE gives the window dimensions in the lParam and expects the client dimensions in the same field on return. // By not modifying it and signaling the message as handled, we can use the entire window dimensions as our client area. handled = true; return(IntPtr.Zero); case WM.DWMCOMPOSITIONCHANGED: _TryExtendGlass(hwnd); // Empirically it looks like these (or at least the no-peek flag) need to be reapplied when glass composition changes. // Haven't found this documented, may be a bug in Windows. _SetDwmAttributes(hwnd); handled = false; return(IntPtr.Zero); } handled = false; return(IntPtr.Zero); }
/// <summary>Display the system menu at a specified location.</summary> /// <param name="screenLocation">The location to display the system menu, in logical screen coordinates.</param> public static void ShowSystemMenu(Window window, Point screenLocation) { Verify.IsNotNull(window, "window"); ShowSystemMenuPhysicalCoordinates(window, DpiHelper.LogicalPixelsToDevice(screenLocation)); }
private void _SetRoundingRegion(WINDOWPOS?wp) { if (NativeMethods.GetWindowPlacement(_hwnd).showCmd == SW.SHOWMAXIMIZED) { int x; int y; if (wp.HasValue) { x = wp.Value.x; y = wp.Value.y; } else { var rect = _GetWindowRect(); x = (int)rect.Left; y = (int)rect.Top; } var rcWork = NativeMethods.GetMonitorInfo(NativeMethods.MonitorFromWindow(_hwnd, 2)).rcWork; rcWork.Offset(-x, -y); var zero = IntPtr.Zero; try { zero = NativeMethods.CreateRectRgnIndirect(rcWork); NativeMethods.SetWindowRgn(_hwnd, zero, NativeMethods.IsWindowVisible(_hwnd)); zero = IntPtr.Zero; } finally { Utility.SafeDeleteObject(ref zero); } } else { Size size; if (wp.HasValue && !Utility.IsFlagSet(wp.Value.flags, 1)) { size = new Size(wp.Value.cx, wp.Value.cy); } else { if (wp.HasValue && _lastRoundingState == _window.WindowState) { return; } size = _GetWindowRect().Size; } _lastRoundingState = _window.WindowState; var hrgnSource = IntPtr.Zero; try { var num3 = Math.Min(size.Width, size.Height); var radius = Math.Min(DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.TopLeft, 0.0)).X, num3 / 2.0); if (_IsUniform(_chromeInfo.CornerRadius)) { hrgnSource = _CreateRoundRectRgn(new Rect(size), radius); } else { hrgnSource = _CreateRoundRectRgn( new Rect(0.0, 0.0, size.Width / 2.0 + radius, size.Height / 2.0 + radius), radius); var num5 = Math.Min( DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.TopRight, 0.0)).X, num3 / 2.0); var region = new Rect(0.0, 0.0, size.Width / 2.0 + num5, size.Height / 2.0 + num5); region.Offset(size.Width / 2.0 - num5, 0.0); _CreateAndCombineRoundRectRgn(hrgnSource, region, num5); var num6 = Math.Min( DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.BottomLeft, 0.0)).X, num3 / 2.0); var rect4 = new Rect(0.0, 0.0, size.Width / 2.0 + num6, size.Height / 2.0 + num6); rect4.Offset(0.0, size.Height / 2.0 - num6); _CreateAndCombineRoundRectRgn(hrgnSource, rect4, num6); var num7 = Math.Min( DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.BottomRight, 0.0)).X, num3 / 2.0); var rect5 = new Rect(0.0, 0.0, size.Width / 2.0 + num7, size.Height / 2.0 + num7); rect5.Offset(size.Width / 2.0 - num7, size.Height / 2.0 - num7); _CreateAndCombineRoundRectRgn(hrgnSource, rect5, num7); } NativeMethods.SetWindowRgn(_hwnd, hrgnSource, NativeMethods.IsWindowVisible(_hwnd)); hrgnSource = IntPtr.Zero; } finally { Utility.SafeDeleteObject(ref hrgnSource); } } }
public static void ShowSystemMenu(Window window, Point screenLocation) { Verify.IsNotNull <Window>(window, "window"); Microsoft.Windows.Shell.SystemCommands.ShowSystemMenuPhysicalCoordinates(window, DpiHelper.LogicalPixelsToDevice(screenLocation)); }
private void _SetRoundingRegion(WINDOWPOS?wp) { const int MONITOR_DEFAULTTONEAREST = 0x00000002; var wpl = NativeMethods.GetWindowPlacement(_hwnd); if (wpl.showCmd == SW.SHOWMAXIMIZED) { int left; int top; if (wp.HasValue) { left = wp.Value.x; top = wp.Value.y; } else { var r = _GetWindowRect(); left = (int)r.Left; top = (int)r.Top; } var hMon = NativeMethods.MonitorFromWindow(_hwnd, MONITOR_DEFAULTTONEAREST); var mi = NativeMethods.GetMonitorInfo(hMon); var rcMax = mi.rcWork; rcMax.Offset(-left, -top); var hrgn = IntPtr.Zero; try { hrgn = NativeMethods.CreateRectRgnIndirect(rcMax); NativeMethods.SetWindowRgn(_hwnd, hrgn, NativeMethods.IsWindowVisible(_hwnd)); hrgn = IntPtr.Zero; } finally { Utility.SafeDeleteObject(ref hrgn); } } else { Size windowSize; if (null != wp && !Utility.IsFlagSet(wp.Value.flags, (int)SWP.NOSIZE)) { windowSize = new Size(wp.Value.cx, wp.Value.cy); } else if (null != wp && (_lastRoundingState == _window.WindowState)) { return; } else { windowSize = _GetWindowRect().Size; } _lastRoundingState = _window.WindowState; var hrgn = IntPtr.Zero; try { var shortestDimension = Math.Min(windowSize.Width, windowSize.Height); var topLeftRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.TopLeft, 0)).X; topLeftRadius = Math.Min(topLeftRadius, shortestDimension / 2); if (_IsUniform(_chromeInfo.CornerRadius)) { hrgn = _CreateRoundRectRgn(new Rect(windowSize), topLeftRadius); } else { hrgn = _CreateRoundRectRgn(new Rect(0, 0, windowSize.Width / 2 + topLeftRadius, windowSize.Height / 2 + topLeftRadius), topLeftRadius); var topRightRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.TopRight, 0)).X; topRightRadius = Math.Min(topRightRadius, shortestDimension / 2); var topRightRegionRect = new Rect(0, 0, windowSize.Width / 2 + topRightRadius, windowSize.Height / 2 + topRightRadius); topRightRegionRect.Offset(windowSize.Width / 2 - topRightRadius, 0); Assert.AreEqual(topRightRegionRect.Right, windowSize.Width); _CreateAndCombineRoundRectRgn(hrgn, topRightRegionRect, topRightRadius); var bottomLeftRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.BottomLeft, 0)).X; bottomLeftRadius = Math.Min(bottomLeftRadius, shortestDimension / 2); var bottomLeftRegionRect = new Rect(0, 0, windowSize.Width / 2 + bottomLeftRadius, windowSize.Height / 2 + bottomLeftRadius); bottomLeftRegionRect.Offset(0, windowSize.Height / 2 - bottomLeftRadius); Assert.AreEqual(bottomLeftRegionRect.Bottom, windowSize.Height); _CreateAndCombineRoundRectRgn(hrgn, bottomLeftRegionRect, bottomLeftRadius); var bottomRightRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.BottomRight, 0)).X; bottomRightRadius = Math.Min(bottomRightRadius, shortestDimension / 2); var bottomRightRegionRect = new Rect(0, 0, windowSize.Width / 2 + bottomRightRadius, windowSize.Height / 2 + bottomRightRadius); bottomRightRegionRect.Offset(windowSize.Width / 2 - bottomRightRadius, windowSize.Height / 2 - bottomRightRadius); Assert.AreEqual(bottomRightRegionRect.Right, windowSize.Width); Assert.AreEqual(bottomRightRegionRect.Bottom, windowSize.Height); _CreateAndCombineRoundRectRgn(hrgn, bottomRightRegionRect, bottomRightRadius); } NativeMethods.SetWindowRgn(_hwnd, hrgn, NativeMethods.IsWindowVisible(_hwnd)); hrgn = IntPtr.Zero; } finally { Utility.SafeDeleteObject(ref hrgn); } } }
private void _SetRoundingRegion(WINDOWPOS?wp) { WINDOWPLACEMENT windowPlacement = NativeMethods.GetWindowPlacement(this._hwnd); if (windowPlacement.showCmd == SW.SHOWMAXIMIZED) { int num; int num2; if (wp != null) { num = wp.Value.x; num2 = wp.Value.y; } else { Rect rect = this._GetWindowRect(); num = (int)rect.Left; num2 = (int)rect.Top; } IntPtr hMonitor = NativeMethods.MonitorFromWindow(this._hwnd, 2u); MONITORINFO monitorInfo = NativeMethods.GetMonitorInfo(hMonitor); RECT rcWork = monitorInfo.rcWork; rcWork.Offset(-num, -num2); IntPtr hRgn = IntPtr.Zero; try { hRgn = NativeMethods.CreateRectRgnIndirect(rcWork); NativeMethods.SetWindowRgn(this._hwnd, hRgn, NativeMethods.IsWindowVisible(this._hwnd)); hRgn = IntPtr.Zero; return; } finally { Utility.SafeDeleteObject(ref hRgn); } } Size size; if (wp != null && !Utility.IsFlagSet(wp.Value.flags, 1)) { size = new Size((double)wp.Value.cx, (double)wp.Value.cy); } else { if (wp != null && this._lastRoundingState == this._window.WindowState) { return; } size = this._GetWindowRect().Size; } this._lastRoundingState = this._window.WindowState; IntPtr intPtr = IntPtr.Zero; try { double num3 = Math.Min(size.Width, size.Height); double num4 = DpiHelper.LogicalPixelsToDevice(new Point(this._chromeInfo.CornerRadius.TopLeft, 0.0)).X; num4 = Math.Min(num4, num3 / 2.0); if (WindowChromeWorker._IsUniform(this._chromeInfo.CornerRadius)) { intPtr = WindowChromeWorker._CreateRoundRectRgn(new Rect(size), num4); } else { intPtr = WindowChromeWorker._CreateRoundRectRgn(new Rect(0.0, 0.0, size.Width / 2.0 + num4, size.Height / 2.0 + num4), num4); double num5 = DpiHelper.LogicalPixelsToDevice(new Point(this._chromeInfo.CornerRadius.TopRight, 0.0)).X; num5 = Math.Min(num5, num3 / 2.0); Rect region = new Rect(0.0, 0.0, size.Width / 2.0 + num5, size.Height / 2.0 + num5); region.Offset(size.Width / 2.0 - num5, 0.0); WindowChromeWorker._CreateAndCombineRoundRectRgn(intPtr, region, num5); double num6 = DpiHelper.LogicalPixelsToDevice(new Point(this._chromeInfo.CornerRadius.BottomLeft, 0.0)).X; num6 = Math.Min(num6, num3 / 2.0); Rect region2 = new Rect(0.0, 0.0, size.Width / 2.0 + num6, size.Height / 2.0 + num6); region2.Offset(0.0, size.Height / 2.0 - num6); WindowChromeWorker._CreateAndCombineRoundRectRgn(intPtr, region2, num6); double num7 = DpiHelper.LogicalPixelsToDevice(new Point(this._chromeInfo.CornerRadius.BottomRight, 0.0)).X; num7 = Math.Min(num7, num3 / 2.0); Rect region3 = new Rect(0.0, 0.0, size.Width / 2.0 + num7, size.Height / 2.0 + num7); region3.Offset(size.Width / 2.0 - num7, size.Height / 2.0 - num7); WindowChromeWorker._CreateAndCombineRoundRectRgn(intPtr, region3, num7); } NativeMethods.SetWindowRgn(this._hwnd, intPtr, NativeMethods.IsWindowVisible(this._hwnd)); intPtr = IntPtr.Zero; } finally { Utility.SafeDeleteObject(ref intPtr); } }
private void _SetRoundingRegion(WINDOWPOS?wp) { int left; int top; Size size; if (Standard.NativeMethods.GetWindowPlacement(this._hwnd).showCmd != SW.SHOWMAXIMIZED) { if (!wp.HasValue || Utility.IsFlagSet(wp.Value.flags, 1)) { if (wp.HasValue && this._lastRoundingState == this._window.WindowState) { return; } size = this._GetWindowRect().Size; } else { size = new Size((double)wp.Value.cx, (double)wp.Value.cy); } this._lastRoundingState = this._window.WindowState; IntPtr zero = IntPtr.Zero; try { double num = Math.Min(size.Width, size.Height); CornerRadius cornerRadius = this._chromeInfo.CornerRadius; Point device = DpiHelper.LogicalPixelsToDevice(new Point(cornerRadius.TopLeft, 0)); double x = device.X; x = Math.Min(x, num / 2); if (!WindowChromeWorker._IsUniform(this._chromeInfo.CornerRadius)) { zero = WindowChromeWorker._CreateRoundRectRgn(new Rect(0, 0, size.Width / 2 + x, size.Height / 2 + x), x); cornerRadius = this._chromeInfo.CornerRadius; device = DpiHelper.LogicalPixelsToDevice(new Point(cornerRadius.TopRight, 0)); double x1 = device.X; x1 = Math.Min(x1, num / 2); Rect rect = new Rect(0, 0, size.Width / 2 + x1, size.Height / 2 + x1); rect.Offset(size.Width / 2 - x1, 0); WindowChromeWorker._CreateAndCombineRoundRectRgn(zero, rect, x1); cornerRadius = this._chromeInfo.CornerRadius; device = DpiHelper.LogicalPixelsToDevice(new Point(cornerRadius.BottomLeft, 0)); double num1 = device.X; num1 = Math.Min(num1, num / 2); Rect rect1 = new Rect(0, 0, size.Width / 2 + num1, size.Height / 2 + num1); rect1.Offset(0, size.Height / 2 - num1); WindowChromeWorker._CreateAndCombineRoundRectRgn(zero, rect1, num1); cornerRadius = this._chromeInfo.CornerRadius; device = DpiHelper.LogicalPixelsToDevice(new Point(cornerRadius.BottomRight, 0)); double x2 = device.X; x2 = Math.Min(x2, num / 2); Rect rect2 = new Rect(0, 0, size.Width / 2 + x2, size.Height / 2 + x2); rect2.Offset(size.Width / 2 - x2, size.Height / 2 - x2); WindowChromeWorker._CreateAndCombineRoundRectRgn(zero, rect2, x2); } else { zero = WindowChromeWorker._CreateRoundRectRgn(new Rect(size), x); } Standard.NativeMethods.SetWindowRgn(this._hwnd, zero, Standard.NativeMethods.IsWindowVisible(this._hwnd)); zero = IntPtr.Zero; } finally { Utility.SafeDeleteObject(ref zero); } } else { if (!wp.HasValue) { Rect rect3 = this._GetWindowRect(); left = (int)rect3.Left; top = (int)rect3.Top; } else { left = wp.Value.x; top = wp.Value.y; } RECT monitorInfo = Standard.NativeMethods.GetMonitorInfo(Standard.NativeMethods.MonitorFromWindow(this._hwnd, 2)).rcWork; monitorInfo.Offset(-left, -top); IntPtr intPtr = IntPtr.Zero; try { intPtr = Standard.NativeMethods.CreateRectRgnIndirect(monitorInfo); Standard.NativeMethods.SetWindowRgn(this._hwnd, intPtr, Standard.NativeMethods.IsWindowVisible(this._hwnd)); intPtr = IntPtr.Zero; } finally { Utility.SafeDeleteObject(ref intPtr); } } }