最近有个项目涉及到在原有MFC项目中使用C#编写的.NET控件的问题,几经周折总算搞定,整理下步骤,以备后面需要。
1、环境:VS2008+WIN7
2、语言:MFC、c#
3、目的:在MFC中使用C#编写的自定义控件,控件是包含可视化内容的,本例中主要是包含了一个WEB浏览页。
下面开始正式介绍:
一、定义.NET控件:
1、 使用c#自定义一个控件:
这个无需太多介绍了,就是新建一个C#的Windows窗体控件库,内容随便写了。
2、 为控件添加事件:
public event EventHandler NewWebURL;
EventHandler为.net默认的委托类型
3、向外抛出事件:
MyEventArgs _args = new MyEventArgs();
_args.Para_String = this.txtTop.Text;
_args.Para_Int = 8888;
NewWebURL(this, _args);
其中MyEventArgs为自定义的数据类,主要为了满足向外抛出想要的参数,具体定义如下:
public class MyEventArgs : EventArgs
{
public string Para_String { get; set; }
public int Para_Int { get; set; }
}
4、添加供MFC调用的函数:
就是定义一个普通的public类型的函数即可,如下:
public string CallLib(string _msg)
{
_msg = string.Format("{0}_{1}", _msg, DateTime.Now.ToString());
return _msg;
}
二、集成到MFC中:
1、新建一个MFC的DLG工程:
2、添加必要的头文件引用:
在stdafx.h中添加#include <afxwinforms.h>
3、引用控件到此工程:
引用方法与在C#工程中引用控件方法一致,鼠标右键点击工程,选择“引用”,找到控件的DLL即可。
4、声明引用的控件:
一般是在DLG的头文件中,一般放在“// 标准构造函数”后面即可,如下:
CWinFormsControl<WFCLibrary::UserControl1> m_ctrl1;
WFCLibrary为控件的命名空间,UserControl1为控件类名称,m_ctrl1即为声明的可供DLG调用的控件。
5、绑定控件到DLG界面:
在DLG界面编辑窗口,新建一个StaticText控件,定义名称为IDC_STATIC_CTRL
在DLG.CPP中,手工添加数据绑定内容,粗体为添加内容:
void CMFCDlgContinerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_ManagedControl(pDX, IDC_STATIC, m_ctrl1);
}
6、MFC调用.NET控件的函数方法:
CString _msg = (CString)m_ctrl1->CallLib((System::String^)"fdafdsa");AfxMessageBox(_msg);
注意数据类型转换。
7、响应控件抛出的事件:
7.1在DLG头文件中添加事件声明,一般与CWinFormsControl<WFCLibrary::UserControl1> m_ctrl1放在一起,如下:
CWinFormsControl<WFCLibrary::UserControl1> m_ctrl1;
BEGIN_DELEGATE_MAP( CMFCDlgContinerDlg )
EVENT_DELEGATE_ENTRY(CSMyEventFunc,System::Object^, System::EventArgs^ )
END_DELEGATE_MAP()
CSMyEventFunc即为接收到事件时的响应函数
7.2添加事件绑定声明,可在OnInitDialog()中添加,如下:
m_ctrl1->NewWebURL +=MAKE_DELEGATE( System::EventHandler, CSMyEventFunc );
7.3添加本地事件处理函数:
CSMyEventFunc即为接收到事件时的响应函数,定义如下:
//接收到事件,开始本地处理
void CMFCDlgContinerDlg::CSMyEventFunc(System::Object^, System::EventArgs^ msg)
{
WFCLibrary::MyEventArgs^_tmp = (WFCLibrary::MyEventArgs^)msg;
AfxMessageBox((CString)(_tmp->Para_String));
}
至此,事件添加即可完成,MFC就能接收到.NET控件抛出的事件了。
补充:当然,既然在MFC中引用了.NET控件,MFC的工程设定里就一定要选择“公共语言运行时支持(/clr)”。