The "ATL simple object" wizard doesn't provide a way to specify that a new class is derived from an existing coclass and its interface. In Visual Studio 2008, how do I make a new ATL COM class derived from an existing one (i.e. Base
implements IBase
, and I want to make a new Derived
class derived from Base
that implements IDerived
, where IDerived
is derived from IBase
.)
Update: it sounds simple, but a wizard-generated ATL class has up to six base classes, a COM map and a connection point map. Which of these base classes and maps should be repeated in the derived class? If maps are repeated in the derived class should they contain the contents of the base class map or just the additional items? Does the order of base classes matter? What about FinalConstruct()
and FinalRelease()
? Should DECLARE_PROTECT_FINAL_CONSTRUCT
and DECLARE_REGISTRY_RESOURCEID
be repeated in the derived class?
Here's a sample base class that is empty except for all the boilerplate. Now what should the derived class look like?
class ATL_NO_VTABLE CBase :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CBase, &CLSID_Base>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CBase>,
public CProxy_IBaseEvents<CBase>,
public IDispatchImpl<IBase, &IID_IBase, &LIBID_ExampleLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CBase()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_Base)
BEGIN_COM_MAP(CBase)
COM_INTERFACE_ENTRY(IBase)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CBase)
CONNECTION_POINT_ENTRY(__uuidof(_IBaseEvents))
END_CONNECTION_POINT_MAP()
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
};
OBJECT_ENTRY_AUTO(__uuidof(Base), CBase)
Just a suggestion - if your COM object does not need to do anything special with COM related stuff then you can implement code such that the real logic that your base COM class does is encapsulated in another plain old C++ class say CBaseLogic.
CBaseLogic : IBase
class ATL_NO_VTABLE CBase :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CBase, &CLSID_Base>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CBase>,
public CProxy_IBaseEvents<CBase>,
public IDispatchImpl<IBase, &IID_IBase, &LIBID_ExampleLib
{
CBaseLogic m_LogicObj; /* Method calls are simply forwarded to this member */
};
CDerivedLogic : public CBaseLogic
class ATL_NO_VTABLE CDerived :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDerived, &CLSID_Base>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CDerived>,
public CProxy_IBaseEvents<CDerived>,
public IDispatchImpl<IBase, &IID_IBase, &LIBID_ExampleLib
{
CDerivedLogic m_LogicObj;
};
This achieves what you are trying to do with the added advantage of
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With