I’ve been working on some MFC application and to apply my WPF knowledge I added a WPF control written in C# to my MFC CView with the following code:
int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; try { gcroot<hwndsource ^> hwnd_source = gcnew HwndSource(0, WS_VISIBLE | WS_CHILD, 0, 0, 0, "HwndSource", IntPtr(m_hWnd)); MyWpfControl ^ control = gcnew MyWpfControl(); hwnd_source->RootVisual = control; } catch (Exception ^ ex) { String ^ msg = ex->Message; } return 0; }
All that I needed to do is to follow the steps described in this post: How do I host WPF content in MFC Applications, fix VS2012 bug described here, and got rid of std::mutex and std::lock_guard replacing them with the following classes using typedefs:
namespace awl { class kernel_mutex { public: kernel_mutex() { hMutex = ::CreateMutex(NULL, FALSE, NULL); AWL_ASSERT(hMutex != INVALID_HANDLE_VALUE); } ~kernel_mutex() { AWL_VERIFY(::CloseHandle(hMutex) != FALSE); } void lock() { AWL_VERIFY(::WaitForSingleObject(hMutex, INFINITE) == 0); } void unlock() { AWL_VERIFY(::ReleaseMutex(hMutex) != FALSE); } private: HANDLE hMutex; }; template <class T> class lock_guard { public: lock_guard(T & m) : Mutex(m) { Mutex.lock(); } ~lock_guard() { Mutex.unlock(); } private: T & Mutex; }; }; //namespace awl typedef awl::kernel_mutex mutex; typedef awl::lock_guard<mutex> lock_guard;
Also I turned off ZI and Cm compiler options that are not compatible with CLI (/crl) and linked MFC and runtime dynamically.
The only small thing that I have not solved yet is that some MFC DLL triggered fore asserts at startup probably related to thread local storage and MFC module state so I press “Ignore” button fourfold each time I start my application.
The alternate way to add WPF content to existing MFC application is to show entire WPF window with the following code:
MyWpfWindow ^ window = gcnew MyWpfWindow(); System::Windows::Interop::WindowInteropHelper ^ helper = gcnew System::Windows::Interop::WindowInteropHelper(window); helper->Owner = IntPtr(m_hWnd); window->Show();