2017-05-11 1 views
0

HwndSourceを直接作成してウィンドウを作成しようとしています。現時点では、Windowクラスを継承している代替ソリューションがありますが、私のHwndSource実装で何が問題なのか不思議です。 WindowはコアにHwndSourceを使用しているので、方法があるはずです。ここで直接HwndSourceを作成する

は、私のコードの簡易版である:

private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
{ 
    HwndSource wndPopup = new HwndSource(0, 0x12cf0000/*WS_VISIBLE|WS_OVERLAPPEDWINDOW*/, 0, 10, 10, 500, 500, "Test", IntPtr.Zero); 
    wndPopup.RootVisual = new Rectangle() { Fill = Brushes.Red, Width = 100, Height = 100 }; 
} 

ウィンドウが期待通りに作成したが、私は(Altキー+ F4または閉じるアイコン)を閉じて、私のメインウィンドウの上にマウスを移動した後、メッセージをたくさんされてデバッガにスピッティングされています

例外がスロー: 'System.ComponentModel.Win32Exception' をWindowsBase.dllに

例外の詳細は以下のとおりです。

Exception thrown: 'System.ComponentModel.Win32Exception' in WindowsBase.dll 
Additional information: Invalid window handle 

スタックトレース:

WindowsBase.dll!MS.Win32.UnsafeNativeMethods.GetWindowText(System.Runtime.InteropServices.HandleRef, System.Text.StringBuilder, int) 
PresentationCore.dll!System.Windows.Automation.Peers.GenericRootAutomationPeer.GetNameCore() 
PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() 
PresentationCore.dll!System.Windows.ContextLayoutManager.fireAutomationEvents() 
PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout() 
PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayoutCallback(object) 
PresentationCore.dll!System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork() 
PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() 
PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object) 
PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandler(object) 
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, object, int) 
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object, System.Delegate, object, int, System.Delegate) 
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() 
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object) 
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, object, bool) 
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, object, bool) 
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, object) 
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() 
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() 
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr, int, System.IntPtr, System.IntPtr, ref bool) 
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr, int, System.IntPtr, System.IntPtr, ref bool) 
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object) 
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, object, int) 
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object, System.Delegate, object, int, System.Delegate) 
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, object, int) 
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr, int, System.IntPtr, System.IntPtr) 
[Native to Managed Transition]  
[Managed to Native Transition]  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame) 
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame) 
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object) 
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window) 
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window) 
PresentationFramework.dll!System.Windows.Application.Run() 
WpfCombox.exe!WpfCombox.App.Main() 
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.ExecuteAssembly(string, System.Security.Policy.Evidence, string[]) 
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object) 
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, object, bool) 
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, object, bool) 
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, object) 
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() 

ので、エラーが深いフレームワークコードのどこかで発生します。

Disposedハンドラに他のプロパティを追加したり、クリーンアップを追加しようとしましたが、結果に影響はありません。 RootVisualを設定しないと、エラーはありません(ただし、オプションではありません)。

アイデアは何ですか?

+0

複製できません。私の窓はうまく動作するようです。閉鎖後、私は例外を見ません。 – AQuirky

+0

@AQuirkyちょうど明確にする:それは未処理の例外ではありません。メッセージは出力ウィンドウに書き込まれ、プログラムは続行されます。しかし、1)何かが間違っていることを示します。2)そのようなメッセージがたくさん出力に追加されるので、デバッグがひどく遅くなります。 – nevermind

+0

はい、わかります。私はデバッガの出力ウィンドウに何も持っていません。 – AQuirky

答えて

0

解決策の1つは、ルートビジュアルの自動化ピアを作成することです。それ以外の場合は、フレームワークによってGenericRootAutomationPeerが作成され、GetWindowText Windows APIが呼び出されます。

public class PopupRootAutomationPeer : UIElementAutomationPeer 
{ 
    public PopupRootAutomationPeer(FrameworkElement owner) 
     : base(owner) { } 

    protected override string GetClassNameCore() 
    { 
     return "Pane"; 
    } 

    protected override AutomationControlType GetAutomationControlTypeCore() 
    { 
     return AutomationControlType.Pane; 
    } 

    protected override string GetNameCore() 
    { 
     return "PopupRootAutomationPeer"; 
    } 
} 

// Wrap content of the window with this class 
class PopupRoot : Canvas 
{ 
    protected override AutomationPeer OnCreateAutomationPeer() 
    { 
     return new PopupRootAutomationPeer(this); 
    } 
} 

はおそらくオートメーションが非既存のウィンドウで呼び出されないように、それは、閉じたときにHwndSourceをdeinitializeする方法があるが、私はまだそれを発見していません。

関連する問題