Table of contents
1.
Introduction
2.
Class Factory
3.
Aggregation Model
4.
How to Implement ATL Object? 
4.1.
Steps to Implement an ATL simple object to your ATL COM project
5.
Supporting IDispatch and IErrorInfo, IDispEventImpl in ATL
5.1.
Supporting IDispatch and IErrorInfo
5.2.
Supporting IDispEventImpl
6.
Changing the default class factory and aggregation model in ATL
6.1.
DECLARE_CLASSFACTORY
6.2.
DECLARE_AGGREGATABLE 
7.
Aggregation and Class Factory Macros
7.1.
DECLARE_AGGREGATABLE
7.2.
DECLARE_CLASSFACTORY
7.3.
DECLARE_CLASSFACTORY_EX
7.4.
DECLARE_CLASSFACTORY2
7.5.
DECLARE_CLASSFACTORY_AUTO_THREAD
7.6.
DECLARE_CLASSFACTORY_SINGLETON
7.7.
DECLARE_GET_CONTROLLING_UNKNOWN
7.8.
DECLARE_NOT_AGGREGATABLE
7.9.
DECLARE_PROTECT_FINAL_CONSTRUCT
7.10.
DECLARE_VIEW_STATUS
7.11.
DECLARE_ONLY_AGGREGATABLE
7.12.
DECLARE_POLY_AGGREGATABLE
8.
DECLARE_AGGREGATABLE
9.
DECLARE_CLASSFACTORY
10.
How to Implement a dual interface?
11.
ATL Multiple dual interfaces
12.
Frequently Asked Questions
12.1.
What Is the ATL Control-Hosting API?
12.2.
What is the class description of CWindow?
12.3.
What is the process?
13.
Conclusion
Last Updated: Aug 13, 2025

Changing the default class factory and aggregation model in ATL

Author Nilesh Kumar
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

The ActiveTemplateLibrary (ATL), a collection of template-based C++ classes that make it easier to program Component Object Model (COM) objects, is described in the ATL Reference. For generating and consuming software components on Windows, COM is a binary specification. To fully benefit from ATL, a working knowledge of COM is strongly advised to fully benefit from ATL. In this article, we will learn about Changing the default class factory and aggregation model in ATL.

 

Changing the default class factory and aggregation model in ATL

Class Factory

Class Factory is a method or function that, depending on some condition identified by input parameters or the context of the entire system, creates or picks a class and returns it. When the kind of object needed can't be identified until runtime, this is necessary. When classes are objects in the chosen language, like Python, implementation can be done directly.

 

A similar outcome can frequently be obtained by imitating "virtual constructors," where you call a base-class function Object() but get back an instance of another derived class. This is useful in languages like C++ where classes are not objects that can be passed around and handled. This is because the main purpose of any class is to create instances of itself. Because constructors can't actually be virtual, this needs to be emulated.

Aggregation Model

There are situations when the implementor of an object wants to utilize the features provided by another prebuilt object. It also wants this second object to look like a natural extension of the first. Both of these objectives are accomplished by COM through containment and aggregation.

Aggregation refers to the formation of the contained (inner) object by the containing (outer) object and the outer object's exposure to the inner object's interfaces. An object can decide whether or not it wants to be aggregated. If it is, then for aggregation to function effectively, it must adhere to specific constraints.

How to Implement ATL Object? 

Your project must have been completed as an ATL application or an MFC program with ATL support if you want to implement an ATL (Active Template Library) object. You can incorporate ATL support for an MFC program by adding an ATL object or using the ATL Project Wizard to create an ATL application.

You can specify COM interfaces when you first build your new ATL object. Later on, you can add them by using the Implement Interface command from the Class View shortcut menu.

Steps to Implement an ATL simple object to your ATL COM project

  1. Right-click the project name you wish to add the ATL simple object to in Solution Explorer or Class View.
  2. Select Add from the shortcut menu, then select Add Class.
  3. Click ATL Simple Object in the Templates pane of the Add Class dialogue box, and then click Open to bring up the ATL Simple Object Wizard.
  4. On the Options page of the ATL Simple Object wizard, specify additional project options.
  5. To add the object to your project, click Finish.

Supporting IDispatch and IErrorInfo, IDispEventImpl in ATL

Supporting IDispatch and IErrorInfo

Use the template class IDispatchImpl to provide a default implementation of the IDispatch Interface portion of any dual interfaces on your object.

Your object must support the ISupportErrorInfo Interface interface if it uses the IErrorInfo interface to communicate errors to the client. If your object only has one interface that creates errors, the template class ISupportErrorInfoImpl offers a simple implementation method.

Supporting IDispEventImpl

Your ATL class can enable connection point sinks using the template class IDispEventImpl. Using a connection point sink, your class can respond to events sent by COM objects that are external to it. The event sink map from your class is used to map this connection point sinks.

Changing the default class factory and aggregation model in ATL

The default class factory and aggregation model for your object are defined by ATL using CComCoClass. CComCoClass specifies the two macros listed below:

DECLARE_CLASSFACTORY

DECLARE_CLASSFACTORY determines that the class factory is CComClassFactory.

DECLARE_AGGREGATABLE 

DECLARE_AGGREGATABLE is a statement stating that your object can be aggregated.

 

Two more macros define a class factory:

  • DECLARE_CLASSFACTORY_AUTO_THREAD 
  • DECLARE_CLASSFACTORY_SINGLETON

ATL also uses the typedef approach to implementing a default behavior. In the  DECLARE_AGGREGATABLE macro, for instance, a type called _CreatorClass is defined using typedef and then used as a reference throughout ATL. It should be noted that if a typedef in a derived class has the same name as the typedef in the base class, ATL will use your declaration and override the default behavior.

 

Aggregation and Class Factory Macros

These macros offer techniques to declare class factories and regulate aggregation.

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

Proclaims CComClassFactory2 to be the class factory.

DECLARE_CLASSFACTORY_AUTO_THREAD

Proclaims CComClassFactoryAutoThread to be the class factory.

DECLARE_CLASSFACTORY_SINGLETON

Proclaims CComClassFactorySingleton to be the class factory.

DECLARE_GET_CONTROLLING_UNKNOWN

Proclaims a virtual GetControllingUnknown function.

DECLARE_NOT_AGGREGATABLE

Proclaims that your object cannot be aggregated.

DECLARE_PROTECT_FINAL_CONSTRUCT

Protects the outer object from deletion while constructing an inner object.

DECLARE_VIEW_STATUS

Specifies the VIEWSTATUS flags to the container.

DECLARE_ONLY_AGGREGATABLE

Proclaims that your object must be aggregated.

DECLARE_POLY_AGGREGATABLE

Checks the value of the outer unknown and Proclaims your object is aggregatable or not aggregatable, as appropriate.

 

DECLARE_AGGREGATABLE

Indicates that your item is aggregate-able.

In c++, we can use

DECLARE_AGGREGATABLE( x ).

This macro is part of CComCoClass and specifies the default aggregate model. Use the DECLARE_NOT_AGGREGATABLE  or DECLARE_ONLY_AGGREGATABLE  macros in your class declaration to override this default.

Example

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

DECLARE_CLASSFACTORY

Declares that the class factory is CComClassFactory.

In c++, we can use

DECLARE_CLASSFACTORY()

CComCoClass uses this macro to declare the object's default class factory.

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.
}

How to Implement a dual interface?

The IDispatchImpl class, which offers a default implementation of the IDispatch methods of a dual interface, can be used to implement a dual interface.IDispatch can be implemented by ActiveX or OLE objects for use by ActiveX clients like Visual Basic. Through the use of IDispatch::GetIDsOfNames and IDispatch::Invoke, the object's attributes and methods can be accessed.

To implement this class:

  • Create a type library and define your dual interface.
  • Draw inspiration for your class from an IDispatchImpl specialization (pass information about the interface and type library as the template arguments).
  • To expose the dual interface through QueryInterface, add an entry (or entries) to the COM map.
  • In your class, implement the vtable portion of the interface.
  • Make sure your objects can access the type library holding the interface definition at runtime.

ATL Multiple dual interfaces

You could want to combine the benefits of multiple inheritances with the advantages of a dual interface (that is, the adaptability of both vtable and late binding, making the class available to scripting languages and C++).

It is not advisable to expose many dual interfaces on a single COM object, even though it is feasible. There can only be one IDispatch interface exposed if numerous dual interfaces exist. The methods were available to ensure this comes with drawbacks like function loss or more sophisticated code. The developer adopting this strategy should carefully balance the benefits and drawbacks.

Frequently Asked Questions

What Is the ATL Control-Hosting API?

Any window can serve as an ActiveX control container thanks to the control-hosting API from ATL.

These routines are accessible by ATL80.dll and are available as source code so that they can be statically or dynamically linked to your project. The table below contains a list of the control-hosting operations.

What is the class description of CWindow?

Offers the GetDlgControl function, which, given the ID of its host window, returns an interface pointer on a control. Additionally, window management is often made simpler by the Windows API wrappers supplied by CWindow

What is the process?

Thread is a unit of execution in Windows.

The setting in which a thread runs is a process.

The threads, not the process, are scheduled by the scheduler.

Thread is regarded as a lightweight process in Unix versions.

Conclusion

In this article, we have extensively discussed This blog explains the details of SChanging the default class factory and aggregation model in ATL along with the implementation of ATL object, Supporting IDispatch and IErrorInfo, IDispEventImpl in ATL, dual interface, Multiple dual interfaces.

We hope this blog has helped you enhance your knowledge of The Elliptic Curve DSA. You can refer to our guided paths on the Coding Ninjas Studio platform to learn more about DSADBMSCompetitive ProgrammingPythonJavaJavaScript, etc. To practice and improve yourself in the interview, you can also check out Top 100 SQL problemsInterview experienceCoding interview questions, and the Ultimate guide path for interviews. Do upvote our blog to help other ninjas grow. Happy Coding!!

 

Live masterclass