Skip to content

Commit

Permalink
Wpf: Fix crash when setting the Title or Icon of a borderless window.
Browse files Browse the repository at this point in the history
  • Loading branch information
cwensley committed Nov 29, 2022
1 parent 05cf515 commit 0989787
Showing 1 changed file with 40 additions and 16 deletions.
56 changes: 40 additions & 16 deletions src/Eto.Wpf/Forms/WpfWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ 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<TControl, TWidget, TCallback> : WpfPanel<TControl, TWidget, TCallback>, Window.IHandler, IWpfWindow, IInputBindingHost
where TControl : sw.Window
where TWidget : Window
where TCallback : Window.ICallback
{
Icon icon;
MenuBar menu;
Eto.Forms.ToolBar toolBar;
swc.DockPanel main;
Expand Down Expand Up @@ -484,13 +484,18 @@ public MenuBar Menu

public Icon Icon
{
get { return icon ?? (icon = Control.Icon.ToEtoIcon()); }
get => Widget.Properties.Get<Icon>(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<Icon>(WpfWindow.Icon_Key, value))
{
Control.Icon = (swm.ImageSource)icon.ControlObject;
var style = SaveWindowStyle();
Control.Icon = (swm.ImageSource)value?.ControlObject;
RestoreWindowStyle(style);
}
}
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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()
Expand Down

0 comments on commit 0989787

Please sign in to comment.