2009-05-06 31 views
16

Tôi sẽ trả lời câu hỏi của riêng tôi ở đây vì tôi đã dành một vài giờ chắp nối điều này với nhau và muốn chia sẻ những gì tôi tìm thấy với hy vọng rằng tôi sẽ cứu người khác đào bới.Làm cách nào để lưu trữ nội dung WPF trong Ứng dụng MFC?

Có một MSDN Walkthrough mang đến cho bạn hầu hết mọi cách, nhưng có một vài phần quan trọng mà tôi tìm thấy ở nơi khác. Ví dụ, hướng dẫn cho bạn biết đặt dòng [System :: STAThreadAttribute] trước định nghĩa _tWinMain() nhưng nếu bạn đang triển khai một ứng dụng MFC chuẩn thì bạn không có _tWinMain() trong mã nguồn của bạn.

Nếu bất cứ điều gì ở đây không rõ ràng, vui lòng đặt câu hỏi và tôi sẽ chỉnh sửa câu trả lời để làm cho mọi thứ rõ ràng hơn.

Trả lời

22

Bước 1: Cấu hình các ứng dụng MFC để biên dịch với sự hỗ trợ CLR

Cách tốt nhất để đạt được khả năng tương tác giữa mẹ đẻ C++ và mã NET quản lý là để biên dịch các ứng dụng như quản lý C++ chứ không phải là bản ngữ C++. Điều này được thực hiện bằng cách vào phần Configuration Properties của dự án. Dưới mục General có một tùy chọn "Common Language Runtime support". Đặt điều này thành "Hỗ trợ thời gian chạy ngôn ngữ chung/clr".

Bước 2: Thêm các hội WPF cho dự án

Nhấp chuột phải vào các dự án trong Solution Explorer và chọn "Tham khảo". Nhấp vào "Thêm tham chiếu mới". Trong tab .NET, thêm WindowsBase, PresentationCore, PresentationFramework và System. Hãy chắc chắn rằng bạn xây dựng lại tất cả sau khi thêm bất kỳ tài liệu tham khảo để cho họ để có được chọn.

Bước 3: Đặt STAThreadAttribute về việc áp dụng MFC

WPF đòi hỏi STAThreadAttribute được thiết lập trên thread UI chính. Thiết lập điều này bằng cách vào Configuration Properties của dự án. Dưới Linker-> Advanced có một tùy chọn gọi là "CLR Thread Attribute". Đặt điều này thành "thuộc tính luồng STA".

Bước 4: Tạo một thể hiện của HwndSource để bọc các thành phần WPF

Hệ thống :: của Windows :: Interop :: HwndSource là một lớp .NET để xử lý sự tương tác giữa MFC và .NET thành phần. Tạo một tài khoản bằng cách sử dụng cú pháp sau:

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; 

Thêm một biến thành viên HWND đến lớp hộp thoại và sau đó gán nó như thế này: m_hWnd = (HWND) source> Handle.ToPointer();

Đối tượng nguồn và nội dung WPF được liên kết sẽ vẫn tồn tại cho đến khi bạn gọi :: DestroyWindow (m_hWnd).

Bước 5: Thêm điều khiển WPF cho wrapper HwndSource

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

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

Bước 6: Giữ một tham chiếu đến đối tượng WPF

Kể từ khi biến trình duyệt sẽ đi ra khỏi phạm vi sau chúng ta thoát khỏi chức năng đang tạo ra, chúng ta cần bằng cách nào đó giữ một tham chiếu đến nó.Các đối tượng được quản lý không thể là thành viên của các đối tượng không được quản lý nhưng bạn có thể sử dụng một mẫu trình bao bọc được gọi là gcroot để hoàn thành công việc.

Thêm một biến thành viên lớp thoại:

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

Sau đó, thêm dòng sau vào mã trong Bước 5:

m_webBrowser = browser; 

Bây giờ chúng ta có thể truy cập vào các thuộc tính và các phương pháp trên thành phần WPF thông qua m_webBrowser.

+0

rất đẹp. Cảm ơn vì đăng. – Gishu

+1

nguồn-> SizeToContent = Hệ thống :: Windows :: SizeToContent :: WidthAndHeight; Đây là những gì tôi đã mất tích! +1 –

+2

Một đoạn thông tin bổ sung, nếu bạn không đặt StaThreadModel, nó sẽ sụp đổ khá sâu trong MFC. Và bạn cần phải đặt mô hình chuỗi trên ứng dụng thực thi chính. Nếu bạn, giống như tôi, có hộp thoại bạn muốn thay thế trong một DLL khác, nó sẽ ** không ** trợ giúp nếu bạn thiết lập thuộc tính thread CLR trên DLL chưa bao hàm. Nó có thể hiển nhiên với người khác, nhưng không phải với tôi. – Dervall

Các vấn đề liên quan