0

WindowInteropHelper クラスを使用してウィンドウ ハンドルを取得できるように、特に System.Windows.Window クラスから継承する WPF フォーム (WSWindow という名前) を表示しようとしている C++ アプリケーションがあります。

私の問題は、以下のメソッドを呼び出すたびに、アプリケーションがクラッシュすることです。

public IntPtr GetHWND()
{
    if (ivWindow == null)
    {
        ivWindow = new WSWindow();

        ivWindow.WindowStartupLocation = WindowStartupLocation.Manual;

        ivWindow.Show();
    }

    IntPtr handle = new WindowInteropHelper(ivWindow).Handle;

    return handle;                    
}

WSWindow コンストラクターがクラッシュを引き起こしていると思います。C# 側では、WSWindow コンストラクターを呼び出す WSService クラスがあり、WSService コンストラクターに WSWindow コンストラクターを配置すると、WSService コンストラクターの呼び出し時に C++ アプリがクラッシュします (WSService コンストラクターにWSWindow コンストラクタ)。また、上記のメソッドを呼び出すことに加えて、C++ アプリで次のことを試しました。

WSWindow^ w = gcnew WSWindow();

この行の直後に、ログ ファイルに書き込まれないログ行があります。

WSWindow コンストラクターには、WSWindow.g.cs ファイルで生成されたコードである InitializeComponents への呼び出しがあります。

[System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public void InitializeComponent() {
        if (_contentLoaded) {
            return;
        }
        _contentLoaded = true;
        System.Uri resourceLocater = new System.Uri("/Project_Name;component/wswindow.xaml", System.UriKind.Relative);

        #line 1 "..\..\WSWindow.xaml"
        System.Windows.Application.LoadComponent(this, resourceLocater);

        #line default
        #line hidden
    }

最初は、URI を解決できなかったために LoadComponent の呼び出しが失敗したのではないかと考えましたが、Windows フォーム テストから WSWindow が作成されたときに書き込まれる InitializeComponent() の呼び出しの前に、WSWindow コンストラクターにログ行を追加しました。アプリですが、C++ アプリからの呼び出しによって WSWindow が作成された場合はそうではないため、WSWindow コンストラクターで何も実行されないように見え、すぐにクラッシュします。

私が知ることができる参照には問題はありません。1 つは int を返すテスト メソッド、もう 1 つは幅/高さのメンバーを持つ単純なカスタム Window オブジェクトで、C++ アプリから両方を正常に呼び出しました。

また、WSWindow が WPF アプリとしてコンパイルされ、C++ アプリを起動する前に実行されるときに、WSWindow へのハンドルを正常に取得しましたが、C++ アプリ内の呼び出しから WSWindow を作成できるようにする必要があります。

私はこの問題に何日も費やして、クラッシュがうまくいかない理由を突き止めようとしました。これを読んだ誰かが、この問題を引き起こしている可能性のある WPF について、または C++/CLI と WPF コントロールの間の既知の問題について何か知っていることを願っています。私は完全にアイデアがありません。

追加情報: C++ アプリを起動してプロセスに VS をアタッチすると、コール スタックには何も表示されません (これは私が取り組むべき別の問題です)。

First-chance exception at 0x75a8b9bc (KernelBase.dll) in MM.EXE: Microsoft C++ exception: HRException at memory location 0x06e6b158..
First-chance exception at 0x75a8b9bc (KernelBase.dll) in MM.EXE: Microsoft C++ exception: [rethrow] at memory location 0x00000000..
First-chance exception at 0x75a8b9bc (KernelBase.dll) in MM.EXE: Microsoft C++ exception: HRException at memory location 0x06e6b608..
First-chance exception at 0x75a8b9bc (KernelBase.dll) in MM.EXE: Microsoft C++ exception: [rethrow] at memory location 0x00000000..
4

1 に答える 1

1

解決策は、[STAThread] 属性を使用して WPF ウィンドウを作成/表示する呼び出しを行うスレッドをマークする必要があるということでした。

于 2012-05-30T19:36:28.003 に答える