聚合和类工厂宏

这些宏提供控制聚合和声明类工厂的方式。

说明
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_AGGREGATABLEDECLARE_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_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] 实现 VerifyLicenseKeyGetLicenseKeyIsLicenseValid 的类。

备注

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

CMyLicenseCComClassFactory2 的模板参数,必须实现静态函数 VerifyLicenseKeyGetLicenseKeyIsLicenseValid。 下面是一个简单类型定义的示例:

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 的优点是,可以避免在模块中同时使用 CComAggObjectCComObject 来处理聚合和非聚合事例。 单个 CComPolyObject 对象处理这两种情况。 这意味着模块中只有一个 vtable 副本和一个函数副本。 如果 vtable 很大,这可以大大减小模块大小。 但是,如果 vtable 较小,则使用 CComPolyObject 可能会导致模块大小略大,因为它未针对聚合或非聚合对象进行优化,如 CComAggObjectCComObject 所示。

如果使用 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)

另请参阅