[英]Invalid Window Handle when closing a WinForm that hosts a WPF UserControl that hosts a Windows Forms control
我有一個程序,它是由一群不同的人在不同的年份制作的。 有些應用程序是用 Winforms 編寫的,有些應用程序是用 WPF 編寫的。 我有一個在某些窗口 (WPF) 中使用的 WPF 用戶控件,我正試圖將其放入我程序的 Winforms 窗口之一中。 我有這個控件的 WPF 和 WinForms 版本,與我的新 WPF 版本相比,WinForms 的非常復雜且有些錯誤,這就是我將它放入舊 WinForms 窗口的原因。
這個 WPF 用戶控件里面有一個 WinForms 控件,因為我找不到我需要的控件的 WPF 版本(一個十六進制框)。 在我的 winforms 表單中,我放置了一個 ElementHost 來托管這個 UserControl(WPF)。 它工作得很好,直到我關閉窗口,也就是當我收到一個 Win32Exception 說 InvalidWindowHandle 時。 沒有有用的堆棧跟蹤。
當我關閉表單時,我處理了 interpreterWPF,它的 elementhost。 在處理 interpreterWPF 時,它會依次處理 hexbox 和 WinFormHostedControl。
當我關閉 PathfindingEditor 時,我會處理很多東西以防止內存泄漏。
(pathfindingeditor.cs)
private void PathfindingEditor_FormClosing(object sender, FormClosingEventArgs e)
{
//Nullify things to prevent memory leaks
interpreterWPF.Dispose();
interpreterWPFElementHost.Child = null;
interpreterWPFElementHost.Dispose();
...
(interpreterwpf.xaml.cs)
public override void Dispose()
{
Interpreter_Hexbox = null;
Interpreter_Hexbox_Host.Child.Dispose();
Interpreter_Hexbox_Host.Dispose();
}
我不知道此時還能做什么。 正在替換 winforms 控件的新 WPF 控件要簡單得多,而且錯誤也少得多。 將舊表單更改為 WPF 會很棒,但我還沒有找到適合它需要執行的復雜任務的庫,並且 WPF 中的 Winforms 托管元素有很多缺點,這就是為什么我不會比 hexbox 走得更遠.
我已經閱讀了 Dispatcher.InvokeShutdown() 但這似乎完全關閉了 WPF UI 線程。 我懷疑這就是我要找的東西。
嘗試將 ElementHost 的 WPF 根元素的 AutomationProperties.NameProperty 設置為一些有效字符串,例如如下:
elementHost.HandleCreated += delegate(object sender, EventArgs e)
{
HwndSource source = (HwndSource)HwndSource.FromVisual(elementHost.Child);
AutomationProperties.SetName(source.RootVisual, "elementHost");
};
當附加 Visual Studio 調試器時,我收到了以下異常,非常短的調用堆棧:
Source "WindowsBase" StackTrace "at MS.Win32.UnsafeNativeMethods.GetWindowText(HandleRef hWnd, StringBuilder lpString, Int32 nMaxCount)"
沒有調試器,異常是不可見的。
該異常是從 WPF 框架方法System.Windows.Automation.Peers.GenericRootAutomationPeer.GetNameCore
引發的,因為在該方法中使用了 ElementHost 的 WPF 部分的已經處理的窗口句柄base.Hwnd
,如下所示:
namespace System.Windows.Automation.Peers // from PresentationCore.dll
{
public class GenericRootAutomationPeer : UIElementAutomationPeer
{
...
protected override string GetNameCore()
{
string text = base.GetNameCore();
if (text == string.Empty)
{
IntPtr hwnd = base.Hwnd;
if (hwnd != IntPtr.Zero)
{
try
{
StringBuilder stringBuilder = new StringBuilder(512);
Throws ======> MS.Win32.UnsafeNativeMethods.GetWindowText(new HandleRef(null, hwnd), stringBuilder, stringBuilder.Capacity);
text = stringBuilder.ToString();
}
catch (Win32Exception)
{
}
if (text == null)
{
text = string.Empty;
}
}
}
return text;
}
設置 AutomationProperties.NameProperty 可確保base.GetNameCore()
返回有效字符串,從而導致跳過有問題的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.