public static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset);
private void _ExtendGlassFrame() { Assert.IsNotNull(_window); // Expect that this might be called on OSes other than Vista. if (!Utility.IsOSVistaOrNewer) { // Not an error. Just not on Vista so we're not going to get glass. return; } if (IntPtr.Zero == _hwnd) { // Can't do anything with this call until the Window has been shown. return; } // Ensure standard HWND background painting when DWM isn't enabled. if (!NativeMethods.DwmIsCompositionEnabled()) { _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { // This makes the glass visible at a Win32 level so long as nothing else is covering it. // The Window's Background needs to be changed independent of this. // Apply the transparent background to the HWND _hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; // Thickness is going to be DIPs, need to convert to system coordinates. Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Left, _chromeInfo.GlassFrameThickness.Top)); Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Right, _chromeInfo.GlassFrameThickness.Bottom)); var dwmMargin = new MARGINS { // err on the side of pushing in glass an extra pixel. cxLeftWidth = (int)Math.Ceiling(deviceTopLeft.X), cxRightWidth = (int)Math.Ceiling(deviceBottomRight.X), cyTopHeight = (int)Math.Ceiling(deviceTopLeft.Y), cyBottomHeight = (int)Math.Ceiling(deviceBottomRight.Y), }; NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin); } }
private void _RestoreGlassFrame() { Assert.IsNull(_chromeInfo); Assert.IsNotNull(_window); // Expect that this might be called on OSes other than Vista // and if the window hasn't yet been shown, then we don't need to undo anything. if (!Utility.IsOSVistaOrNewer || _hwnd == IntPtr.Zero) { return; } _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; if (NativeMethods.DwmIsCompositionEnabled()) { // If glass is enabled, push it back to the normal bounds. var dwmMargin = new MARGINS(); NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin); } }
/// <summary>Extends the frame into client area. /// </summary> /// <param name="window">The window.</param> /// <param name="margin">The margin.</param> /// <returns><c>True</c> if the function succeeded, <c>False</c> otherwise.</returns> public static void ExtendFrameIntoClientArea(IntPtr hwnd, System.Windows.Thickness margin) { if (!IsCompositionEnabled) throw new InvalidOperationException("Composition is not enabled. Glass cannot be extended."); if (hwnd == IntPtr.Zero) throw new ArgumentOutOfRangeException("hwnd"); // Set the background to transparent to get the full Glass effect System.Windows.Interop.HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = System.Windows.Media.Colors.Transparent; MARGINS margins = new MARGINS(margin); NativeMethods.DwmExtendFrameIntoClientArea(hwnd, ref margins); }
private void _ExtendGlassFrame() { Assert.IsNotNull(_window); // Expect that this might be called on OSes other than Vista. if (!Utility.IsOSVistaOrNewer) { // Not an error. Just not on Vista so we're not going to get glass. return; } if (IntPtr.Zero == _hwnd) { // Can't do anything with this call until the Window has been shown. return; } // Ensure standard HWND background painting when DWM isn't enabled. if (!NativeMethods.DwmIsCompositionEnabled()) { _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { // This makes the glass visible at a Win32 level so long as nothing else is covering it. // The Window's Background needs to be changed independent of this. // Apply the transparent background to the HWND _hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; // Thickness is going to be DIPs, need to convert to system coordinates. Thickness deviceGlassThickness = DpiHelper.LogicalThicknessToDevice(_chromeInfo.GlassFrameThickness); if (_chromeInfo.SacrificialEdge != SacrificialEdge.None) { Thickness windowResizeBorderThicknessDevice = DpiHelper.LogicalThicknessToDevice(SystemParameters2.Current.WindowResizeBorderThickness); if (Utility.IsFlagSet((int)_chromeInfo.SacrificialEdge, (int)SacrificialEdge.Top)) { deviceGlassThickness.Top -= windowResizeBorderThicknessDevice.Top; deviceGlassThickness.Top = Math.Max(0, deviceGlassThickness.Top); } if (Utility.IsFlagSet((int)_chromeInfo.SacrificialEdge, (int)SacrificialEdge.Left)) { deviceGlassThickness.Left -= windowResizeBorderThicknessDevice.Left; deviceGlassThickness.Left = Math.Max(0, deviceGlassThickness.Left); } if (Utility.IsFlagSet((int)_chromeInfo.SacrificialEdge, (int)SacrificialEdge.Bottom)) { deviceGlassThickness.Bottom -= windowResizeBorderThicknessDevice.Bottom; deviceGlassThickness.Bottom = Math.Max(0, deviceGlassThickness.Bottom); } if (Utility.IsFlagSet((int)_chromeInfo.SacrificialEdge, (int)SacrificialEdge.Right)) { deviceGlassThickness.Right -= windowResizeBorderThicknessDevice.Right; deviceGlassThickness.Right = Math.Max(0, deviceGlassThickness.Right); } } var dwmMargin = new MARGINS { // err on the side of pushing in glass an extra pixel. cxLeftWidth = (int)Math.Ceiling(deviceGlassThickness.Left), cxRightWidth = (int)Math.Ceiling(deviceGlassThickness.Right), cyTopHeight = (int)Math.Ceiling(deviceGlassThickness.Top), cyBottomHeight = (int)Math.Ceiling(deviceGlassThickness.Bottom), }; NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin); } }
private void _ExtendGlassFrame() { Debug.Assert(null != _window); // Expect that this might be called on OSes other than Vista. if (!_OnVista) { // Not an error. Just not on Vista so we're not going to get glass. return; } if (IntPtr.Zero == _hwnd) { // Can't do anything with this call until the Window has been shown. return; } HwndSource hwndSource = HwndSource.FromHwnd(_hwnd); // The Window's Background property is handled by _UpdateFrameState. // The Border/Background part of the template is made invisible when glass is on. if (!_IsCompositionEnabled) { hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { // Apply the transparent background to the HWND hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; // Thickness is going to be DIPs, need to convert to system coordinates. Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice(new Point(ClientBorderThickness.Left, ClientBorderThickness.Top)); Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice(new Point(ClientBorderThickness.Right, ClientBorderThickness.Bottom)); var dwmMargin = new MARGINS { // err on the side of pushing in glass an extra pixel. cxLeftWidth = (int)Math.Ceiling(deviceTopLeft.X), cxRightWidth = (int)Math.Ceiling(deviceBottomRight.X), cyTopHeight = (int)Math.Ceiling(deviceTopLeft.Y), cyBottomHeight = (int)Math.Ceiling(deviceBottomRight.Y), }; NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin); } }
private static bool _ExtendGlassFrameInternal(Window window, Thickness margin) { Assert.IsNotNull(window); Assert.IsTrue(window.CheckAccess()); // Expect that this might be called on OSes other than Vista. if (Environment.OSVersion.Version.Major < 6) { // Not an error. Just not on Vista so we're not going to get glass. return false; } IntPtr hwnd = new WindowInteropHelper(window).Handle; if (IntPtr.Zero == hwnd) { throw new InvalidOperationException("Window must be shown before extending glass."); } HwndSource hwndSource = HwndSource.FromHwnd(hwnd); bool isGlassEnabled; NativeMethods.DwmIsCompositionEnabled(out isGlassEnabled); if (!isGlassEnabled) { window.Background = SystemColors.WindowBrush; hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { // Apply the transparent background to both the Window and HWND window.Background = Brushes.Transparent; hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; var dwmMargin = new MARGINS(margin); NativeMethods.DwmExtendFrameIntoClientArea(hwnd, ref dwmMargin); } // Even if glass isn't currently enabled, add the hook so we can appropriately respond // if that changes. bool addHook = !_extendedWindows.ContainsKey(hwnd); if (addHook) { HwndSourceHook hook = delegate(IntPtr innerHwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (WM.DWMCOMPOSITIONCHANGED == (WM)msg) { _ExtendGlassFrameInternal(window, margin); handled = false; } return IntPtr.Zero; }; _extendedWindows.Add(hwnd, hook); hwndSource.AddHook(hook); window.Closing += _OnExtendedWindowClosing; } return isGlassEnabled; }
private static bool _ExtendGlassFrameInternal(Window window, Thickness margin) { Assert.IsNotNull(window); Assert.IsTrue(window.CheckAccess()); // Expect that this might be called on OSes other than Vista. if (!Utility.IsOSVistaOrNewer) { // Not an error. Just not on Vista so we're not going to get glass. return false; } IntPtr hwnd = new WindowInteropHelper(window).Handle; if (IntPtr.Zero == hwnd) { throw new InvalidOperationException("Window must be shown before extending glass."); } HwndSource hwndSource = HwndSource.FromHwnd(hwnd); bool isGlassEnabled = NativeMethods.DwmIsCompositionEnabled(); if (!isGlassEnabled) { window.Background = SystemColors.WindowBrush; hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { // Apply the transparent background to both the Window and the HWND window.Background = Brushes.Transparent; hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; // Thickness is going to be DIPs, need to convert to system coordinates. Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice(new Point(margin.Left, margin.Top)); Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice(new Point(margin.Right, margin.Bottom)); var dwmMargin = new MARGINS { // err on the side of pushing in glass an extra pixel. cxLeftWidth = (int)Math.Ceiling(deviceTopLeft.X), cxRightWidth = (int)Math.Ceiling(deviceBottomRight.X), cyTopHeight = (int)Math.Ceiling(deviceTopLeft.Y), cyBottomHeight = (int)Math.Ceiling(deviceBottomRight.Y), }; NativeMethods.DwmExtendFrameIntoClientArea(hwnd, ref dwmMargin); } // Even if glass isn't currently enabled, add the hook so we can appropriately respond // if that changes. bool addHook = !_extendedWindows.ContainsKey(hwnd); if (addHook) { HwndSourceHook hook = delegate(IntPtr innerHwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (WM.DWMCOMPOSITIONCHANGED == (WM)msg) { _ExtendGlassFrameInternal(window, margin); handled = false; } return IntPtr.Zero; }; _extendedWindows.Add(hwnd, hook); hwndSource.AddHook(hook); window.Closing += _OnExtendedWindowClosing; } return isGlassEnabled; }
private static bool _ExtendGlassFrameInternal(Window window, Thickness margin) { Assert.IsNotNull(window); Assert.IsTrue(window.CheckAccess()); // Expect that this might be called on OSes other than Vista. if (!Utility.IsOSVistaOrNewer) { // Not an error. Just not on Vista so we're not going to get glass. return(false); } IntPtr hwnd = new WindowInteropHelper(window).Handle; if (IntPtr.Zero == hwnd) { throw new InvalidOperationException("Window must be shown before extending glass."); } HwndSource hwndSource = HwndSource.FromHwnd(hwnd); bool isGlassEnabled = NativeMethods.DwmIsCompositionEnabled(); if (!isGlassEnabled) { window.Background = SystemColors.WindowBrush; hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; } else { // Apply the transparent background to both the Window and the HWND window.Background = Brushes.Transparent; hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; // Thickness is going to be DIPs, need to convert to system coordinates. Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice(new Point(margin.Left, margin.Top)); Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice(new Point(margin.Right, margin.Bottom)); var dwmMargin = new MARGINS { // err on the side of pushing in glass an extra pixel. cxLeftWidth = (int)Math.Ceiling(deviceTopLeft.X), cxRightWidth = (int)Math.Ceiling(deviceBottomRight.X), cyTopHeight = (int)Math.Ceiling(deviceTopLeft.Y), cyBottomHeight = (int)Math.Ceiling(deviceBottomRight.Y), }; NativeMethods.DwmExtendFrameIntoClientArea(hwnd, ref dwmMargin); } // Even if glass isn't currently enabled, add the hook so we can appropriately respond // if that changes. bool addHook = !_extendedWindows.ContainsKey(hwnd); if (addHook) { HwndSourceHook hook = delegate(IntPtr innerHwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (WM.DWMCOMPOSITIONCHANGED == (WM)msg) { _ExtendGlassFrameInternal(window, margin); handled = false; } return(IntPtr.Zero); }; _extendedWindows.Add(hwnd, hook); hwndSource.AddHook(hook); window.Closing += _OnExtendedWindowClosing; } return(isGlassEnabled); }