List the core ATL classes and understand what they do.
Core ATL Classes
Most ATL classes are template based. ATL is shipped as a set of source files. To use ATL classes, we include ATL's *.h and *.cpp files
in our project. For basic ATL projects, the core files we use are atlbase.h and atlcom.h. ATL files can be found in the Visual C++ ATL\include and ATL\src directories. ATL provides built-in support for COM servers, class factories, and IUnknown. The general idea behind using ATL is to plug
your application classes into the ATL class hierarchy. You add one C++ class for each COM object in a server. Following are brief summaries of ATL core classes.
ATL class CComModule provides support for COM server functionality. It provides methods to register and unregister COM objects,
check server lock and references counts, and get class objects. All ATL-based programs have a global instance of CComModule (or a class derived from it) called _Module. Class CComObject provides QueryInterface, AddRef, and Release. These methods call into internal methods in CComObjectRoot. Class CComObjectRoot (and its base class, CComObjectRootBase) provides an internal data-driven implementation of IUnknown, called from QueryInterface, AddRef, and Release in CComObject.
Class CComCoClass provides a data-driven implementation of IClassFactory.
An interesting feature of ATL is that your application classes are not the most derived classes.
An instance of CComObject derives from your class.
CComObject: How ATL creates COM objects
CComObject is the most-derived class; it uses our COM implementation class as a base class. CComObject is defined as a template that takes the name of our COM implementation class as a parameter. Following is a partial listing of CComObject from file atlcom.h:
template <class Base>
class CComObject : public Base
{
public:
...
STDMETHOD_(ULONG, AddRef)(){...}
STDMETHOD_(ULONG, Release)(){...}
...
STDMETHOD(QueryInterface)
(REFIID iid, void ** ppvObject)
{...}
...
};
ATL uses internal creator classes to create COM object classes (i.e., ComCreator and ComCreator2 in atlcom.h). These classes call another internal creator method. This function creates an instance of our COM object by calling new CComObject(). For CPhBookObj, this call is new CComObject<CPhBookObj>().
ATL uses Multiple Inheritance | CComObjectRoot and CComCoClass
Your class derives CComObjectRoot and CComCoClass.
ATL uses multiple inheritance and your COM implementation class multiply inherits from CComObjectRootEx and CComCoClass.
For example, following is the declaration of CPhBookObj:.
class CPhBookObj :
...,
public CComObjectRoot,
public CComCoClass<CPhBook,&CLSID_PhBook>
{ ... };
As stated above, CComObjectRoot provides an internal implementation of IUnknown. ATL's class hierarchy supports single and multithreaded COM objects. CComObjectRoot is actually a typedef of class CComObjectRootEx, a template-based class that takes a thread model class as its parameter. CComObjectRoot defines a version of CComObjectRootEx that uses the default threading model. CComCoClass is also a template-based class. It provides a data-driven implementation of IClassFactory. As template parameters, it takes the name of the C++ class that implements a COM object and the CLSID of the COM object. Using this information, its implementation of CreateInstance can instantiate an instance of our C++ class.
Implementing COM Object PhBookObj in C++ class
Assume we are implementing COM object PhBookObj in C++ class CPhBookObj.
The following diagram depicts how CPhBookObj fits into the ATL class hierarchy.
Normally, we do not manually code required in-process server functions (for example, DllGetClassObject) or our COM object implementation classes. Instead, we use the ATL COM AppWizard to generate a skeleton server and add our COM implementation classes using Visual C++ tools. This is the topic of the next lesson.