聚合和类工厂宏
这些宏提供控制聚合和声明类工厂的方式。
宏 | 说明 |
---|---|
DECLARE_AGGREGATABLE | 声明对象可聚合(默认值)。 |
DECLARE_CLASSFACTORY | 将类工厂声明为 CComClassFactory,即 ATL 默认类工厂。 |
DECLARE_CLASSFACTORY_EX | 将类工厂对象声明为类工厂。 |
DECLARE_CLASSFACTORY2 | 将 CComClassFactory2 声明为类工厂。 |
DECLARE_CLASSFACTORY_AUTO_THREAD | 将 CComClassFactoryAutoThread 声明为类工厂。 |
DECLARE_CLASSFACTORY_SINGLETON | 将 CComClassFactorySingleton 声明为类工厂。 |
DECLARE_GET_CONTROLLING_UNKNOWN | 声明一个虚拟 GetControllingUnknown 函数。 |
DECLARE_NOT_AGGREGATABLE | 声明对象不可聚合。 |
DECLARE_ONLY_AGGREGATABLE | 声明对象必须聚合。 |
DECLARE_POLY_AGGREGATABLE | 检查外部未知成员的值,并相应地将对象声明为可聚合或不可聚合。 |
DECLARE_PROTECT_FINAL_CONSTRUCT | 防止在构造内部对象期间删除外部对象。 |
DECLARE_VIEW_STATUS | 指定容器的 VIEWSTATUS 标志。 |
要求
标头:atlcom.h
DECLARE_AGGREGATABLE
指定对象可聚合。
DECLARE_AGGREGATABLE( x )
参数
x
[in] 要定义为可聚合的类的名称。
备注
CComCoClass 包含此宏以指定默认聚合模型。 若要重写此默认值,请在类定义中指定 DECLARE_NOT_AGGREGATABLE 或 DECLARE_ONLY_AGGREGATABLE 宏。
示例
class ATL_NO_VTABLE CNoAggClass :
public CComObjectRoot,
public CComCoClass<CNoAggClass, &CLSID_NoAggClass>
{
public:
CNoAggClass()
{
}
DECLARE_NOT_AGGREGATABLE(CNoAggClass)
};
DECLARE_CLASSFACTORY
将 CComClassFactory 声明为类工厂。
DECLARE_CLASSFACTORY()
备注
CComCoClass 使用此宏为对象声明默认类工厂。
示例
class ATL_NO_VTABLE CMyClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyClass, &CLSID_MyClass>,
public IDispatchImpl<IMyClass, &IID_IMyClass, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispatchImpl<IMyDualInterface, &__uuidof(IMyDualInterface), &LIBID_NVC_ATL_COMLib, /* wMajor = */ 1, /* wMinor = */ 0>
{
public:
DECLARE_CLASSFACTORY()
// Remainder of class declaration omitted
CComClassFactory 类
此类实现 IClassFactory 接口。
class CComClassFactory : public IClassFactory,
public CComObjectRootEx<CComGlobalsThreadModel>
注解
CComClassFactory
实现 IClassFactory 接口,该接口包含用于创建特定 CLSID 对象的方法,以及锁定内存中的类工厂的方法,以便更快地创建新对象。 IClassFactory
必须为在系统注册表中注册的每个类以及为其分配 CLSID 的每个类实现。
ATL 对象通常通过从 CComCoClass 派生来获取类工厂。 此类包括宏 DECLARE_CLASSFACTORY,该宏将 CComClassFactory
声明为默认类工厂。 若要重写此默认值,请在类定义中指定一个 DECLARE_CLASSFACTORYXXX 宏。 例如,DECLARE_CLASSFACTORY_EX 宏使用类工厂的指定类:
class ATL_NO_VTABLE CMyCustomClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyCustomClass, &CLSID_MyCustomClass>,
public IDispatchImpl<IMyCustomClass, &IID_IMyCustomClass, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
DECLARE_CLASSFACTORY_EX(CMyClassFactory)
// Remainder of class declaration omitted.
上述类定义规定 CMyClassFactory
将用作对象的默认类工厂。 CMyClassFactory
必须派生自 CComClassFactory
和重写 CreateInstance
。
ATL 提供声明类工厂的其他三个宏:
DECLARE_CLASSFACTORY2 使用 CComClassFactory2,它通过许可证控制创建。
DECLARE_CLASSFACTORY_AUTO_THREAD 使用 CComClassFactoryAutoThread,后者在多个单元中创建对象。
DECLARE_CLASSFACTORY_SINGLETON 使用 CComClassFactorySingleton,该实例构造单个 CComObjectGlobal 对象。
DECLARE_CLASSFACTORY_EX
将 cf
声明为类工厂。
DECLARE_CLASSFACTORY_EX( cf )
参数
cf
[in] 实现类工厂对象的类的名称。
注解
cf 参数必须派生自 CComClassFactory 并重写 CreateInstance
方法。
CComCoClass 包含 DECLARE_CLASSFACTORY 宏,该宏将 CComClassFactory
指定为默认类工厂。 但是,可以通过在对象的类定义中包含 DECLARE_CLASSFACTORY_EX 宏来重写此默认值。
示例
class ATL_NO_VTABLE CMyCustomClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyCustomClass, &CLSID_MyCustomClass>,
public IDispatchImpl<IMyCustomClass, &IID_IMyCustomClass, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
DECLARE_CLASSFACTORY_EX(CMyClassFactory)
// Remainder of class declaration omitted.
DECLARE_CLASSFACTORY2
将 CComClassFactory2 声明为类工厂。
DECLARE_CLASSFACTORY2( lic )
参数
lic
[in] 实现 VerifyLicenseKey
、GetLicenseKey
和 IsLicenseValid
的类。
备注
CComCoClass 包含 DECLARE_CLASSFACTORY 宏,该宏将 CComClassFactory 指定为默认类工厂。 但是,可以通过在对象的类定义中包含 DECLARE_CLASSFACTORY2 宏来重写此默认值。
示例
class ATL_NO_VTABLE CMyClass2 :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyClass2, &CLSID_MyClass>,
public IDispatchImpl<IMyClass, &IID_IMyClass, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispatchImpl<IMyDualInterface, &__uuidof(IMyDualInterface), &LIBID_NVC_ATL_COMLib, /* wMajor = */ 1, /* wMinor = */ 0>
{
public:
DECLARE_CLASSFACTORY2(CMyLicense)
// Remainder of class declaration omitted
CComClassFactory2 类
此类实现 IClassFactory2 接口。
template <class license>
class CComClassFactory2 : public IClassFactory2,
public CComObjectRootEx<CComGlobalsThreadModel>,
public license
参数
license
实现以下静态函数的类:
static BOOL VerifyLicenseKey( BSTR bstr );
static BOOL GetLicenseKey( DWORD dwReserved, BSTR * pBstr );
static BOOL IsLicenseValid( );
备注
CComClassFactory2
实现 IClassFactory2 接口,该接口是 IClassFactory 的扩展。 IClassFactory2
通过许可证控制对象创建。 在许可计算机上执行的类工厂可以提供运行时许可证密钥。 此许可证密钥允许应用程序在不存在完整计算机许可证时实例化对象。
ATL 对象通常通过从 CComCoClass 派生来获取类工厂。 此类包括宏 DECLARE_CLASSFACTORY,该宏将 CComClassFactory 声明为默认类工厂。 若要使用 CComClassFactory2
,请在对象的类定义中指定 DECLARE_CLASSFACTORY2 宏。 例如:
class ATL_NO_VTABLE CMyClass2 :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyClass2, &CLSID_MyClass>,
public IDispatchImpl<IMyClass, &IID_IMyClass, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispatchImpl<IMyDualInterface, &__uuidof(IMyDualInterface), &LIBID_NVC_ATL_COMLib, /* wMajor = */ 1, /* wMinor = */ 0>
{
public:
DECLARE_CLASSFACTORY2(CMyLicense)
// Remainder of class declaration omitted
CMyLicense
,CComClassFactory2
的模板参数,必须实现静态函数 VerifyLicenseKey
、GetLicenseKey
和 IsLicenseValid
。 下面是一个简单类型定义的示例:
class CMyLicense
{
protected:
static BOOL VerifyLicenseKey(BSTR bstr)
{
USES_CONVERSION;
return !lstrcmp(OLE2T(bstr), _T("My run-time license key"));
}
static BOOL GetLicenseKey(DWORD /*dwReserved*/, BSTR* pBstr)
{
USES_CONVERSION;
*pBstr = SysAllocString( T2OLE(_T("My run-time license key")));
return TRUE;
}
static BOOL IsLicenseValid() { return TRUE; }
};
CComClassFactory2
派生自 CComClassFactory2Base
和 许可证。 而 CComClassFactory2Base
又派生自 IClassFactory2
和 CComObjectRootEx< CComGlobalsThreadModel >。
DECLARE_CLASSFACTORY_AUTO_THREAD
将 CComClassFactoryAutoThread 声明为类工厂。
DECLARE_CLASSFACTORY_AUTO_THREAD()
备注
CComCoClass 包含 DECLARE_CLASSFACTORY 宏,该宏将 CComClassFactory 指定为默认类工厂。 但是,可以通过在对象的类定义中包含 DECLARE_CLASSFACTORY_AUTO_THREAD 宏来重写此默认值。
在多个单元中(进程内和进程外服务器中)创建对象时,请将 DECLARE_CLASSFACTORY_AUTO_THREAD 添加到类。
示例
class ATL_NO_VTABLE CMyAutoClass :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CMyAutoClass, &CLSID_MyAutoClass>,
public IMyAutoClass
{
public:
DECLARE_CLASSFACTORY_AUTO_THREAD()
// Remainder of class declaration omitted.
CComClassFactoryAutoThread 类
此类实现 IClassFactory 接口,并允许在多个单元中创建对象。
重要
无法在 Windows 运行时中执行的应用程序中使用此类及其成员。
class CComClassFactoryAutoThread : public IClassFactory,
public CComObjectRootEx<CComGlobalsThreadModel>
备注
CComClassFactoryAutoThread
类似于 CComClassFactory,但允许在多个单元中创建对象。 若要利用此支持,请从 CComAutoThreadModule 派生 EXE 模块。
ATL 对象通常通过从 CComCoClass 派生来获取类工厂。 此类包括宏 DECLARE_CLASSFACTORY,该宏将 CComClassFactory 声明为默认类工厂。 若要使用 CComClassFactoryAutoThread
,请在对象的类定义中指定 DECLARE_CLASSFACTORY_AUTO_THREAD 宏。 例如:
class ATL_NO_VTABLE CMyAutoClass :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CMyAutoClass, &CLSID_MyAutoClass>,
public IMyAutoClass
{
public:
DECLARE_CLASSFACTORY_AUTO_THREAD()
// Remainder of class declaration omitted.
DECLARE_CLASSFACTORY_SINGLETON
将 CComClassFactorySingleton 声明为类工厂。
DECLARE_CLASSFACTORY_SINGLETON( obj )
参数
obj
[in] 类对象的名称。
注解
CComCoClass 包含 DECLARE_CLASSFACTORY 宏,该宏将 CComClassFactory 指定为默认类工厂。 但是,可以通过在对象的类定义中包含 DECLARE_CLASSFACTORY_SINGLETON 宏来重写此默认值。
示例
class ATL_NO_VTABLE CMySingletonClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMySingletonClass, &CLSID_MySingletonClass>,
public IMySingletonClass
{
public:
DECLARE_CLASSFACTORY_SINGLETON(CMySingletonClass)
// Remainder of class declaration omitted.
CComClassFactorySingleton 类
此类派生自 CComClassFactory,并使用 CComObjectGlobal 构造单个对象。
重要
无法在 Windows 运行时中执行的应用程序中使用此类及其成员。
template<class T>
class CComClassFactorySingleton : public CComClassFactory
参数
T
你的类。
CComClassFactorySingleton
派生自 CComClassFactory,并使用 CComObjectGlobal 构造单个对象。 每次调用 CreateInstance
方法只需查询此对象以获取接口指针。
备注
ATL 对象通常通过从 CComCoClass 派生来获取类工厂。 此类包括宏 DECLARE_CLASSFACTORY,该宏将 CComClassFactory
声明为默认类工厂。 若要使用 CComClassFactorySingleton
,请在对象的类定义中指定 DECLARE_CLASSFACTORY_AUTO_THREAD 宏。 例如:
class ATL_NO_VTABLE CMySingletonClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMySingletonClass, &CLSID_MySingletonClass>,
public IMySingletonClass
{
public:
DECLARE_CLASSFACTORY_SINGLETON(CMySingletonClass)
// Remainder of class declaration omitted.
DECLARE_GET_CONTROLLING_UNKNOWN
声明虚拟函数 GetControllingUnknown
。
DECLARE_GET_CONTROLLING_UNKNOWN()
备注
如果收到指出未定义 GetControllingUnknown
的编译器错误消息(例如,在 CComAggregateCreator
中),请将此宏添加到对象。
DECLARE_NOT_AGGREGATABLE
指定对象不可聚合。
DECLARE_NOT_AGGREGATABLE( x )
参数
x
[in] 要定义为不可聚合的类对象的名称。
备注
如果尝试聚合到对象,则 DECLARE_NOT_AGGREGATABLE 会导致 CreateInstance
返回错误 (CLASS_E_NOAGGREGATION)。
默认情况下,CComCoClass 包含 DECLARE_AGGREGATABLE 宏,该宏指定对象可聚合。 若要重写此默认行为,请在类定义中包含 DECLARE_NOT_AGGREGATABLE。
示例
class ATL_NO_VTABLE CNoAggClass :
public CComObjectRoot,
public CComCoClass<CNoAggClass, &CLSID_NoAggClass>
{
public:
CNoAggClass()
{
}
DECLARE_NOT_AGGREGATABLE(CNoAggClass)
};
DECLARE_ONLY_AGGREGATABLE
指定对象必须聚合。
DECLARE_ONLY_AGGREGATABLE( x )
参数
x
[in] 要定义为仅可聚合的类对象的名称。
注解
如果尝试调用 CoCreate
将对象指定为不可聚合的对象,则 DECLARE_ONLY_AGGREGATABLE 会导致错误 (E_FAIL)。
默认情况下,CComCoClass 包含 DECLARE_AGGREGATABLE 宏,该宏指定对象可聚合。 若要重写此默认行为,请在类定义中包含 DECLARE_ONLY_AGGREGATABLE。
示例
class ATL_NO_VTABLE COnlyAggClass :
public CComObjectRoot,
public CComCoClass<COnlyAggClass, &CLSID_OnlyAggClass>
{
public:
COnlyAggClass()
{
}
DECLARE_ONLY_AGGREGATABLE(COnlyAggClass)
};
DECLARE_POLY_AGGREGATABLE
指定在创建对象时创建 CComPolyObject < x > 的实例。
DECLARE_POLY_AGGREGATABLE( x )
参数
x
[in] 要定义为可聚合或不可聚合的类对象的名称。
备注
在创建过程中,将检查外部未知成员的值。 如果为 NULL,则 IUnknown
为非聚合对象实现。 如果外部未知不为 NULL,则会为聚合对象实现 IUnknown
。
使用 DECLARE_POLY_AGGREGATABLE 的优点是,可以避免在模块中同时使用 CComAggObject
和 CComObject
来处理聚合和非聚合事例。 单个 CComPolyObject
对象处理这两种情况。 这意味着模块中只有一个 vtable 副本和一个函数副本。 如果 vtable 很大,这可以大大减小模块大小。 但是,如果 vtable 较小,则使用 CComPolyObject
可能会导致模块大小略大,因为它未针对聚合或非聚合对象进行优化,如 CComAggObject
和 CComObject
所示。
如果使用 ATL 控件向导创建完整控件,则会在对象中自动声明 DECLARE_POLY_AGGREGATABLE 宏。
DECLARE_PROTECT_FINAL_CONSTRUCT
防止在(在执行 FinalConstruct 期间)内部聚合对象递增引用计数,然后将计数递减至 0 的情况下删除对象。
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_VIEW_STATUS
将此宏放入 ATL ActiveX 控件的控件类中可以指定容器的 VIEWSTATUS 标志。
DECLARE_VIEW_STATUS( statusFlags )
参数
statusFlags
[in] VIEWSTATUS 标志。 有关标志列表,请参阅 VIEWSTATUS。
示例
DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)