2008-11-17 33 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