Как разместить контент WPF в приложениях MFC? - PullRequest
17 голосов
/ 06 мая 2009

Я собираюсь ответить на свой вопрос здесь, потому что я потратил несколько часов на то, чтобы сложить все вместе и хотел поделиться тем, что нашел, в надежде, что я спасу кого-то еще от раскопок.

Существует MSDN Walkthrough , который поможет вам в этом, но есть пара ключевых моментов, которые я нашел в другом месте. Например, пошаговое руководство говорит вам поместить строку [System :: STAThreadAttribute] перед определением _tWinMain (), но если вы реализуете стандартное приложение MFC, в вашем исходном коде нет _tWinMain ().

Если что-то здесь неясно, не стесняйтесь задавать вопросы, и я отредактирую ответ, чтобы прояснить ситуацию.

1 Ответ

23 голосов
/ 06 мая 2009

Шаг 1. Настройка приложения MFC для компиляции с поддержкой CLR

Лучший способ добиться совместимости между собственным C ++ и управляемым кодом .NET - это компилировать приложение как управляемый C ++, а не как собственный C ++. Это можно сделать, перейдя в Свойства конфигурации проекта. В разделе «Общие» есть опция «Common Language Runtime support». Установите для этого параметра «Common Language Runtime Support /clr".

».

Шаг 2. Добавление сборок WPF в проект

Щелкните правой кнопкой мыши проект в обозревателе решений и выберите «Ссылки». Нажмите «Добавить новую ссылку». На вкладке .NET добавьте WindowsBase, PresentationCore, PresentationFramework и System. Убедитесь, что вы перестроили все после добавления каких-либо ссылок, чтобы их могли получить.

Шаг 3: Установить атрибут STAThreadAttribute для приложения MFC

WPF требует, чтобы STAThreadAttribute был установлен в основном потоке пользовательского интерфейса. Установите это, перейдя в Configuration Properties проекта. Под Linker-> Advanced есть опция под названием «Атрибут потока CLR». Установите для этого параметра «Атрибут потоков STA».

Шаг 4. Создайте экземпляр HwndSource для переноса компонента WPF

System :: Windows :: Interop :: 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) source-> 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.

...