Aggregation and Class Factory Macros

 

The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.

The latest version of this topic can be found at Aggregation and Class Factory Macros.

These macros provide ways of controlling aggregation and of declaring class factories.

DECLARE_AGGREGATABLE Declares that your object can be aggregated (the default).
DECLARE_CLASSFACTORY Declares the class factory to be CComClassFactory, the ATL default class factory.
DECLARE_CLASSFACTORY_EX Declares your class factory object to be the class factory.
DECLARE_CLASSFACTORY2 Declares CComClassFactory2 to be the class factory.
DECLARE_CLASSFACTORY_AUTO_THREAD Declares CComClassFactoryAutoThread to be the class factory.
DECLARE_CLASSFACTORY_SINGLETON Declares CComClassFactorySingleton to be the class factory.
DECLARE_GET_CONTROLLING_UNKNOWN Declares a virtual GetControllingUnknown function.
DECLARE_NOT_AGGREGATABLE Declares that your object cannot be aggregated.
DECLARE_ONLY_AGGREGATABLE Declares that your object must be aggregated.
DECLARE_POLY_AGGREGATABLE Checks the value of the outer unknown and declares your object aggregatable or not aggregatable, as appropriate.
DECLARE_PROTECT_FINAL_CONSTRUCT Protects the outer object from deletion during construction of an inner object.
DECLARE_VIEW_STATUS Specifies the VIEWSTATUS flags to the container.

DECLARE_AGGREGATABLE

Specifies that your object can be aggregated.

DECLARE_AGGREGATABLE(Â
    x Â)

Parameters

x
[in] The name of the class you are defining as aggregatable.

Remarks

CComCoClass contains this macro to specify the default aggregation model. To override this default, specify either the DECLARE_NOT_AGGREGATABLE or DECLARE_ONLY_AGGREGATABLE macro in your class definition.

Example

class ATL_NO_VTABLE CNoAggClass :
   public CComObjectRoot,
   public CComCoClass<CNoAggClass, &CLSID_NoAggClass>
{
public:
   CNoAggClass()
   {
   }

   DECLARE_NOT_AGGREGATABLE(CNoAggClass)
};

DECLARE_CLASSFACTORY

Declares CComClassFactory to be the class factory.

DECLARE_CLASSFACTORY
()

Remarks

CComCoClass uses this macro to declare the default class factory for your object.

Example

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 Class

This class implements the IClassFactory interface.

class CComClassFactory : 
    public IClassFactory, 
    public CComObjectRootEx<CComGlobalsThreadModel>

Remarks

CComClassFactory implements the IClassFactory interface, which contains methods for creating an object of a particular CLSID, as well as locking the class factory in memory to allow new objects to be created more quickly. IClassFactory must be implemented for every class that you register in the system registry and to which you assign a CLSID.

ATL objects normally acquire a class factory by deriving from CComCoClass. This class includes the macro DECLARE_CLASSFACTORY, which declares CComClassFactory as the default class factory. To override this default, specify one of the DECLARE_CLASSFACTORYXXX macros in your class definition. For example, the DECLARE_CLASSFACTORY_EX macro uses the specified class for the class factory:

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.

The above class definition specifies that CMyClassFactory will be used as the object's default class factory. CMyClassFactory must derive from CComClassFactory and override CreateInstance.

ATL provides three other macros that declare a class factory:

DECLARE_CLASSFACTORY_EX

Declares cf to be the class factory.

DECLARE_CLASSFACTORY_EX(Â
    cf Â)

Parameters

cf
[in] The name of the class that implements your class factory object.

Remarks

The cf parameter must derive from CComClassFactory and override the CreateInstance method.

CComCoClass includes the DECLARE_CLASSFACTORY macro, which specifies CComClassFactory as the default class factory. However, by including the DECLARE_CLASSFACTORY_EX macro in your object's class definition, you override this default.

Example

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

Declares CComClassFactory2 to be the class factory.

DECLARE_CLASSFACTORY2(Â
    lic Â)

Parameters

lic
[in] A class that implements VerifyLicenseKey, GetLicenseKey, and IsLicenseValid.

Remarks

CComCoClass includes the DECLARE_CLASSFACTORY macro, which specifies CComClassFactory as the default class factory. However, by including the DECLARE_CLASSFACTORY2 macro in your object's class definition, you override this default.

Example

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 Class

This class implements the IClassFactory2 interface.

template <class license>
class  CComClassFactory2 : public IClassFactory2,
    public CComObjectRootEx<CComGlobalsThreadModel>,
    public license

Parameters

license
A class that implements the following static functions:

  • static BOOL VerifyLicenseKey( BSTR bstr );

  • static BOOL GetLicenseKey( DWORD dwReserved , BSTR* pBstr );

  • static BOOL IsLicenseValid( );

Remarks

CComClassFactory2 implements the IClassFactory2 interface, which is an extension of IClassFactory. IClassFactory2 controls object creation through a license. A class factory executing on a licensed machine can provide a run-time license key. This license key allows an application to instantiate objects when a full machine license does not exist.

ATL objects normally acquire a class factory by deriving from CComCoClass. This class includes the macro DECLARE_CLASSFACTORY, which declares CComClassFactory as the default class factory. To use CComClassFactory2, specify the DECLARE_CLASSFACTORY2 macro in your object's class definition. For example:

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, the template parameter to CComClassFactory2, must implement the static functions VerifyLicenseKey, GetLicenseKey, and IsLicenseValid. The following is an example of a simple license class:

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 derives from both CComClassFactory2Base and license. CComClassFactory2Base, in turn, derives from IClassFactory2 and CComObjectRootEx< CComGlobalsThreadModel >.

DECLARE_CLASSFACTORY_AUTO_THREAD

Declares CComClassFactoryAutoThread to be the class factory.

DECLARE_CLASSFACTORY_AUTO_THREAD
()

Remarks

CComCoClass includes the DECLARE_CLASSFACTORY macro, which specifies CComClassFactory as the default class factory. However, by including the DECLARE_CLASSFACTORY_AUTO_THREAD macro in your object's class definition, you override this default.

When you create objects in multiple apartments (in an out-of-proc server), add DECLARE_CLASSFACTORY_AUTO_THREAD to your class.

Example

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 Class

This class implements the IClassFactory interface, and allows objects to be created in multiple apartments.

Important

This class and its members cannot be used in applications that execute in the Windows Runtime.

class CComClassFactoryAutoThread : public IClassFactory,
public CComObjectRootEx<CComGlobalsThreadModel>

Remarks

CComClassFactoryAutoThread is similar to CComClassFactory, but allows objects to be created in multiple apartments. To take advantage of this support, derive your EXE module from CComAutoThreadModule.

ATL objects normally acquire a class factory by deriving from CComCoClass. This class includes the macro DECLARE_CLASSFACTORY, which declares CComClassFactory as the default class factory. To use CComClassFactoryAutoThread, specify the DECLARE_CLASSFACTORY_AUTO_THREAD macro in your object's class definition. For example:

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

Declares CComClassFactorySingleton to be the class factory.

DECLARE_CLASSFACTORY_SINGLETON(Â
    obj Â)

Parameters

obj
[in] The name of your class object.

Remarks

CComCoClass includes the DECLARE_CLASSFACTORY macro, which specifies CComClassFactory as the default class factory. However, by including the DECLARE_CLASSFACTORY_SINGLETON macro in your object's class definition, you override this default.

Example

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 Class

This class derives from CComClassFactory and uses CComObjectGlobal to construct a single object.

Important

This class and its members cannot be used in applications that execute in the Windows Runtime.

template<class T>
class CComClassFactorySingleton : public CComClassFactory

Parameters

T
Your class.

CComClassFactorySingleton derives from CComClassFactory and uses CComObjectGlobal to construct a single object. Each call to the CreateInstance method simply queries this object for an interface pointer.

Remarks

ATL objects normally acquire a class factory by deriving from CComCoClass. This class includes the macro DECLARE_CLASSFACTORY, which declares CComClassFactory as the default class factory. To use CComClassFactorySingleton, specify the DECLARE_CLASSFACTORY_SINGLETON macro in your object's class definition. For example:

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

Declares a virtual function GetControllingUnknown.

DECLARE_GET_CONTROLLING_UNKNOWN
()

Remarks

Add this macro to your object if you get the compiler error message that GetControllingUnknown is undefined (for example, in CComAggregateCreator).

DECLARE_NOT_AGGREGATABLE

Specifies that your object cannot be aggregated.

DECLARE_NOT_AGGREGATABLE(Â
    x Â)

Parameters

x
[in] The name of the class object you are defining as not aggregatable.

Remarks

DECLARE_NOT_AGGREGATABLE causes CreateInstance to return an error ( CLASS_E_NOAGGREGATION) if an attempt is made to aggregate onto your object.

By default, CComCoClass contains the DECLARE_AGGREGATABLE macro, which specifies that your object can be aggregated. To override this default behavior, include DECLARE_NOT_AGGREGATABLE in your class definition.

Example

class ATL_NO_VTABLE CNoAggClass :
   public CComObjectRoot,
   public CComCoClass<CNoAggClass, &CLSID_NoAggClass>
{
public:
   CNoAggClass()
   {
   }

   DECLARE_NOT_AGGREGATABLE(CNoAggClass)
};

DECLARE_ONLY_AGGREGATABLE

Specifies that your object must be aggregated.

DECLARE_ONLY_AGGREGATABLE(Â
    x Â)

Parameters

x
[in] The name of the class object you are defining as only aggregatable.

Remarks

DECLARE_ONLY_AGGREGATABLE causes an error ( E_FAIL) if an attempt is made to CoCreate your object as nonaggregated object.

By default, CComCoClass contains the DECLARE_AGGREGATABLE macro, which specifies that your object can be aggregated. To override this default behavior, include DECLARE_ONLY_AGGREGATABLE in your class definition.

Example

class ATL_NO_VTABLE COnlyAggClass :
   public CComObjectRoot,
   public CComCoClass<COnlyAggClass, &CLSID_OnlyAggClass>
{
public:
   COnlyAggClass()
   {
   }

   DECLARE_ONLY_AGGREGATABLE(COnlyAggClass)
};

DECLARE_POLY_AGGREGATABLE

Specifies that an instance of CComPolyObject < x > is created when your object is created.

DECLARE_POLY_AGGREGATABLE(Â
    x Â)

Parameters

x
[in] The name of the class object you are defining as aggregatable or not aggregatable.

Remarks

During creation, the value of the outer unknown is checked. If it is NULL, IUnknown is implemented for a nonaggregated object. If the outer unknown is not NULL, IUnknown is implemented for an aggregated object.

The advantage of using DECLARE_POLY_AGGREGATABLE is that you avoid having both CComAggObject and CComObject in your module to handle the aggregated and nonaggregated cases. A single CComPolyObject object handles both cases. This means only one copy of the vtable and one copy of the functions exist in your module. If your vtable is large, this can substantially decrease your module size. However, if your vtable is small, using CComPolyObject can result in a slightly larger module size because it is not optimized for an aggregated or nonaggregated object, as are CComAggObject and CComObject.

The DECLARE_POLY_AGGREGATABLE macro is automatically declared in your object if you use the ATL Control Wizard to create a full control.

DECLARE_PROTECT_FINAL_CONSTRUCT

Protects your object from being deleted if (during FinalConstruct) the internal aggregated object increments the reference count then decrements the count to 0.

DECLARE_PROTECT_FINAL_CONSTRUCT
()

DECLARE_VIEW_STATUS

Place this macro in an ATL ActiveX control's control class to specify the VIEWSTATUS flags to the container.

DECLARE_VIEW_STATUS(Â
    statusFlags Â)

Parameters

statusFlags
[in] The VIEWSTATUS flags. See VIEWSTATUS for a list of flags.

Example

   DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

See Also

Macros