1 类厂的作用
类厂也是组件,用于创建其他组件,通过类厂可以创建其它的组件,实际上类厂封装了创建组件的过程,使得创建组件变得标准化,ATL封装了组件的编写过程,
类厂封装了组件的创建。通过类厂机制,每添加一个组件a,就会在类厂组件中添加一个组件a的创建接口,所以以后创建组件的过程变成了:在DLL模块中获取指定组件
的类厂创建接口,利用类厂创建接口创建组件。
类厂的标准接口:IClassFactoryATL中使用CComCoClass完成类厂封装
2 类厂的实现
2.1 添加类厂的支持 CComCoClass例如
class CMath :public CComObjectRootEx<CComMultiThreadModel>,
public IMath,
public CComCoClass<CMath, &CLSID_Math>
2.2 在类中增加宏
DECLARE_REGISTRY_RESOURCE(0)
2.3 定义组件ID和组件对应关系的管理的变量
BEGIN_OBJECT_MAP(objectmap)
OBJECT_ENTRY(CLSID_Math, CMath)
END_OBJECT_MAP()
2.4 将管理的变量初始化到模块
_Module.Init(objectmap, NULL, NULL);
2.5 使用类厂创建组件
2.3.1 从Module获取CLISD指定组件的类厂接口
IClassFactory* piClassFactory
_Module.GetClassObject(clsid, IID_IclassFactory,
(LPVOID* &piClassFactory);
2.3.2 创建组件获取IUnknown接口
piClassFactory->CraeateInstance(IID_IUnknown, (LPVOID*)&piUnknown
3 代码说明
3.1CCOmClClass类在组件中添加类厂(CComClassFactory)和组件生成器(CComCreater)以及组件的创建函数
CreateInstance
3.2 在CComClassFactory当中实现了类厂接口的
CreateInstance函数,函数内会调用CComCoClass的创建函数
3.3 CComCoClass的创建函数中会调用CComCreater的函数创建
组件
代码示例
IDL文件
import "oaidl.idl";
import "ocidl.idl";
import "objidl.idl";
[
object,
uuid(CFF0849D-61E2-4ED1-9DC9-0E43E2FBDE25)
]
interface IMath :IUnknown
{
HRESULT Add(long nAdd1, long nAdd2, long* pnAdd) = 0;
HRESULT Sub(long nSub1, long nSub2, long* pnSub) = 0;
};
[
uuid(39B16755-783D-49B1-93E2-0FCA9F66CC2D)
]
coclass ComObj
{
interface IMath;
};
Math.h
#pragma once
//ATL库头文件
#include "atlbase.h"
#include "atlcom.h"
#include "comobj_h.h"
extern const CLSID CLSID_Math;
extern CComModule _Module;
class CMath :public CComObjectRootEx<CComMultiThreadModel>,
public IMath,
public CComCoClass<CMath, &CLSID_ComObj>
{
public:
CMath();
~CMath();
//添加注册表资源宏
DECLARE_REGISTRY_RESOURCE(0)
public:
//用于接口查询等相关信息的宏
BEGIN_COM_MAP(CMath)
COM_INTERFACE_ENTRY(IMath)
END_COM_MAP()
//IMath接口的函数
public:
STDMETHOD(Add)(long nAdd1, long nAdd2, long* pnAdd);
STDMETHOD(Sub)(long nSub1, long nSub2, long* pnSub);
};
Math.cpp
#include "stdafx.h"
#include "Math.h"
CComModule _Module;
CMath::CMath()
{
}
CMath::~CMath()
{
}
STDMETHODIMP CMath::Add(long nAdd1,
long nAdd2,
long* pnAdd)
{
*pnAdd = nAdd1 + nAdd2;
return S_OK;
}
STDMETHODIMP CMath::Sub(long nSub1,
long nSub2,
long* pnSub)
{
*pnSub = nSub1 - nSub2;
return S_OK;
}
组件创建函数
IUnknown* MyCreateInstance2(CLSID clsid)
{
//从Module获取CLISD指定组件的类厂接口
IClassFactory* piClassFactory = NULL;
_Module.GetClassObject(clsid, IID_IclassFactory,
(LPVOID* &piClassFactory);
//创建组件获取IUnknown接口
IUnknown *piUnknown = NULL;
piClassFactory->CraeateInstance(IID_IUnknown, (LPVOID*)&piUnknown);
return piUnknown;
}