介绍这方面的文章不少,这里仅仅简明扼要提供代码和一些说明。
在要到处的MFC类加上AFX_EXT_CLASS,比如
class AFX_EXT_CLASS CMIVPToolDlg : public CDialog
即可形成到处类,用dumpbin查看发现几乎导出了所有的MFC函数,暂时不管他。
在客户端,也就是需要使用该MFC类的程序,加载方式,在工程中加入.lib库以及库目录设定。
对对话框而言,调用方式有两种:模态调用和动态创建。
两种方式都会遇到资源ID号冲突的问题,解决办法介绍如下:
1,模态调用
客户端使用doModal函数启动模态对话框,所以在导出类中重载该函数并修改如下:
INT_PTR CMIVPToolDlg::DoModal()
{
// TODO: Add your specialized code here and/or call the base class
HMODULE hDLL=GetModuleHandle(_T("MIVPToolbar.dll"));
HINSTANCE hEXE=AfxGetResourceHandle();
AfxSetResourceHandle((HINSTANCE)hDLL);
INT_PTR curp = CDialog::DoModal();
AfxSetResourceHandle(hEXE);
return curp;
}
其中MIVPToolbar.dll为导出类生成的动态链接库名字
这就解决了资源冲突问题。
2,动态创建
制作一个导出类的新的构造函数:
CMIVPToolDlg::CMIVPToolDlg(CWnd* pParent,UINT dType) // standard constructor
{
#ifndef _WIN32_WCE
EnableActiveAccessibility();
#endif
EnableAutomation();
HMODULE hDLL=GetModuleHandle(_T("MIVPToolbar.dll"));
HINSTANCE hEXE=AfxGetResourceHandle();
AfxSetResourceHandle((HINSTANCE)hDLL);
BOOL bCreated = CDialog::Create( IDD_FORMVIEW_TOOLDLG, pParent);
SUCCEEDED(bCreated);
AfxSetResourceHandle(hEXE);
}
在客户端动态创建方式非常简单,注意析构就可以了:
if( !m_toolbar1 )
{
m_toolbar1 = new CMIVPToolDlg(this,1);
}
m_toolbar1->ShowWindow(SW_SHOW);
3,通信
在扩展类中已经掌握了主类的指针,不成问题;同时,主类负责创建扩展类对象,拥有指针而且负责销毁对象。
4,宗旨
代码一样、思想更是一样。目的就是对面板进行封装,协作开发方便。比如,我要求某个哥们给我做个什么样的界面,提供的功能很单一,与其他模块的交互不多,那么就让他去起个exe工程,进行单独的编写和测试,然后我将他的工程通过这种方式做成dll库的方式供我主程序调用。
5, 讨论
这种方式的利弊还有待实践,有哥们说扩展MFC DLL仅适合做控件的扩展?