2009-05-06 67 views
16

我在這裏回答我自己的問題,因爲我花了幾個小時將它們拼湊在一起,並希望分享我發現的內容,希望能夠拯救別人。如何在MFC應用程序中託管WPF內容?

有一個MSDN Walkthrough可以讓你在那裏的大部分路上,但有一些我在其他地方找到的關鍵部分。例如,演練告訴你在_tWinMain()定義之前放置[System :: STAThreadAttribute]行,但如果你正在實現一個標準的MFC應用程序,那麼你的源代碼中沒有_tWinMain()。

如果這裏有什麼不清楚的地方,隨時提問,我會編輯答案,使事情更清楚。

回答

22

步驟1:配置MFC應用程序來編譯與CLR支持

實現本地C++和管理的.NET代碼之間的互操作性的最好方法是將應用程序編譯爲託管C++,而不是本地C++。這通過轉到項目的配置屬性來完成。在常規下,有一個選項「公共語言運行時支持」。將其設置爲「Common Language Runtime Support/clr」。

第2步:WPF組件添加到項目在Solution Explorer中的項目

單擊鼠標右鍵,選擇「參考」。點擊「添加新參考」。在.NET選項卡下,添加WindowsBase,PresentationCore,PresentationFramework和System。確保在添加任何引用以便讓他們獲取後重建所有內容。

第3步:設置請將STAThreadAttribute在MFC應用程序

WPF要求請將STAThreadAttribute可以在主UI線程上設置。通過轉到項目的配置屬性進行設置。在鏈接器 - >高級下,有一個名爲「CLR線程屬性」的選項。將其設置爲「STA線程屬性」。

步驟4:創建HwndSource的實例,以包裹WPF部件

系統:視窗::互操作:: HwndSource是一個.NET類來處理MFC和.NET組件之間的交互。

System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew  System::Windows::Interop::HwndSourceParameters("MyWindowName"); 
sourceParams->PositionX = x; 
sourceParams->PositionY = y; 
sourceParams->ParentWindow = System::IntPtr(hWndParent); 
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; 

System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams); 
source->SizeToContent = System::Windows::SizeToContent::WidthAndHeight; 

添加HWND成員變量到對話框類,然後將其指定這樣的::使用以下語法創建一個 m_hWnd =(HWND)源 - > Handle.ToPointer();

源對象和關聯的WPF內容將保持存在狀態,直到調用:: DestroyWindow(m_hWnd)。

步驟5:將WPF控件添加到HwndSource包裝

System::Windows::Controls::WebBrowser^ browser = gcnew System::Windows::Controls::WebBrowser(); 

browser->Height = height; 
browser->Width = width; 
source->RootVisual = browser; 

步驟6:保持到WPF對象

基準由於瀏覽器變量會走出範圍後我們退出創建的函數,我們需要以某種方式對其進行引用。託管對象不能是非託管對象的成員,但可以使用名爲gcroot的包裝模板來完成工作。

一個成員變量添加到對話框類:

#include <vcclr.h> 
gcroot<System::Windows::Controls::WebBrowser^> m_webBrowser; 

以下行然後添加到代碼中第5步:

m_webBrowser = browser; 

現在,我們可以在WPF部件上訪問的屬性和方法通過m_webBrowser。

+0

非常好。感謝張貼。 – Gishu 2009-05-06 14:47:12

+1

source-> SizeToContent = System :: Windows :: SizeToContent :: WidthAndHeight;這就是我錯過的! +1 – 2010-07-22 16:02:41

+2

另外一條信息,如果你沒有設置StaThreadModel,它會在MFC內部非常神祕地崩潰。你需要在主可執行應用上設置線程模型。如果你像我一樣,想在另一個DLL中替換對話框,那麼如果你在未包含的DLL上設置了CLR線程屬性,它將不會**幫助。對其他人可能是顯而易見的,但它不是我。 – Dervall 2012-02-21 12:19:38

相關問題