Hosting a Windows Form User Control as an MFC Dialog Box
MFC provides the template class CWinFormsDialog so that you can host a Windows Forms user control (UserControl) in a modal or modeless MFC dialog box. CWinFormsDialog
is derived from the MFC class CDialog, so the dialog box can be launched as modal or modeless.
The process that CWinFormsDialog
uses to host the user control is the similar to that described in Hosting a Windows Form User Control in an MFC Dialog Box. However, CWinFormsDialog
manages the initialization and hosting of the user control so that it does not have to be programmed manually.
To create the MFC host application
Create an MFC Application project.
On the File menu, select New, and then click Project. In the Visual C++ folder, select MFC Application.
In the Name box, enter
MFC03
and change the Solution setting to Add to Solution.Click OK.In the MFC Application Wizard, accept all the defaults, and then click Finish. This creates an MFC application with a Multiple Document Interface.
Configure the project.
In Solution Explorer, right-click the MFC03 project node, and choose Properties. The Property Pages dialog box appears.
In the Property Pages dialog box, select Configuration Properties > General. In the Project Defaults section, set Common Language Runtime support to Common Language Runtime Support (/clr). Choose OK.
Add a reference to the .NET control.
In Solution Explorer, right-click the MFC03 project node and choose Add, References. In the Property Page, click Add New Reference, select WindowsControlLibrary1 (under the Projects tab), and click OK. This adds a reference in the form of a /FU compiler option so that the program will compile; it also copies WindowsControlLibrary1.dll into the
MFC03
project directory so that the program will run.Add
#include <afxwinforms.h>
to pch.h (stdafx.h in Visual Studio 2017 and earlier), at the end of the existing#include
statements.Add a new class that subclasses
CDialog
.Right click on project name and add an MFC class (called CHostForWinForm) that subclasses
CDialog
. Since you do not need the dialog box resource, you can delete the resource ID (select Resource View, expand the Dialog folder and deleteIDD_HOSTFORWINFORM
resource. Then, remove any references to the ID in code.).Replace
CDialog
in CHostForWinForm.h and CHostForWinForm.cpp files withCWinFormsDialog<WindowsControlLibrary1::UserControl1>
.Call DoModal on the CHostForWinForm class.
In MFC03.cpp, add
#include "HostForWinForm.h"
.Before the return statement in the definition of CMFC03App::InitInstance, add:
CHostForWinForm m_HostForWinForm; m_HostForWinForm.DoModal();
Build and run the project.
On the Build menu, click Build Solution.
On the Debug menu, click Start without debugging.
Next you will add code to monitor the state of a control on the Windows Forms from the MFC application.
Add a handler for OnInitDialog.
Display the Properties window (F4). In Class View, select CHostForWinForm. In the Properties window, select overrides and in the row for OnInitDialog, click in the left hand column and select < Add >. This adds the following line to CHostForWinForm.h:
virtual BOOL OnInitDialog();
Define OnInitDialog (in CHostForWinForm.cpp) as follows:
BOOL CHostForWinForm::OnInitDialog() { CWinFormsDialog<WindowsControlLibrary1::UserControl1>::OnInitDialog(); GetControl()->button1->Click += MAKE_DELEGATE(System::EventHandler, OnButton1); return TRUE; }
Next add the OnButton1 handler. Add the following lines to the public section of the CHostForWinForm class in CHostForWinForm.h:
virtual void OnButton1( System::Object^ sender, System::EventArgs^ e ); BEGIN_DELEGATE_MAP( CHostForWinForm ) EVENT_DELEGATE_ENTRY( OnButton1, System::Object^, System::EventArgs^ ); END_DELEGATE_MAP()
In CHostForWinForm.cpp, add this definition:
void CHostForWinForm::OnButton1( System::Object^ sender, System::EventArgs^ e ) { System::Windows::Forms::MessageBox::Show("test"); }
Build and run the project. When you click the button, which is on the Windows Form, code in the MFC application will run.
Next you will add code to display from the MFC code the value in the text box on the Windows Form.
In the public section of the CHostForWinForm class in CHostForWinForm.h, add the following declaration:
CString m_sEditBoxOnWinForm;
In the definition of DoDataExchange in CHostForWinForm.cpp, add the following three lines to the end of the function:
if (pDX->m_bSaveAndValidate) m_sEditBoxOnWinForm = CString( GetControl()->textBox1->Text); else GetControl()->textBox1->Text = gcnew System::String(m_sEditBoxOnWinForm);
In the definition of OnButton1 in CHostForWinForm.cpp, add the following three lines to the end of the function:
this->UpdateData(TRUE); System::String ^ z = gcnew System::String(m_sEditBoxOnWinForm); System::Windows::Forms::MessageBox::Show(z);
Build and run the project.
See also
System.Windows.Forms.UserControl Using a Windows Form User Control in MFC