none
C++, System::Windows::Interop::HwndSourceからSystem::Windows::Windowを取得できない? RRS feed

  • 質問

  • 下記はC++のよくあるxamlサンプルです。マネージドWindowクラスをを取得したいのですがよき方法はないものでしょうか?

     

    コード ブロック

    int CSampleView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
     if (CView::OnCreate(lpCreateStruct) == -1)
      return -1;

     System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters("hi");
       
        sourceParams->PositionX = 110;
        sourceParams->PositionY = 10;
        sourceParams->Height = 300;
        sourceParams->Width = 600;
        sourceParams->ParentWindow = IntPtr(m_hWnd);
        sourceParams->WindowStyle =  WS_CHILD |WS_VISIBLE;
     
        System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams);
     
     
     // Load xaml
     System::IO::Stream^ xamlStream = System::IO::File::OpenRead("XamlPad_Saved.xaml");  
     
     source->RootVisual = (Visual^)System::Windows::Markup::XamlReader::Load( xamlStream );

     xamlStream->Close(); 
     
     // Get root
     Visual^ rootv = source->RootVisual;

     // Get Window
     Window^ w = System::Windows::Window::GetWindow( rootv ); // nullになってしまう
     

     return 0;
    }

     

     

    2007年11月19日 9:59

すべての返信

  • 単に無い物は取れないってだけの話だと思いますが。

    2007年11月20日 0:25
  • Windowクラスが取得できないと、以下のOwnerを設定することができないのです。

    OwnerはC++のウインドウ内にあるHwndSourceです。

     

    Window^ w = gcnew MyWinodw();

    w->Owner = xxx; <-- ここに設定したいが、Windowクラスである

    w->Left = 0;

    w->Top=0;

    w->Show();

     

     

     

     

    2007年11月20日 3:53
  • 今度は逆に HwndHost を使って WPF ウィンドウに仕立てるとか。

    // WPF コンテンツをホストする Win32 ウィンドウをホストする WPF コンテンツ……ややこし。

     

    2007年11月20日 4:41
  • 全然試していないので、なんなんですが、

    source->RootVisualを設定する部分が

     

    コード ブロック

     Window^ rootWindow = gcnew System::Windows::Window();
     source->RootVisual = rootWindow;

     rootWindow->Content = (Visual^)System::Windows::Markup::XamlReader::Load( xamlStream );

     

     

    こんな感じでは駄目なんですかね ?

     

    2007年11月21日 2:34
  • WPF の Window は,
    トップレベルウィンドウとしてしか存在できないですよね。

    子ウィンドウの HwndSource による Win32 ウィンドウラッパ に Page は設定できますが,

    その子ウィンドウはトップレベルウィンドウではないので,

    GetWindow( ) ではとれないのでは?

     

    最初に作成する HwndSource による Win32ウィンドウラッパ の WindowStyle を

    WS_OVERLAPPEDWINDOW などにすれば,GetWindow() で取れるので,

    そうだと思います。たぶん。

    2007年11月21日 15:11
  • FC-Shiro さん、稍丼さん、レスありがとうございます。

    やはり、MSのサンプル以上のことをするのは難しいですね。

     

    もう少し様子を見てから、挑戦してみます。

     

    2007年11月22日 10:40
  • コード ブロック
    System::IntPtr hWnd = hwndSource->Handle;

     

     

    で,子ウィンドウのハンドルを取得できるので,
    完全信頼のアプリなら,そこからは WinAPI でやってくれってことかな。

    マネジドでやれてしまうと,XBAP などで具合がわるいのもあるのかも。
    今の仕組みなら,子ウィンドウでXBAPを表示する限り,
    親側へのアクセスを封じ込むことが可能になりますし。

     

    System.Windows.Window がトップレベルウィンドウのみのラッパならば,

    ChildWindow のような Show() できない感じのマネジドクラスもあってもいいのかもしれない。

    2007年11月22日 19:48
  • メモ:

     

    Win32 プロジェクト の雛形からテストする場合。
    プロジェクトのプロパティ -> 構成プロパティ (Configuration Properties) -> 全般 (General) の
    共通言語ランタイムサポート (Common Language Runtime support) を
    共通言語ランタイムサポート (/clr) (Common Language Runtime Support (/clr)) にし(お約束),


    で,WPF が STA(Single-Threaded Apartment) を要求するので

     

    コード ブロック

    [System::STAThread]
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {

    }

     

    のように System:: STAThreadAttribute 属性を追加。

     

    マネジドクラスをネイティブ側の関数内以外(グローバルやネイティブクラスのメンバ)に持ちたい場合。

    コード ブロック

    #include <vcclr.h>

     

    を stdafx.h 等に追加。

    で,例えば,

    コード ブロック

    gcroot<System::Windows::Interop::HwndSource^> m_hwndSource;

     

    のようにする。

    2007年11月23日 12:52
  • メモ:

     

    新規にスレッドを起こして,WPFを利用する場合は,
    CoInitialize(NULL) して,STAにする他に,
    Window表示後に,メッセージループ(ポンプ)を必要とする。

    これは,STA が,隠されたトップレベルWindowを使用しているため,
    メッセージループがないと固まってしまいます。

    要するに,STAスレッドごとにメッセージループが必要。
    もちろん,UIに絡まないバックグラウンドスレッドには不要。

     

    また,MTAで作成した ネイティブWindow に

    新規STA(メッセージループ付き)での WPFのWindow を表示などというのも,
    一見うまく行っているようで,サイズ変更などしてみれば,

    うまくマーシャリングできずに描画がおかしくなるのを確認できます。

    2007年12月13日 5:33