COM Map Macros
The latest version of this topic can be found at COM Map Macros.
These macros define COM interface maps.
BEGIN_COM_MAP | Marks the beginning of the COM interface map entries. |
COM_INTERFACE_ENTRY | Enters interfaces into the COM interface map. |
COM_INTERFACE_ENTRY2 | Use this macro to disambiguate two branches of inheritance. |
COM_INTERFACE_ENTRY_IID | Use this macro to enter the interface into the COM map and specify its IID. |
COM_INTERFACE_ENTRY2_IID | Same as COM_INTERFACE_ENTRY2, except you can specify a different IID. |
COM_INTERFACE_ENTRY_AGGREGATE | When the interface identified by iid is queried for, COM_INTERFACE_ENTRY_AGGREGATE forwards to punk . |
COM_INTERFACE_ENTRY_AGGREGATE_BLIND | Same as COM_INTERFACE_ENTRY_AGGREGATE, except that querying for any IID results in forwarding the query to punk . |
COM_INTERFACE_ENTRY_AUTOAGGREGATE | Same as COM_INTERFACE_ENTRY_AGGREGATE, except if punk is NULL, it automatically creates the aggregate described by the clsid . |
COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND | Same as COM_INTERFACE_ENTRY_AUTOAGGREGATE, except that querying for any IID results in forwarding the query to punk , and if punk is NULL, automatically creating the aggregate described by the clsid . |
COM_INTERFACE_ENTRY_BREAK | Causes your program to call DebugBreak when the specified interface is queried for. |
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF | Saves the interface-specific data for every instance. |
COM_INTERFACE_ENTRY_TEAR_OFF | Exposes your tear-off interfaces. |
COM_INTERFACE_ENTRY_CHAIN | Processes the COM map of the base class when the processing reaches this entry in the COM map. |
COM_INTERFACE_ENTRY_FUNC | A general mechanism for hooking into ATL's QueryInterface logic. |
COM_INTERFACE_ENTRY_FUNC_BLIND | Same as COM_INTERFACE_ENTRY_FUNC, except that querying for any IID results in a call to func . |
COM_INTERFACE_ENTRY_NOINTERFACE | Returns E_NOINTERFACE and terminates COM map processing when the specified interface is queried for. |
END_COM_MAP | Marks the end of the COM interface map entries. |
BEGIN_COM_MAP
The COM map is the mechanism that exposes interfaces on an object to a client through QueryInterface
.
BEGIN_COM_MAP
(x)
Parameters
x
[in] The name of the class object you are exposing interfaces on.
Remarks
CComObjectRootEx::InternalQueryInterface only returns pointers for interfaces in the COM map. Start your interface map with the BEGIN_COM_MAP
macro, add entries for each of your interfaces with the COM_INTERFACE_ENTRY macro or one of its variants, and complete the map with the END_COM_MAP macro.
Example
From the ATL BEEPER sample:
BEGIN_COM_MAP(CBeeper)
COM_INTERFACE_ENTRY(IBeeper)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_TEAR_OFF(IID_ISupportErrorInfo, CBeeper2)
END_COM_MAP()
COM_INTERFACE_ENTRY Macros
These macros enter an object's interfaces into its COM map so that they can be accessed by QueryInterface
. The order of entries in the COM map is the order interfaces will be checked for a matching IID during QueryInterface
.
COM_INTERFACE_ENTRY2
Use this macro to disambiguate two branches of inheritance.
COM_INTERFACE_ENTRY2
(x, x2)
Parameters
x
[in] The name of an interface you want to expose from your object.
x2
[in] The name of the inheritance branch from which x is exposed.
Remarks
For example, if you derive your class object from two dual interfaces, you expose IDispatch
using COM_INTERFACE_ENTRY2
since IDispatch
can be obtained from either one of the interfaces.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
class ATL_NO_VTABLE CEntry2Example :
public CEntry2ExampleBase, // CEntry2ExampleBase derives from IDispatch
public IDispatchImpl<IEntry2Example, &IID_IEntry2Example, &LIBID_NVC_ATL_WindowingLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public CComCoClass<CEntry2Example, &CLSID_Entry2Example>
{
public:
CEntry2Example()
{
}
BEGIN_COM_MAP(CEntry2Example)
COM_INTERFACE_ENTRY(IEntry2Example)
COM_INTERFACE_ENTRY2(IDispatch, IEntry2Example)
END_COM_MAP()
};
COM_INTERFACE_ENTRY_IID
Use this macro to enter the interface into the COM map and specify its IID.
COM_INTERFACE_ENTRY_IID
(iid, x)
Parameters
iid
[in] The GUID of the interface exposed.
x
[in] The name of the class whose vtable will be exposed as the interface identified by iid
.
Remarks
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(CExample)
COM_INTERFACE_ENTRY(IExample)
COM_INTERFACE_ENTRY_IID(IID_IDispatch, CExampleDispatch)
COM_INTERFACE_ENTRY(IExampleBase)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
COM_INTERFACE_ENTRY2_IID
Same as COM_INTERFACE_ENTRY2, except you can specify a different IID.
COM_INTERFACE_ENTRY2_IID
(iid, x, x2)
Parameters
iid
[in] The GUID you are specifying for the interface.
x
[in] The name of an interface that your class object derives from directly.
x2
[in] The name of a second interface that your class object derives from directly.
Remarks
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
COM_INTERFACE_ENTRY2
Use this macro to disambiguate two branches of inheritance.
COM_INTERFACE_ENTRY2
(x, x2)
Parameters
x
[in] The name of an interface you want to expose from your object.
x2
[in] The name of the inheritance branch from which x is exposed.
Remarks
For example, if you derive your class object from two dual interfaces, you expose IDispatch
using COM_INTERFACE_ENTRY2
since IDispatch
can be obtained from either one of the interfaces.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
class ATL_NO_VTABLE CEntry2Example :
public CEntry2ExampleBase, // CEntry2ExampleBase derives from IDispatch
public IDispatchImpl<IEntry2Example, &IID_IEntry2Example, &LIBID_NVC_ATL_WindowingLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public CComCoClass<CEntry2Example, &CLSID_Entry2Example>
{
public:
CEntry2Example()
{
}
BEGIN_COM_MAP(CEntry2Example)
COM_INTERFACE_ENTRY(IEntry2Example)
COM_INTERFACE_ENTRY2(IDispatch, IEntry2Example)
END_COM_MAP()
};
COM_INTERFACE_ENTRY_AGGREGATE
When the interface identified by iid
is queried for, COM_INTERFACE_ENTRY_AGGREGATE
forwards to punk
.
COM_INTERFACE_ENTRY_AGGREGATE
(iid, punk)
Parameters
iid
[in] The GUID of the interface queried for.
punk
[in] The name of an IUnknown pointer.
Remarks
The punk
parameter is assumed to point to the inner unknown of an aggregate or to NULL, in which case the entry is ignored. Typically, you would CoCreate the aggregate in FinalConstruct
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter1)
COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IAgg), m_punkAgg)
END_COM_MAP()
COM_INTERFACE_ENTRY_AGGREGATE_BLIND
Same as COM_INTERFACE_ENTRY_AGGREGATE, except that querying for any IID results in forwarding the query to punk
.
COM_INTERFACE_ENTRY_AGGREGATE_BLIND
(punk)
Parameters
punk
[in] The name of an IUnknown pointer.
Remarks
If the interface query fails, processing of the COM map continues.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter2)
COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_punkAggBlind)
END_COM_MAP()
COM_INTERFACE_ENTRY_AGGREGATE
When the interface identified by iid
is queried for, COM_INTERFACE_ENTRY_AGGREGATE
forwards to punk
.
COM_INTERFACE_ENTRY_AGGREGATE
(iid, punk)
Parameters
iid
[in] The GUID of the interface queried for.
punk
[in] The name of an IUnknown pointer.
Remarks
The punk
parameter is assumed to point to the inner unknown of an aggregate or to NULL, in which case the entry is ignored. Typically, you would CoCreate the aggregate in FinalConstruct
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter1)
COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IAgg), m_punkAgg)
END_COM_MAP()
COM_INTERFACE_ENTRY_AUTOAGGREGATE
Same as COM_INTERFACE_ENTRY_AGGREGATE, except if punk
is NULL, it automatically creates the aggregate described by the clsid
.
COM_INTERFACE_ENTRY_AUTOAGGREGATE
(iid, punk, clsid)
Parameters
iid
[in] The GUID of the interface queried for.
punk
[in] The name of an IUnknown pointer. Must be a member of the class containing the COM map.
clsid
[in] The identifier of the aggregate that will be created if punk
is NULL.
Remarks
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter3)
COM_INTERFACE_ENTRY_AUTOAGGREGATE(__uuidof(IAutoAgg), m_punkAutoAgg, CLSID_CAutoAgg)
END_COM_MAP()
COM_INTERFACE_ENTRY_AGGREGATE
When the interface identified by iid
is queried for, COM_INTERFACE_ENTRY_AGGREGATE
forwards to punk
.
COM_INTERFACE_ENTRY_AGGREGATE
(iid, punk)
Parameters
iid
[in] The GUID of the interface queried for.
punk
[in] The name of an IUnknown pointer.
Remarks
The punk
parameter is assumed to point to the inner unknown of an aggregate or to NULL, in which case the entry is ignored. Typically, you would CoCreate the aggregate in FinalConstruct
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter1)
COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IAgg), m_punkAgg)
END_COM_MAP()
COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND
Same as COM_INTERFACE_ENTRY_AUTOAGGREGATE, except that querying for any IID results in forwarding the query to punk
, and if punk
is NULL, automatically creating the aggregate described by the clsid
.
COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND
(punk, clsid)
Parameters
punk
[in] The name of an IUnknown pointer. Must be a member of the class containing the COM map.
clsid
[in] The identifier of the aggregate that will be created if punk
is NULL.
Remarks
If the interface query fails, processing of the COM map continues.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter4)
COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND(m_punkAutoAggB, CLSID_CAutoAggB)
END_COM_MAP()
COM_INTERFACE_ENTRY_AUTOAGGREGATE
Same as COM_INTERFACE_ENTRY_AGGREGATE, except if punk
is NULL, it automatically creates the aggregate described by the clsid
.
COM_INTERFACE_ENTRY_AUTOAGGREGATE
(iid, punk, clsid)
Parameters
iid
[in] The GUID of the interface queried for.
punk
[in] The name of an IUnknown pointer. Must be a member of the class containing the COM map.
clsid
[in] The identifier of the aggregate that will be created if punk
is NULL.
Remarks
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter3)
COM_INTERFACE_ENTRY_AUTOAGGREGATE(__uuidof(IAutoAgg), m_punkAutoAgg, CLSID_CAutoAgg)
END_COM_MAP()
COM_INTERFACE_ENTRY_BREAK
Causes your program to call DebugBreak when the specified interface is queried for.
COM_INTERFACE_ENTRY_BREAK
(x)
Parameters
x
[in] Text used to construct the interface identifier.
Remarks
The interface IID will be constructed by appending x to IID_
. For example, if x is IPersistStorage
, the IID will be IID_IPersistStorage
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF
Saves the interface-specific data for every instance.
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF
(iid, x, punk)
Parameters
iid
[in] The GUID of the tear-off interface.
x
[in] The name of the class implementing the interface.
punk
[in] The name of an IUnknown pointer. Must be a member of the class containing the COM map. Should be initialized to NULL in the class object's constructor.
Remarks
If the interface is not used, this lowers the overall instance size of your object.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(COuter)
COM_INTERFACE_ENTRY(IOuter)
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(IID_ITearOff, CTearOff, punkTearOff)
END_COM_MAP()
COM_INTERFACE_ENTRY_TEAR_OFF
Exposes your tear-off interfaces.
COM_INTERFACE_ENTRY_TEAR_OFF
(iid, x)
Parameters
iid
[in] The GUID of the tear-off interface.
x
[in] The name of the class implementing the interface.
Remarks
A tear-off interface is implemented as a separate object that is instantiated every time the interface it represents is queried for. Typically, you build your interface as a tear-off if the interface is rarely used, since this saves a vtable pointer in every instance of your main object. The tear-off is deleted when its reference count becomes zero. The class implementing the tear-off should be derived from CComTearOffObjectBase
and have its own COM map.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
Example
BEGIN_COM_MAP(CBeeper)
COM_INTERFACE_ENTRY(IBeeper)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_TEAR_OFF(IID_ISupportErrorInfo, CBeeper2)
END_COM_MAP()
COM_INTERFACE_ENTRY_CHAIN
Processes the COM map of the base class when the processing reaches this entry in the COM map.
COM_INTERFACE_ENTRY_CHAIN
(classname)
Parameters
classname
[in] A base class of the current object.
Remarks
For example, in the following code:
BEGIN_COM_MAP(COuterObject)
COM_INTERFACE_ENTRY2(IDispatch, IOuterObject)
COM_INTERFACE_ENTRY_CHAIN(CBase)
END_COM_MAP()
Note that the first entry in the COM map must be an interface on the object containing the COM map. Thus, you cannot start your COM map entries with COM_INTERFACE_ENTRY_CHAIN
, which causes the COM map of a different object to be searched at the point where COM_INTERFACE_ENTRY_CHAIN(COtherObject
) appears in your object's COM map. If you want to search the COM map of another object first, add an interface entry for IUnknown to your COM map, then chain the other object's COM map. For example:
BEGIN_COM_MAP(CThisObject)
COM_INTERFACE_ENTRY(IUnknown)
COM_INTERFACE_ENTRY_CHAIN(CBase)
END_COM_MAP()
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
COM_INTERFACE_ENTRY_FUNC
A general mechanism for hooking into ATL's QueryInterface
logic.
COM_INTERFACE_ENTRY_FUNC
(iid, dw, func)
Parameters
iid
[in] The GUID of the interface exposed.
dw
[in] A parameter passed through to the func
.
func
[in] The function pointer that will return iid
.
Remarks
If iid matches the IID of the interface queried for, then the function specified by func
is called. The declaration for the function should be:
HRESULT WINAPI func(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw);
When your function is called, pv
points to your class object. The riid
parameter refers to the interface being queried for, ppv
is the pointer to the location where the function should store the pointer to the interface, and dw
is the parameter you specified in the entry. The function should set * ppv
to NULL and return E_NOINTERFACE or S_FALSE if it chooses not to return an interface. With E_NOINTERFACE, COM map processing terminates. With S_FALSE, COM map processing continues, even though no interface pointer was returned. If the function returns an interface pointer, it should return S_OK
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
COM_INTERFACE_ENTRY_FUNC_BLIND
Same as COM_INTERFACE_ENTRY_FUNC, except that querying for any IID results in a call to func
.
COM_INTERFACE_ENTRY_FUNC_BLIND
(dw, func)
Parameters
dw
[in] A parameter passed through to the func
.
func
[in] The function that gets called when this entry in the COM map is processed.
Remarks
Any failure will cause processing to continue on the COM map. If the function returns an interface pointer, it should return S_OK
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
COM_INTERFACE_ENTRY_FUNC
A general mechanism for hooking into ATL's QueryInterface
logic.
COM_INTERFACE_ENTRY_FUNC
(iid, dw, func)
Parameters
iid
[in] The GUID of the interface exposed.
dw
[in] A parameter passed through to the func
.
func
[in] The function pointer that will return iid
.
Remarks
If iid matches the IID of the interface queried for, then the function specified by func
is called. The declaration for the function should be:
HRESULT WINAPI func(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw);
When your function is called, pv
points to your class object. The riid
parameter refers to the interface being queried for, ppv
is the pointer to the location where the function should store the pointer to the interface, and dw
is the parameter you specified in the entry. The function should set * ppv
to NULL and return E_NOINTERFACE or S_FALSE if it chooses not to return an interface. With E_NOINTERFACE, COM map processing terminates. With S_FALSE, COM map processing continues, even though no interface pointer was returned. If the function returns an interface pointer, it should return S_OK
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
COM_INTERFACE_ENTRY_NOINTERFACE
Returns E_NOINTERFACE and terminates COM map processing when the specified interface is queried for.
COM_INTERFACE_ENTRY_NOINTERFACE
(x)
Parameters
x
[in] Text used to construct the interface identifier.
Remarks
You can use this macro to prevent an interface from being used in a particular case. For example, you can insert this macro into your COM map right before COM_INTERFACE_ENTRY_AGGREGATE_BLIND
to prevent a query for the interface from being forwarded to the aggregate's inner unknown.
The interface IID will be constructed by appending x to IID_
. For example, if x is IPersistStorage
, the IID will be IID_IPersistStorage
.
See COM_INTERFACE_ENTRY Macros for remarks about COM map entries.
END_COM_MAP
Ends the definition of your COM interface map.
END_COM_MAP
()