MFC and WPF Interop
Cancellation with .NET 4 (Part 1)

Resource Management in Interop Scenarios

In a previous blog post I’ve shown a scenario for interop between MFC/C++ and WPF. This blog post didn’t further mention the requirements to release the resources. Naveen also mentioned this in a comment. This information is added here.

With the sample code a UserControl1 and a HwndSource object are instantiated.

HWND CMFCDialogAppDlg::GetUserControl1Hwnd(HWND parent, int x, int y, int width, int height)
{
HwndSourceParameters^ sourceParams = gcnew HwndSourceParameters("MFCWPFApp");
sourceParams->PositionX = x;
sourceParams->PositionY = y;
sourceParams->Height = height;
sourceParams->Width = width;
sourceParams->ParentWindow = IntPtr(parent);
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD;
m_hwndSource = gcnew HwndSource(*sourceParams);
m_wpfUC = gcnew UserControl1();
m_hwndSource->RootVisual = m_wpfUC;
return (HWND) m_hwndSource->Handle.ToPointer();
}

Both of these types implement the IDisposable interface, and thus the Dispose method should be invoked. Using C++/CLI, the Dispose method can be invoked by using the delete operator. The compiler changes delete to an invocation of the Dispose method.

CMFCDialogAppdlg::~CMFCDialogAppdlg()
{
delete m_hwndSource;
delete m_wpfUC;
}

The gcnew operator allocates an object on the managed heap. The delete operator does not release the object from the managed heap but invokes the Dispose method if available. This is a different behavior from the new/delete operators and the native heap.

What could be changed in the sample in regard to resource consumption is the use of the HwndSourceParameters. HwndSourceParameters is a managed value type and thus can be stored on the managed heap, the native heap, or the stack. Without the gcnew operator sourceParams is on the stack:

HWND CMFCDialogAppDlg::GetUserControl1Hwnd(HWND parent, int x, int y, int width, int height)
{
HwndSourceParameters sourceParams("MFCWPFApp");
sourceParams.PositionX = x;
sourceParams.PositionY = y;
sourceParams.Height = height;
sourceParams.Width = width;
sourceParams.ParentWindow = IntPtr(parent);
sourceParams.WindowStyle = WS_VISIBLE | WS_CHILD;
m_hwndSource = gcnew HwndSource(sourceParams);
m_wpfUC = gcnew UserControl1();
m_hwndSource->RootVisual = m_wpfUC;
return (HWND) m_hwndSource->Handle.ToPointer();
}

Christian

More information:

Comments

Feed You can follow this conversation by subscribing to the comment feed for this post.

The comments to this entry are closed.