質問者
C++, System::Windows::Interop::HwndSourceからSystem::Windows::Windowを取得できない?

質問
-
下記は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;
}
すべての返信
-
-
コード ブロックSystem::IntPtr hWnd = hwndSource->Handle;
で,子ウィンドウのハンドルを取得できるので,
完全信頼のアプリなら,そこからは WinAPI でやってくれってことかな。マネジドでやれてしまうと,XBAP などで具合がわるいのもあるのかも。
今の仕組みなら,子ウィンドウでXBAPを表示する限り,
親側へのアクセスを封じ込むことが可能になりますし。System.Windows.Window がトップレベルウィンドウのみのラッパならば,
ChildWindow のような Show() できない感じのマネジドクラスもあってもいいのかもしれない。
-
メモ:
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>で,例えば,
コード ブロック
gcroot<System::Windows::Interop::HwndSource^> m_hwndSource;のようにする。
-
メモ:
新規にスレッドを起こして,WPFを利用する場合は,
CoInitialize(NULL) して,STAにする他に,
Window表示後に,メッセージループ(ポンプ)を必要とする。これは,STA が,隠されたトップレベルWindowを使用しているため,
メッセージループがないと固まってしまいます。要するに,STAスレッドごとにメッセージループが必要。
もちろん,UIに絡まないバックグラウンドスレッドには不要。また,MTAで作成した ネイティブWindow に
新規STA(メッセージループ付き)での WPFのWindow を表示などというのも,
一見うまく行っているようで,サイズ変更などしてみれば,うまくマーシャリングできずに描画がおかしくなるのを確認できます。