There are many places where ATL’s COM_MAP macros are documented, but I haven’t seen it plainly stated what they actually mean.
Simply put, BEGIN_COM_MAP implements _InternalQueryInterface. COM_INTERFACE_ENTRY indicates that your class supports the specified interface. END_COM_MAP finishes the _InternalQueryInterface implementation.
Note: A QueryInterface implementation which calls this _InternalQueryInterface method must either be hand-coded, or supplied by CComObject, CComAggObject, etc.
For example:
class MyClass :
public CComObjectRoot,
public ISomeInterface
{
public:
BEGIN_COM_MAP(MyClass)
COM_INTERFACE_ENTRY(ISomeInterface)
END_COM_MAP()
};
CComClass myInstance = new CComClass;
The COM_INTERFACE_ENTRY line indicates that MyClass implements ISomeInterface. If QueryInterface is called to requests an ISomeInterface pointer, the call will succeed. Without the COM_INTERFACE_ENTRY line, the QueryInterface call would fail.