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.