2009-05-06 2 views
16

나는 몇 시간을 함께 모으고 다른 누군가를 파헤 치게 할 것이라는 희망에서 발견 한 것을 나누고 싶었 기 때문에 여기에 내 자신의 질문에 대답 할 것입니다.MFC 응용 프로그램에서 WPF 컨텐트를 호스트하는 방법은 무엇입니까?

대부분의 방법을 제공하는 MSDN Walkthrough이 있지만 다른 곳에서 발견 한 몇 가지 중요한 부분이 있습니다. 예를 들어 walkthrough는 _tWinMain() 정의 앞에 [System :: STAThreadAttribute] 행을 배치하라는 메시지를 표시하지만 표준 MFC 응용 프로그램을 구현하는 경우에는 소스 코드에 _tWinMain()이 없습니다.

여기에 어떤 것이 명확하지 않은 경우 자유롭게 질문을하면 답을 수정하여 문제를 분명히합니다.

답변

22

1 단계 : CLR 지원

네이티브 C++ 및 관리 .NET 코드 간의 상호 운용성을 달성하는 가장 좋은 방법을 컴파일하는 MFC 응용 프로그램을 구성 ++ 오히려 네이티브 C보다 ++ 관리 C로 응용 프로그램을 컴파일하는 것입니다. 이 작업은 프로젝트의 구성 속성으로 이동하여 수행됩니다. General 아래에는 "Common Language Runtime support"옵션이 있습니다. 이것을 "Common Language Runtime Support/clr"로 설정하십시오.

2 단계 :

이 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 "참조"를 선택 프로젝트에 WPF 어셈블리를 추가합니다. "Add New Reference"를 클릭하십시오. .NET 탭에서 WindowsBase, PresentationCore, PresentationFramework 및 System을 추가합니다. 모든 참조를 추가 한 후에 모두 다시 작성하여 가져 왔는지 확인하십시오.

3 단계 : MFC 애플리케이션

에 STAThreadAttribute 세트 WPF는 STAThreadAttribute 메인 UI 스레드에 설정하는 것이 필요하다. 프로젝트의 구성 속성으로 이동하여 설정하십시오. Linker-> Advanced에는 "CLR Thread Attribute"라는 옵션이 있습니다. 이것을 "STA 스레딩 속성"으로 설정하십시오.

4 단계 : WPF 구성 요소를

시스템을 포장하여 HwndSource의 인스턴스를 만들기 :: 윈도우 :: 상호 운용성 ::하여 HwndSource는 MFC 및 .NET 구성 요소 사이의 상호 작용을 처리하는 .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 단계 :하여 HwndSource 래퍼에 WPF 컨트롤을 추가

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

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

6 단계 : 후 범위를 벗어나 이동합니다 브라우저 변수 이래 WPF 개체

에 대한 참조를 유지 우리는 생성을 수행하는 함수를 빠져 나가고, 어떻게 든 그것을 참조 할 필요가 있습니다.관리 객체는 관리되지 않는 객체의 멤버가 될 수 없지만 gcroot라는 래퍼 템플릿을 사용하여 작업을 완료 할 수 있습니다.

대화 상자 클래스에 멤버 변수를 추가

m_webBrowser = browser; 

지금 우리는 WPF 구성 요소에 속성과 메서드에 액세스 할 수 있습니다

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

그런 다음 5 단계의 코드에 다음 행을 추가 m_webBrowser를 통해.

+0

아주 좋습니다. 게시 해 주셔서 감사합니다. – Gishu

+1

source-> SizeToContent = System :: Windows :: SizeToContent :: WidthAndHeight; 이것은 내가 놓친 것이었다! +1 –

+2

추가 정보는 StaThreadModel을 설정하지 않으면 MFC 내에서 매우 신비하게 충돌합니다. 그리고 메인 실행 응용 프로그램에서 스레드 모델을 설정해야합니다. 나와 같은 대화 상대가 다른 DLL에서 대체하려고하면, ** unluded DLL에 CLR 스레드 속성을 설정하면 ** 도움이되지 않습니다 **. 그것은 다른 사람들에게 명백 할 수도 있지만 그것은 내 것이 아니 었습니다. – Dervall