步骤:
1.
创建新工程
(1)
New->Projects->MFC AppWizard
(DLL
)->
输入工程名->OK
,进入AppWizard
对话框;
(2)
为生成一个COM
进程内组件,选中Regular DLL using MFC DLL
。同时选中Automation
选项。Finish
。
经MFC AppWizard(dll)创建得到的工程只是一个COM工程框架,它本身并没有实现任何一个COM对象,添加COM对象类可以用ClassWizard向导工具完成。
我们可以看到,在经1、2步创建的工程中只包括一个应用程序类和三个标准的导出函数,这三个函数调用全局的辅助函数或类厂的静态成员函数完成相应的功能:
STDAPI
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllGetClassObject(rclsid, riid, ppv);
}
STDAPI
DllCanUnloadNow(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllCanUnloadNow();
}
// by exporting DllRegisterServer, you can use regsvr.exe
STDAPI
DllRegisterServer(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
COleObjectFactory::UpdateRegistryAll();
return S_OK;
}
应用程序类也很简单,只有构造函数和InitInstance成员函数,InitInstance只注册类厂对象。
另外,如果我们要创建一个进程外COM程序,则可选MFC AppWizard(exe)工程类型,并选择基于对话框的应用,同时选中Automation选项,在工程创建完成后,删除与对话框相关的代码,则可得到可以作为进程外COM程序的框架。
2.
利用ClassWizard
添加COM
对象类
(1)
选中菜单View->ClassWizard
,在弹出的对话框右上角单击菜单按钮Add Class
,并选中New
命令,弹出New Class
对话框;
(2)
在New Class
对话框的Base Class
下拉列表框中选中CCmdTarget
,以创建新的COM
对象类,并在Name
中输入新的类名CDictionaryObj
;OK
返回ClassWizard
对话框,在OK
,新类创建完了。
新建的类只是一个框架,只有基本的构造函数和析构函数。我们可以利用接口映射表和其他的一些宏使新类CDictionaryObj支持接口IDictionary和ISpellCheck。
3.
在新类CDictionaryObj
的定义中加入嵌套类
//IDictionary
BEGIN_INTERFACE_PART(Dictionary, IDictionary)
INIT_INTERFACE_PART(CDictionary, Dictionary)
STDMETHOD_(BOOL, Initialize)();
STDMETHOD_(BOOL, LoadLibrary)(LPOLESTR);
STDMETHOD_(BOOL, InsertWord)(LPOLESTR, LPOLESTR);
STDMETHOD_(void, DeleteWord)(LPOLESTR);
STDMETHOD_(BOOL, LookupWord)(LPOLESTR, LPOLESTR * );
STDMETHOD_(BOOL, RestoreLibrary)(LPOLESTR);
STDMETHOD_(void, FreeLibrary)();
END_INTERFACE_PART_STATIC(Dictionary)
//ISpellCheck
BEGIN_INTERFACE_PART(SpellCheck, ISpellCheck)
INIT_INTERFACE_PART(CDictionary, SpellCheck)
STDMETHOD_(BOOL, CheckWord)(LPOLESTR, LPOLESTR * );
END_INTERFACE_PART_STATIC(SpellCheck)
4.
加入接口映射表声明
DECLARE_INTERFACE_MAP()
5.
在CDictionaryObj
的实现文件中加入接口IID
和接口映射表的定义
extern "C" const IID IID_Dictionary =
{
0x54bf6568, 0x1007, 0x11d1,
{0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}
};
extern "C" const IID IID_SpellCheck =
{
0x54bf6569, 0x1007, 0x11d1,
{0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}
};
BEGIN_INTERFACE_MAP(CDictionaryObj, CCmdTarget)
INTERFACE_PART(CDictionaryObj, IID_Dictionary, Dictionary)
INTERFACE_PART(CDictionaryObj, IID_SpellCheck, SpellCheck)
END_INTERFACE_MAP()
6.
在CDictionaryObj
头文件的接口映射表声明之后加入下面的代码
DECLARE_OLECREATE(CDictionaryObj)
这是因为CDictionaryObj对象必须通过类厂才能被创建,所以我们通过上面的宏定义内嵌的类厂对象。
7.
相应的,在CDictionaryObj
类的实现文件中加入类厂对象的定义
IMPLEMENT_OLECREATE(CDictionaryObj, "Dictionary.Object",
0x54bf6567, 0x1007, 0x11d1, 0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00)
到这里,CDictionaryObj类已经提供了标准的COM支持,剩下的工作就是添加一些内部数据成员并实现嵌套类对象的成员函数。之后,编译链接便可以得到MFC版本的组件程序的DLL。
此外,这个工程还需要定义代码中所用到的接口IDictionary、ISpellCheck,还要实现接口映射表中所映射的函数。等等。