Skip to content

Commit

Permalink
Work around bug in WPF when running in .NET Core
Browse files Browse the repository at this point in the history
See dotnet/wpf#4181 and dotnet/wpf#7345 for more information.
  • Loading branch information
cwensley committed Feb 14, 2024
1 parent d7ad8fe commit 051d935
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 23 deletions.
3 changes: 3 additions & 0 deletions src/Eto.WinForms/Win32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -632,5 +632,8 @@ public struct SCROLLINFO

[DllImport("User32.dll", SetLastError = true)]
public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);

[DllImport("kernel32.dll")]
public static extern void SetLastError(uint dwErrCode);
}
}
39 changes: 38 additions & 1 deletion src/Eto.Wpf/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,51 @@
using System.Windows.Automation.Peers;
using Eto.Wpf.Forms.Controls;
namespace Eto.Wpf.Forms
{
class EtoWindowAutomationPeer : WindowAutomationPeer
{
public EtoWindowAutomationPeer(sw.Window owner) : base(owner)
{
}

protected override string GetNameCore()
{
try
{
// due to windows message hooks, we can already be in error state which causes exceptions here.
#if NET
Marshal.SetLastSystemError(0);
#else
Win32.SetLastError(0);
#endif
return base.GetNameCore();
}
catch (Win32Exception)
{
// See https://github.com/dotnet/wpf/issues/4181 and https://github.com/dotnet/wpf/pull/7345
// Until that fix is in, we fix it ourselves to avoid random crashes
return (Owner as sw.Window)?.Title ?? string.Empty;
}
}
}


public class EtoWindow : sw.Window
{
protected override AutomationPeer OnCreateAutomationPeer()
{
return new EtoWindowAutomationPeer(this);
}
}

public class DialogHandler : WpfWindow<sw.Window, Dialog, Dialog.ICallback>, Dialog.IHandler
{
Button defaultButton;
Rectangle? parentWindowBounds;
swc.DockPanel dockMain;
swc.Grid gridButtons;

public DialogHandler() : this(new sw.Window()) { }
public DialogHandler() : this(new EtoWindow()) { }

public DialogHandler(sw.Window window)
{
Expand Down
43 changes: 21 additions & 22 deletions src/Eto.Wpf/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
namespace Eto.Wpf.Forms
{
public class FormHandler : WpfWindow<sw.Window, Form, Form.ICallback>, Form.IHandler
public class EtoFormWindow : EtoWindow
{
public class EtoWindow : sw.Window
public EtoFormWindow()
{
AllowDrop = true;
}

public EtoWindow()
{
AllowDrop = true;
}

protected override void OnActivated(EventArgs e)
{
if (!Focusable)
return;
base.OnActivated(e);
}
protected override void OnActivated(EventArgs e)
{
if (!Focusable)
return;
base.OnActivated(e);
}

protected override void OnPreviewGotKeyboardFocus(swi.KeyboardFocusChangedEventArgs e)
protected override void OnPreviewGotKeyboardFocus(swi.KeyboardFocusChangedEventArgs e)
{
if (!Focusable)
{
if (!Focusable)
{
e.Handled = true;
return;
}
base.OnPreviewGotKeyboardFocus(e);
e.Handled = true;
return;
}
base.OnPreviewGotKeyboardFocus(e);
}

}

public class FormHandler : WpfWindow<sw.Window, Form, Form.ICallback>, Form.IHandler
{
public FormHandler(sw.Window window)
{
Control = window;
}

public FormHandler()
{
Control = new EtoWindow();
Control = new EtoFormWindow();
}

public virtual void Show()
Expand Down

0 comments on commit 051d935

Please sign in to comment.