Using a WPF control in a MFC application

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();

Leave a Reply

Your email address will not be published. Required fields are marked *