Skip to content

Commit

Permalink
Merge pull request #2337 from cwensley/curtis/wpf-defer-nativehandle-…
Browse files Browse the repository at this point in the history
…use-till-loaded

Wpf: Defer use of NativeHandle until the window is loaded
  • Loading branch information
cwensley authored Oct 19, 2022
2 parents 2fe9f0c + e5716de commit 2e6f094
Showing 1 changed file with 35 additions and 34 deletions.
69 changes: 35 additions & 34 deletions src/Eto.Wpf/Forms/WpfWindow.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -125,19 +125,7 @@ protected override void Initialize()
main.Children.Add(toolBarHolder);
main.Children.Add(content);
Control.Content = main;
Control.Loaded += delegate
{
SetMinimumSize();
if (initialClientSize != null)
{
initialClientSize = null;
SetContentSize();
}
// stop form from auto-sizing after it is shown
SetSizeToContent();
if (Control.ShowActivated)
Control.MoveFocus(new swi.TraversalRequest(swi.FocusNavigationDirection.Next));
};
Control.Loaded += Control_Loaded;
Control.PreviewKeyDown += (sender, e) =>
{
// need to call validate on the input bindings before trying to execute them
Expand All @@ -151,6 +139,31 @@ protected override void Initialize()
HandleEvent(Window.ClosingEvent);
}

private void Control_Loaded(object sender, sw.RoutedEventArgs e)
{
if (!Minimizable || !Maximizable)
{
SetResizeMode();
}

if (initialLocation != null)
{
SetLocation(initialLocation.Value);
initialLocation = null;
}

SetMinimumSize();
if (initialClientSize != null)
{
initialClientSize = null;
SetContentSize();
}
// stop form from auto-sizing after it is shown
SetSizeToContent();
if (Control.ShowActivated)
Control.MoveFocus(new swi.TraversalRequest(swi.FocusNavigationDirection.Next));
}

private void Control_SizeChanged(object sender, sw.SizeChangedEventArgs e)
{
if (Widget.Loaded && Control.SizeToContent == sw.SizeToContent.Manual)
Expand Down Expand Up @@ -566,8 +579,11 @@ protected virtual void SetResizeMode()
else
Control.ResizeMode = sw.ResizeMode.NoResize;

SetStyle(Win32.WS.MAXIMIZEBOX, Maximizable);
SetStyle(Win32.WS.MINIMIZEBOX, Minimizable);
if (Control.IsLoaded)
{
SetStyle(Win32.WS.MAXIMIZEBOX, Maximizable);
SetStyle(Win32.WS.MINIMIZEBOX, Minimizable);
}
}

public virtual bool ShowInTaskbar
Expand Down Expand Up @@ -633,11 +649,10 @@ public override Size Size
{
get
{
var handle = NativeHandle;
if (handle != IntPtr.Zero && Control.IsLoaded)
if (Control.IsLoaded && NativeHandle != IntPtr.Zero)
{
// WPF doesn't always report the correct size when maximized
var rect = Win32.ExecuteInDpiAwarenessContext(() => Win32.GetWindowRect(handle, out var r) ? r : (Win32.RECT?)null);
var rect = Win32.ExecuteInDpiAwarenessContext(() => Win32.GetWindowRect(NativeHandle, out var r) ? r : (Win32.RECT?)null);
if (rect != null)
{
var scale = DpiScale;
Expand Down Expand Up @@ -731,16 +746,12 @@ double DpiScale
if (IsAttached)
throw new NotSupportedException();

if (NativeHandle == IntPtr.Zero)
if (!Control.IsLoaded)
{
// set location when the source is initialized and we have a Win32 handle to move about
// using Left/Top doesn't work (properly) in a per-monitor dpi environment.
initialLocation = value;
if (!LocationSet)
{
LocationSet = true;
Control.SourceInitialized += Control_SourceInitialized;
}
LocationSet = true;
}
else
{
Expand All @@ -750,18 +761,8 @@ double DpiScale
}
}

void Control_SourceInitialized(object sender, EventArgs e)
{
LocationSet = false;
SetLocation(initialLocation.Value);
initialLocation = null;
Control.SourceInitialized -= Control_SourceInitialized;
}

void SetLocation(PointF location)
{
var handle = NativeHandle;

var loc = location.LogicalToScreen();
Win32.ExecuteInDpiAwarenessContext(() => Win32.SetWindowPos(NativeHandle, IntPtr.Zero, loc.X, loc.Y, 0, 0, Win32.SWP.NOSIZE | Win32.SWP.NOACTIVATE));
}
Expand Down

0 comments on commit 2e6f094

Please sign in to comment.