From 0989787adaa46b94851e32bf8ef96c5b92187ea4 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Tue, 29 Nov 2022 15:52:38 -0800 Subject: [PATCH] Wpf: Fix crash when setting the Title or Icon of a borderless window. --- src/Eto.Wpf/Forms/WpfWindow.cs | 56 ++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/Eto.Wpf/Forms/WpfWindow.cs b/src/Eto.Wpf/Forms/WpfWindow.cs index 2471069886..ae743c0cd9 100755 --- a/src/Eto.Wpf/Forms/WpfWindow.cs +++ b/src/Eto.Wpf/Forms/WpfWindow.cs @@ -38,6 +38,7 @@ static class WpfWindow internal static readonly object Maximizable_Key = new object(); internal static readonly object Closeable_Key = new object(); internal static readonly object Resizable_Key = new object(); + internal static readonly object Icon_Key = new object(); } public abstract class WpfWindow : WpfPanel, Window.IHandler, IWpfWindow, IInputBindingHost @@ -45,7 +46,6 @@ public abstract class WpfWindow : WpfPanel Widget.Properties.Get(WpfWindow.Icon_Key, () => { + var icon = Control.Icon.ToEtoIcon(); + Widget.Properties.Set(WpfWindow.Icon_Key, icon); + return icon; + }); set { - icon = value; - if (value != null) + if (Widget.Properties.TrySet(WpfWindow.Icon_Key, value)) { - Control.Icon = (swm.ImageSource)icon.ControlObject; + var style = SaveWindowStyle(); + Control.Icon = (swm.ImageSource)value?.ControlObject; + RestoreWindowStyle(style); } } } @@ -697,7 +702,12 @@ public override Size Size public string Title { get { return Control.Title; } - set { Control.Title = value ?? string.Empty; } + set + { + var style = SaveWindowStyle(); + Control.Title = value ?? string.Empty; + RestoreWindowStyle(style); + } } protected bool LocationSet @@ -886,10 +896,11 @@ public WindowStyle WindowStyle } } - void SetWindowChrome(bool enabled) + uint? SaveWindowStyle() { if (!isSourceInitialized) - return; + return null; + // Annoyingly, WPF gets an AritheticOverflow if the window style has WS_POPUP in it as it treats it as an int // So, we remove that style then re-apply it after. uint? oldStyle = null; @@ -900,6 +911,26 @@ void SetWindowChrome(bool enabled) oldStyle = style & (uint)(0x80000000); Win32.SetWindowLong(NativeHandle, Win32.GWL.STYLE, style & 0x7FFFFFFF); } + return oldStyle; + } + + void RestoreWindowStyle(uint? oldStyle) + { + if (oldStyle == null) + return; + + // reapply the old style bit + var style = Win32.GetWindowLong(NativeHandle, Win32.GWL.STYLE); + style |= oldStyle.Value; + Win32.SetWindowLong(NativeHandle, Win32.GWL.STYLE, style); + } + + void SetWindowChrome(bool enabled) + { + if (!isSourceInitialized) + return; + var oldStyle = SaveWindowStyle(); + if (enabled) { var windowChrome = new sw.Shell.WindowChrome @@ -913,14 +944,7 @@ void SetWindowChrome(bool enabled) { Control.ClearValue(sw.Shell.WindowChrome.WindowChromeProperty); } - - if (oldStyle != null) - { - // reapply the old style bit - style = Win32.GetWindowLong(NativeHandle, Win32.GWL.STYLE); - style |= oldStyle.Value; - Win32.SetWindowLong(NativeHandle, Win32.GWL.STYLE, style); - } + RestoreWindowStyle(oldStyle); } public void BringToFront()