private static void HideDropShadow(CustomChrome window) { var dropShadowEffect = window.Effect as DropShadowEffect; if (dropShadowEffect != null) { // By making the effect nearly invisible but yet still enough // visible this hack allow to "hide" the drop shadow but still // be able to show the resizing handles when AllowTransparency // is set to "true" if (window.ResizeMode != ResizeMode.NoResize && window.ResizeMode != ResizeMode.CanMinimize) { // To "disable" drop shadow effet, we must use an opacity > 0 // otherwise the resizing border will not work (default is 1) // 0.05 was tested to be visible "enough" to make it work dropShadowEffect.Opacity = 1;// 0.05; // Force a blur radius to allow resizing handle to work // When the drop shadow opacity is nearly 0, the blur radius // also shrink, a value of 10 seems to be large enough dropShadowEffect.BlurRadius = 10; } else { dropShadowEffect.Opacity = 1; dropShadowEffect.BlurRadius = 10; } } }
/// <summary> /// Create and show (if enabled) the drop shadow effect /// around the window border /// </summary> /// <param name="window"></param> /// <remarks> /// We need to always create the drop shadow effect /// even if not enabled to be able to support resizing /// </remarks> private static void ShowDropShadow(CustomChrome window) { var dropShadowEffect = window.Effect as DropShadowEffect; if (dropShadowEffect == null) { window.Effect = CreateDropShadowEffect( window.DropShadowColor, window.DropShadowOpacity, window.DropShadowBlurRadius); } else { dropShadowEffect.Color = window.DropShadowColor; dropShadowEffect.Opacity = window.DropShadowOpacity; dropShadowEffect.BlurRadius = Math.Max(window.DropShadowBlurRadius, 2); } // Set the border to make the effect visible when window // cannot resize or can only minimize if (window.ResizeMode == ResizeMode.NoResize || window.ResizeMode == ResizeMode.CanMinimize) { double borderWidth = GetResizeBorderWidth(window); window.BorderThickness = new Thickness(borderWidth); } if (!window.EnableDropShadow) { HideDropShadow(window); } }
/// <summary> /// Get the highest value between the current resize border width and /// the drop shadow blur radius /// </summary> /// <param name="window"></param> /// <returns> /// The highest value between the resize border width and the drop shadown blur radius /// </returns> private static double GetResizeBorderWidth(CustomChrome window) { // Override the resize border width if the blur radius is higher double borderWidth = Math.Max(window.ResizeBorderWidth, window.DropShadowBlurRadius); // Guard against lower than default resize width return(borderWidth > DependencyPropertyDefault.ResizeBorderWidth ? borderWidth : DependencyPropertyDefault.ResizeBorderWidth); }
private static void SetCustomWindow(CustomChrome window) { window.WindowStyle = WindowStyle.None; window.BorderBrush = Brushes.Transparent; window.AllowsTransparency = true; window.SnapsToDevicePixels = true; //TextOptions.SetTextFormattingMode(window, TextFormattingMode.Display); //RenderOptions.SetBitmapScalingMode(window, BitmapScalingMode.HighQuality); }
private static IntPtr WindowHookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { CustomChrome window = GetWindow(hWnd) as CustomChrome; switch (msg) { // Toggle the DropShadowEffect when window is snapped or maximized case WM_SIZE: { int resizing = (int)wParam; if (resizing == SIZE_RESTORED) { MonitorArea monitorArea = GetMonitorArea(hWnd); if (monitorArea != null) { // LOWORD int width = ((int)lParam & 0x0000ffff); // HIWORD int height = (int)((int)lParam & 0xffff0000) >> 16; // Detect if window was snapped to screen side of current monitor // or if spanning width on multiple monitors (to avoid unsnapping) if (height == monitorArea.Work.Height || width >= SystemParameters.VirtualScreenWidth) { window.IsSnapped = true; UpdateResizeBorder(window, monitorArea, window.Left, window.Left + width); } else { window.IsSnapped = false; ShowDropShadow(window); EnableResizeBorder(window); } } } else if (resizing == SIZE_MAXIMIZED) { // Required when maximized from dragging window DisableResizeBorder(window); } } break; // To handle proper resizing of the custom window case WM_GETMINMAXINFO: { MonitorArea monitorArea = GetMonitorArea(hWnd); if (monitorArea != null) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); mmi.ptMaxPosition.x = monitorArea.Offset.x; mmi.ptMaxPosition.y = monitorArea.Offset.y; mmi.ptMaxSize.x = monitorArea.Work.Width; mmi.ptMaxSize.y = monitorArea.Work.Height; // To support minimum window size mmi.ptMinTrackSize.x = (int)window.MinWidth; mmi.ptMinTrackSize.y = (int)window.MinHeight; Marshal.StructureToPtr(mmi, lParam, true); handled = true; } } break; // To activate/deactivate border resize handles from window position case WM_WINDOWPOSCHANGED: { WINDOWPOS windowPos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS)); // When window is snapped and position changes if ((windowPos.flags & SWP_NOMOVE) != SWP_NOMOVE) { if (window.IsSnapped) { MonitorArea monitorArea = GetMonitorArea(hWnd); if (monitorArea != null) { UpdateResizeBorder(window, monitorArea, windowPos.x, windowPos.x + windowPos.cx); } } } } break; } return(IntPtr.Zero); }