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
- Right-click the project name you wish to add the ATL simple object to in Solution Explorer or Class View.
- Select Add from the shortcut menu, then select Add Class.
- 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.
- On the Options page of the ATL Simple Object wizard, specify additional project options.
- 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 DSA, DBMS, Competitive Programming, Python, Java, JavaScript, etc. To practice and improve yourself in the interview, you can also check out Top 100 SQL problems, Interview experience, Coding interview questions, and the Ultimate guide path for interviews. Do upvote our blog to help other ninjas grow. Happy Coding!!
