ATL Development   «Prev  Next»
Lesson 6 Examining ATL code
Objective Understand object maps and COM maps.

Examining ATL Code

Using Visual C++ tools to add class CPhBookObj and interfaces IReadPhBook and IManagePhBook adds code and new files into our project. Class View should now show entries for both interfaces and CPhBookObj.
Class View
Class View

Adding COM object PhBookObj to the project added an entry to the object map in PhBook.cpp, our server implementation file.

Inside Object Maps

The ATL COM AppWizard created an empty object map in file PhBook.cpp, our server implementation file, when we generated our project:

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

Adding class CPhBookObj to implement COM object PhBookObj added an object entry to the map:
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_PhBookObj, CPhBookObj)
END_OBJECT_MAP()

These macros generate a global array of structures of type _ATL_OBJMAP_ENTRY called ObjectMap. Each COM object implemented within the server plugs into the ATL framework via an _ATL_OBJMAP_ENTRY structure placed in the object map.
The _ATL_OBJMAP_ENTRY structure is used by the ATL framework code to create and access an object's class factory, create an instance of the C++ class (i.e., create an instance of the COM object), and get an object's CLSID.

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_PhBookObj, CPhBookObj)
END_OBJECT_MAP()

Each COM object within a server is bound into the ATL framework by adding it into the object map using the OBJECT_ENTRY macro. The OBJECT_ENTRY macro takes the object's CLSID and the name of the implementation class as parameters. This identifies a specific C++ class as implementing a COM object.
Each COM object implementation class contains a COM map:
class CPhBookObj : ... {
...
BEGIN_COM_MAP(CPhBookObj)
COM_INTERFACE_ENTRY(IReadPhBook)
COM_INTERFACE_ENTRY(IManagePhBook)
END_COM_MAP()
...
};

Each interface implemented by an object has a COM_INTERFACE_ENTRY macro.
COM maps add methods and data into the class used by the ATL framework to manage each interface.

inside-com-maps.php

Inside COM Maps

Macro BEGIN_COM_MAP adds methods to cache a COM interface pointer (i.e., the next request for the pointer will use the cached pointer), a method to get IUnknown (IUnknown is implemented in derived class CComObject), and an interface map within the class.
Macro COM_INTERFACE_ENTRY places an interface and its IID into the interface map.
Macro END_COM_MAP delimits the end of the COM map.
Note: The implementation of these macros is slightly different in ATL 2.1 in Visual C++ 5.0 and ATL 3.0 in Visual C++ 6. This difference is not visible to applications developers.
ATL-based COM classes use multiple inheritance. Each class inherits from each interface it implements. Each of these interface classes is really an interface specification, for example, a class with all pure virtual methods. We previously discussed CComObjectRoot and CComCoClass.
COM implementation class CPhBookObj is defined in header file PhBookObj.h as follows:
class CPhBookObj : 
 public IReadPhBook,
 public IManagePhBook,
 public CComObjectRoot,
 public CComCoClass <CPhBookObj,&CLSID_PhBookObj>
{
public:
 CPhBookObj() {}
BEGIN_COM_MAP(CPhBookObj)
 COM_INTERFACE_ENTRY(IReadPhBook)
 COM_INTERFACE_ENTRY(IManagePhBook)
END_COM_MAP()

DECLARE_REGISTRY_RESOURCEID(IDR_PhBookObj)

public:
};

Macro DECLARE_REGISTRY_RESOURCEID will be discussed in the next lesson.

ATL COM Objects - Quiz

Click the Quiz link below to check your understanding of ATL COM objects.
ATL Com Objects - Quiz