Подтвердить что ты не робот

Как разместить содержимое WPF в приложениях MFC?

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Шаг 3: Установите STAThreadAttribute в приложении MFC

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

Шаг 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.