In the course of figuring out how ATL manages interfaces and
QueryInterface, we'll look at some fifteen macros for composing COM classes. These
macros perform all sorts of interface-switching magic. The ordinary
COM_INTERFACE_ENTRY macro finds an interface's offset within the object. ATL
also includes macros to perform tear-offs and aggregation, two of the more
arcane methods of composing COM classes.
Before we examine each technique in detail, here's a quick summary of
the interface map macros we'll cover:
COM_INTERFACE_ENTRY Represents the normal interface
entry for multiple inheritance.
COM_INTERFACE_ENTRY_BREAK Enforces a breakpoint when
an interface is encountered.
COM_INTERFACE_ENTRY_NOINTERFACE Disables an interface
in a base class.
COM_INTERFACE_ENTRY_IID Resolves intermediate
interfaces (necessary for IDispatch and dual interfaces).
COM_INTERFACE_ENTRY2 Another means of resolving
intermediate interfaces (necessary for
IDispatch and dual interfaces).
COM_INTERFACE_ENTRY2_IID Yet another means of
resolving intermediate interfaces (again, necessary for
IDispatch and dual interfaces).
COM_INTERFACE_ENTRY_FUNC Maps an arbitrary function
to an IID.
COM_INTERFACE_ENTRY_FUNC_BLIND Maps an arbitrary
function to a position in the map.
COM_INTERFACE_ENTRY_CHAIN Performs
QueryInterface by delegating to a base class's map.
COM_INTERFACE_ENTRY_TEAR_OFF Creates a new tear-off.
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF Creates a
cached tear-off.
COM_INTERFACE_ENTRY_AGGREGATE Returns an interface
to an aggregate that was created in a constructor for a given interface.
COM_INTERFACE_ENTRY_AGGREGATE_BLIND Also returns
an interface to an aggregate that was created in a constructor for
a given interface.
COM_INTERFACE_ENTRY_AUTOAGGREGATE Returns an
interface to an aggregate that is created on demand.
COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND Also
returns an interface to an aggregate that is created on demand.
Throughout the rest of this chapter, we'll study each of these interface
map macros in detail.