From 4622aab76d7f0dec98473e670bd6f3c933993e28 Mon Sep 17 00:00:00 2001 From: HARVEY Keith D Date: Fri, 14 Aug 2020 08:05:56 -0500 Subject: [PATCH 1/2] Final, final fix that preserves shadow and aero rectangle. --- WpfApp1/NativeMethods.cs | 54 +++++++++++++++++++++++++++ WpfApp1/WindowChromeLoadedBehavior.cs | 43 ++++++++++++++++----- 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/WpfApp1/NativeMethods.cs b/WpfApp1/NativeMethods.cs index 927009c..b6a091e 100644 --- a/WpfApp1/NativeMethods.cs +++ b/WpfApp1/NativeMethods.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; @@ -7,17 +8,70 @@ namespace WpfApp1 { public static class NativeMethods { + public const int WM_NCCALCSIZE = 0x83; + public const int WM_NCPAINT = 0x85; + [DllImport("user32.dll", EntryPoint = "SetWindowLong")] public static extern int SetWindowLong32(HandleRef hWnd, WindowLongFlags nIndex, int dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, WindowLongFlags nIndex, IntPtr dwNewLong); + [DllImport("kernel32", SetLastError = true)] + private static extern IntPtr LoadLibrary(string lpFileName); + + [DllImport("dwmapi.dll", PreserveSig = false)] + public static extern bool DwmIsCompositionEnabled(); + + [DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] + private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); + + [StructLayout(LayoutKind.Sequential)] + public struct MARGINS + { + public int leftWidth; + public int rightWidth; + public int topHeight; + public int bottomHeight; + } + public static IntPtr SetWindowLongPtr(HandleRef hWnd, WindowLongFlags nIndex, IntPtr dwNewLong) { return IntPtr.Size == 8 ? SetWindowLongPtr64(hWnd, nIndex, dwNewLong) : new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32())); } + private delegate int DwmExtendFrameIntoClientAreaDelegate(IntPtr hwnd, ref MARGINS margins); + + public static int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins) + { + var hModule = LoadLibrary("dwmapi"); + + if (hModule == IntPtr.Zero) + { + return 0; + } + + var procAddress = GetProcAddress(hModule, "DwmExtendFrameIntoClientArea"); + + if (procAddress == IntPtr.Zero) + { + return 0; + } + + var delegateForFunctionPointer = (DwmExtendFrameIntoClientAreaDelegate)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(DwmExtendFrameIntoClientAreaDelegate)); + + return delegateForFunctionPointer(hwnd, ref margins); + } + + public static bool IsDwmAvailable() + { + if (LoadLibrary("dwmapi") == IntPtr.Zero) + { + return false; + } + return true; + } + public enum WindowLongFlags { GWL_EXSTYLE = -20, diff --git a/WpfApp1/WindowChromeLoadedBehavior.cs b/WpfApp1/WindowChromeLoadedBehavior.cs index 40d70fb..394a5c8 100644 --- a/WpfApp1/WindowChromeLoadedBehavior.cs +++ b/WpfApp1/WindowChromeLoadedBehavior.cs @@ -11,6 +11,8 @@ namespace WpfApp1 { public class WindowChromeLoadedBehavior : Behavior { + private Window window; + protected override void OnAttached() { base.OnAttached(); @@ -25,7 +27,7 @@ protected override void OnDetaching() private void OnLoaded(object sender, RoutedEventArgs e) { - var window = Window.GetWindow(AssociatedObject); + window = Window.GetWindow(AssociatedObject); if (window == null) return; @@ -59,29 +61,50 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b { switch (msg) { - // WM_NCCALCSIZE - case 0x83: + case NativeMethods.WM_NCPAINT: + RemoveFrame(); + handled = false; + break; + + case NativeMethods.WM_NCCALCSIZE: + + handled = false; + var rcClientArea = (RECT)Marshal.PtrToStructure(lParam, typeof(RECT)); - rcClientArea.Bottom += (int)(WindowChromeHelper.WindowResizeBorderThickness.Bottom / 2); - Marshal.StructureToPtr(rcClientArea, lParam, false); - - handled = true; - + var retVal = IntPtr.Zero; - if (wParam == new IntPtr(1)) { retVal = new IntPtr((int)NativeMethods.WVR.REDRAW); } - return retVal; } return IntPtr.Zero; } + private void RemoveFrame() + { + if (Environment.OSVersion.Version.Major >= 6 && NativeMethods.IsDwmAvailable()) + { + if (NativeMethods.DwmIsCompositionEnabled() && SystemParameters.DropShadow) + { + NativeMethods.MARGINS margins; + + margins.bottomHeight = -1; + margins.leftWidth = 0; + margins.rightWidth = 0; + margins.topHeight = 0; + + var helper = new WindowInteropHelper(window); + + NativeMethods.DwmExtendFrameIntoClientArea(helper.Handle, ref margins); + } + } + } + [Serializable] [StructLayout(LayoutKind.Sequential)] public struct RECT From 35bfe03fea06e9756179f5253c1dbec0e907a5e3 Mon Sep 17 00:00:00 2001 From: HARVEY Keith D Date: Fri, 14 Aug 2020 08:21:36 -0500 Subject: [PATCH 2/2] Cleanup. --- WpfApp1/NativeMethods.cs | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/WpfApp1/NativeMethods.cs b/WpfApp1/NativeMethods.cs index b6a091e..ea7eafe 100644 --- a/WpfApp1/NativeMethods.cs +++ b/WpfApp1/NativeMethods.cs @@ -1,8 +1,5 @@ using System; -using System.ComponentModel; using System.Runtime.InteropServices; -using System.Windows; -using System.Windows.Interop; namespace WpfApp1 { @@ -11,12 +8,6 @@ public static class NativeMethods public const int WM_NCCALCSIZE = 0x83; public const int WM_NCPAINT = 0x85; - [DllImport("user32.dll", EntryPoint = "SetWindowLong")] - public static extern int SetWindowLong32(HandleRef hWnd, WindowLongFlags nIndex, int dwNewLong); - - [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] - public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, WindowLongFlags nIndex, IntPtr dwNewLong); - [DllImport("kernel32", SetLastError = true)] private static extern IntPtr LoadLibrary(string lpFileName); @@ -35,11 +26,6 @@ public struct MARGINS public int bottomHeight; } - public static IntPtr SetWindowLongPtr(HandleRef hWnd, WindowLongFlags nIndex, IntPtr dwNewLong) - { - return IntPtr.Size == 8 ? SetWindowLongPtr64(hWnd, nIndex, dwNewLong) : new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32())); - } - private delegate int DwmExtendFrameIntoClientAreaDelegate(IntPtr hwnd, ref MARGINS margins); public static int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins) @@ -72,20 +58,6 @@ public static bool IsDwmAvailable() return true; } - public enum WindowLongFlags - { - GWL_EXSTYLE = -20, - GWLP_HINSTANCE = -6, - GWLP_HWNDPARENT = -8, - GWL_ID = -12, - GWL_STYLE = -16, - GWL_USERDATA = -21, - GWL_WNDPROC = -4, - DWLP_USER = 0x8, - DWLP_MSGRESULT = 0x0, - DWLP_DLGPROC = 0x4 - } - internal enum WVR { ALIGNTOP = 0x0010,