From a68aa792f6ee6192280f478be995fda4d5537683 Mon Sep 17 00:00:00 2001 From: mntone Date: Mon, 24 Aug 2020 21:48:30 +0900 Subject: [PATCH 1/7] Fix ChromeWindow per-monitor DPI bug. --- .../Chrome/Primitives/ChromeWindow..cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs b/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs index 2c6278c6..2bf7a425 100644 --- a/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs +++ b/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs @@ -232,7 +232,11 @@ protected void UpdateSize() { if (!this.GetIsUpdateAvailable()) return; - this.CheckDpiChange(); + if (this.CheckDpiChange()) + { + this.UpdateLocationAndSizeCore(); + return; + } var ownerRect = User32.GetWindowRect(this.Owner.Handle); var width = this.GetWidth(ownerRect); @@ -247,7 +251,11 @@ private void UpdateLocationAndSize() if (!this.GetIsUpdateAvailable()) return; this.CheckDpiChange(); + this.UpdateLocationAndSizeCore(); + } + private void UpdateLocationAndSizeCore() + { var ownerRect = User32.GetWindowRect(this.Owner.Handle); var left = this.GetLeft(ownerRect); var top = this.GetTop(ownerRect); @@ -258,7 +266,7 @@ private void UpdateLocationAndSize() User32.SetWindowPos(this._handle, IntPtr.Zero, left, top, width, height, flags); } - private void CheckDpiChange() + private bool CheckDpiChange() { if (PerMonitorDpi.IsSupported) { @@ -270,8 +278,11 @@ private void CheckDpiChange() : new ScaleTransform((double)currentDpi.X / this.SystemDpi.X, (double)currentDpi.Y / this.SystemDpi.Y); this.CurrentDpi = currentDpi; this.UpdateDpiResources(); + this.UpdateLayout(); + return true; } } + return false; } public override void OnApplyTemplate() @@ -403,9 +414,8 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b return new IntPtr(3); } - #if NET40 || NET45 || NET451 || NET452 || NET46 || NET461 // Note: Double scaling is avoided on .NET Framework 4.6.2 or later. - if (msg == (int)WindowsMessages.WM_DPICHANGED) + else if (msg == (int)WindowsMessages.WM_DPICHANGED) { // System.Diagnostics.Debug.WriteLine("WM_DPICHANGED: " + this.GetType().Name); @@ -415,7 +425,6 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b handled = true; return IntPtr.Zero; } - #endif return IntPtr.Zero; } From ffec6c1399fdd829593bea798680589667494905 Mon Sep 17 00:00:00 2001 From: mntone Date: Wed, 26 Aug 2020 01:22:06 +0900 Subject: [PATCH 2/7] Fix issue that ChromeWindow doesn't light up with external window. --- source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs b/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs index 2bf7a425..83215df3 100644 --- a/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs +++ b/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs @@ -113,7 +113,7 @@ public void Attach(Window window) public void Attach(IChromeOwner window) { Action applyAccent = color => - this.Background = new SolidColorBrush(Color.FromRgb(color.R, color.G, color.B)); + this.BorderBrush = new SolidColorBrush(Color.FromRgb(color.R, color.G, color.B)); var disposable = WindowsTheme.Accent.RegisterListener(applyAccent); this.Closed += (sender, e) => disposable.Dispose(); From 8644092641220ccf09235d570d9ef7d0f703431a Mon Sep 17 00:00:00 2001 From: mntone Date: Wed, 26 Aug 2020 01:28:14 +0900 Subject: [PATCH 3/7] Fix issue where ChromeWindow's position isn't sometimes correct. --- .../Chrome/Primitives/ChromeWindow..cs | 19 ++++++++++++++++--- .../Interop/Win32/Dwmapi.cs | 19 ++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs b/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs index 83215df3..87a62289 100644 --- a/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs +++ b/source/MetroRadiance.Chrome/Chrome/Primitives/ChromeWindow..cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -220,7 +221,7 @@ private void UpdateLocation() this.CheckDpiChange(); - var ownerRect = User32.GetWindowRect(this.Owner.Handle); + var ownerRect = GetWindowRect(this.Owner.Handle); var left = this.GetLeft(ownerRect); var top = this.GetTop(ownerRect); var flags = SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOOWNERZORDER | SetWindowPosFlags.SWP_NOSENDCHANGING; @@ -238,7 +239,7 @@ protected void UpdateSize() return; } - var ownerRect = User32.GetWindowRect(this.Owner.Handle); + var ownerRect = GetWindowRect(this.Owner.Handle); var width = this.GetWidth(ownerRect); var height = this.GetHeight(ownerRect); var flags = SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOOWNERZORDER | SetWindowPosFlags.SWP_NOSENDCHANGING; @@ -256,7 +257,7 @@ private void UpdateLocationAndSize() private void UpdateLocationAndSizeCore() { - var ownerRect = User32.GetWindowRect(this.Owner.Handle); + var ownerRect = GetWindowRect(this.Owner.Handle); var left = this.GetLeft(ownerRect); var top = this.GetTop(ownerRect); var width = this.GetWidth(ownerRect); @@ -285,6 +286,18 @@ private bool CheckDpiChange() return false; } + private static RECT GetWindowRect(IntPtr hWnd) + { + try + { + return Dwmapi.DwmGetExtendedFrameBounds(hWnd); + } + catch (COMException) + { + return User32.GetWindowRect(hWnd); + } + } + public override void OnApplyTemplate() { base.OnApplyTemplate(); diff --git a/source/MetroRadiance.Core/Interop/Win32/Dwmapi.cs b/source/MetroRadiance.Core/Interop/Win32/Dwmapi.cs index 4e02c68e..bb08bfa7 100644 --- a/source/MetroRadiance.Core/Interop/Win32/Dwmapi.cs +++ b/source/MetroRadiance.Core/Interop/Win32/Dwmapi.cs @@ -10,8 +10,25 @@ public static class Dwmapi [DllImport("Dwmapi.dll", ExactSpelling = true, PreserveSig = false)] public static extern void DwmGetColorizationColor([Out] out uint pcrColorization, [Out, MarshalAs(UnmanagedType.Bool)] out bool pfOpaqueBlend); + [Obsolete("MetroRadiance.Interop.Win32.DwmGetWindowAttributeAsRectangle を使用してください")] [DllImport("Dwmapi.dll", ExactSpelling = true, PreserveSig = false)] - public static extern void DwmGetWindowAttribute(IntPtr hWnd, DWMWINDOWATTRIBUTE dwAttribute, [Out] out RECT pvAttribute, int cbAttribute); + public static extern void DwmGetWindowAttribute(IntPtr hWnd, DWMWINDOWATTRIBUTE dwAttribute, [Out] out RECT pvAttribute, uint cbAttribute); + [DllImport("Dwmapi.dll", EntryPoint = "DwmGetWindowAttribute", ExactSpelling = true, PreserveSig = false)] + public static extern void DwmGetWindowAttributeAsRectangle(IntPtr hWnd, DWMWINDOWATTRIBUTE dwAttribute, [Out] out RECT pvAttribute, uint cbAttribute); + + public static RECT DwmGetCaptionButtonBounds(IntPtr hWnd) + { + RECT rect; + DwmGetWindowAttributeAsRectangle(hWnd, DWMWINDOWATTRIBUTE.DWMWA_CAPTION_BUTTON_BOUNDS, out rect, (uint)Marshal.SizeOf(typeof(RECT))); + return rect; + } + + public static RECT DwmGetExtendedFrameBounds(IntPtr hWnd) + { + RECT rect; + DwmGetWindowAttributeAsRectangle(hWnd, DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, out rect, (uint)Marshal.SizeOf(typeof(RECT))); + return rect; + } } } From 4322bf0c4dd1243a79ef022bca8e47ce76ff3d1c Mon Sep 17 00:00:00 2001 From: mntone Date: Wed, 26 Aug 2020 01:30:46 +0900 Subject: [PATCH 4/7] Add ExternalChromeSamples. --- .../MetroRadiance.Showcase.csproj | 7 + .../UI/ExternalChromeSamples.xaml | 71 ++++++ .../UI/ExternalChromeSamples.xaml.cs | 219 ++++++++++++++++++ .../MetroRadiance.Showcase/UI/MainWindow.xaml | 9 + .../Interop/Win32/Dwmapi.cs | 10 + .../Interop/Win32/User32.cs | 20 +- 6 files changed, 326 insertions(+), 10 deletions(-) create mode 100644 samples/MetroRadiance.Showcase/UI/ExternalChromeSamples.xaml create mode 100644 samples/MetroRadiance.Showcase/UI/ExternalChromeSamples.xaml.cs diff --git a/samples/MetroRadiance.Showcase/MetroRadiance.Showcase.csproj b/samples/MetroRadiance.Showcase/MetroRadiance.Showcase.csproj index e21795ee..fceda4c7 100644 --- a/samples/MetroRadiance.Showcase/MetroRadiance.Showcase.csproj +++ b/samples/MetroRadiance.Showcase/MetroRadiance.Showcase.csproj @@ -97,6 +97,9 @@ BlurWindowSample.xaml + + ExternalChromeSamples.xaml + ImmersiveColorSamples.xaml @@ -111,6 +114,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/samples/MetroRadiance.Showcase/UI/ExternalChromeSamples.xaml b/samples/MetroRadiance.Showcase/UI/ExternalChromeSamples.xaml new file mode 100644 index 00000000..aef79403 --- /dev/null +++ b/samples/MetroRadiance.Showcase/UI/ExternalChromeSamples.xaml @@ -0,0 +1,71 @@ + + + + +