2008-11-17 32 views
8

“ATL简单对象”向导不提供指定从现有的coclass及其接口派生新类的方法。在Visual Studio 2008中,如何让我从一个现有的衍生一个新的ATL COM类(即Base工具IBase,我想打从Base实现IDerived,其中IDerivedIBase衍生派生的新Derived类)。如何制作一个从基类派生的ATL COM类?

更新:听起来很简单,但向导生成的ATL类最多有六个基类,一个COM映射和一个连接点映射。在派生类中应该重复哪些基类和映射?如果映射在派生类中重复,那么它们是否应包含基类映射的内容或仅包含其他项目?基类的顺序是否重要?那么FinalConstruct()FinalRelease()?应该在派生类中重复DECLARE_PROTECT_FINAL_CONSTRUCTDECLARE_REGISTRY_RESOURCEID

这是一个样例基类,除了所有的样板外都是空的。现在派生类应该是什么样子?

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) 

回答

0

编辑向导生成的代码。如果您希望从其他接口派生对象,请将这些基类添加到生成的类声明中。

+0

向导生成的ATL类最多有六个基类,一个COM映射和一个连接点映射。哪些基类和映射应该在派生类中重复,基类的顺序是否重要?那么FinalConstruct()和FinalRelease()呢? – Qwertie 2008-11-18 15:58:24

1

只是一个建议 - 如果你的COM对象并不需要做什么特别的事情与COM相关的东西,那么你可以执行的代码,使得你的基础COM类做实际的逻辑封装在另一个普通的老式C++类说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; 
}; 

这实现你试图用

  1. 额外的好处做保持您真正的程序逻辑从基础设施/包装(COM)
  2. 使独立的真正逻辑平台分开。
  3. 未来的维护者不需要理解你的聪明COM破解
  4. 保持您的程序逻辑干净,并从COM语法而去,提高可读性
  5. 使重新使用真正的逻辑其他形式的包装如更容易的为C DLL
+0

刚刚看到上面发布的vcfaq链接 - 它们包含基本上相同方法的更复杂的实现。我建议你回顾一下上面的内容,并选择最适合你的情况 – computinglife 2008-12-17 16:12:31