通过MFC写了很多代码,后来在一个.NET程序中希望调用一些已经存在的功能模块,而不希望重新使用.NET语言重写,所以开始测试MFC与.NET相互调用是否可行,结果证明完全可以。
1、MFC调用.NET窗口:
1.1、创建一个MFC对话框程序MfcApp,在其中增加一个.NET的WinForm窗口MyWinForm。
1.2、在对话框CMfcAppDlg上增加一个Button,并添加一个消息响应函数OnBnClickedButton1()。
1.3、在MfcAppDlg.cpp中包含头文件#include "mywinform.h",并且在OnBnClickedButton1()函数中增加如下的代码
void CMfcAppDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
MyWinForm ^frm=gcnew MyWinForm;
frm->ShowDialog();
}
1.4、设置MfcApp的配置属性“公共语言运行库支持(/clr)”,编译程序,运行程序,点击Button1,则弹出MyWinForm窗口。表示MFC对话框中调用.NET窗口成功。
2、在MyWinForm窗口中显示MFC对话框
2.1、接上面的程序,在程序中添加一个新的MFC对话框CADlg。
2.2、在MyWinForm.h中包含如下的头文件
#include "stdafx.h"
#include "resource.h"
#include "ADlg.h"
2.3、在MyWinForm窗体上增加一个button1,并在button的消息响应函数中增加如下代码
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
CADlg dlg;
dlg.DoModal();
}
2.3、编译并运行程序,首先弹出第一个MFC对话框,点击上面的按钮,将弹出MyWinForm窗口(这是一个.NET),在MyWinForm窗口上点击button1,则弹出第二个MFC对话框CADlg,表示在.NET窗口中调用MFC对话框成功。
3、在.NET窗口中动态创建MFC控件
3.1、接上面的程序,在MyWinForml类中增加两个指针(注意只能是指针,不允许直接写变量)
CEdit * m_pEdit;
CWnd *pParent;
3.2、在MyWinForml的MyWinForm_Load函数中动态创建CEdit控件,在MyWinForm_FormClosed()函数中是否指针,在MyWinForm_SizeChanged()函数中定位CEdit控件,代码如下:
private: System::Void MyWinForm_Load(System::Object^ sender, System::EventArgs^ e)
{AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
m_pEdit=new CEdit;
pParent=new CWnd;
pParent->Attach((HWND)this->Handle.ToInt32() );
if(m_pEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(1,1,300,100),pParent,100))
{
m_pEdit->ShowWindow(SW_SHOW);
m_pEdit->SetWindowTextW(_T("这是MFC中的CEdit控件"));
}
else
{
delete m_pEdit;
m_pEdit=NULL;
}
}
private: System::Void MyWinForm_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e) {
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
delete m_pEdit;
pParent->Detach();
delete pParent;
}
private: System::Void MyWinForm_SizeChanged(System::Object^ sender, System::EventArgs^ e) {
if(m_pEdit && m_pEdit->GetSafeHwnd())
m_pEdit->MoveWindow(0,0,this->ClientSize.Width,this->ClientSize.Height);
}
3.3、执行2.3中的步骤,在弹出的MyWinForm中将会显示动态创建的CEdit控件,表示.NET窗口中动态创建MFC控件成功。
注意事项:
1)在MFC程序中调用或操作.NET类或数据,必须设置项目的配置属性“公共语言运行库支持(/clr)”。
2).NET窗口中创建或显示MFC的控件时必须提供一个Parent指针,这个指针可以通过下面的代码获得
pParent=new CWnd;
pParent->Attach((HWND)this->Handle.ToInt32() );
使用完之后一定要pParent->Detach();否则将出错。
3)new完成一个指针之后,一定要delete,gcnew一个指针之后不需要delete。
4)如果希望在DLL中封装一个WinForm,该WinForm上动态创建MFC的控件,那么必须在创建控件代码之前增加如下的代码:AFX_MANAGE_STATE(AfxGetStaticModuleState( ));否则,这个WinForm无法显示。
关于AFX_MANAGE_STATE(AfxGetStaticModuleState( ));代码的作用查看MSDN,其中有详细的说明。
另外,在MFC的DLL中写一个.NET类,在VB.NET或C#中都可以直接调用,只要添加引用即可。然而在MFC应用程序中封装一个.NET类,在VB.NET中却不可以调用,总是产生如下的错误,尽管VB可以直接调用C#或VB可执行文件中的.NET类。