9

"ATL シンプル オブジェクト" ウィザードでは、新しいクラスが既存のコクラスとそのインターフェイスから派生することを指定する方法が提供されません。Visual Studio 2008 で、既存のクラスから派生した新しい ATL COM クラスを作成するにはどうすればよいですか (つまり、 Baseimplementsであり、その implementsから派生した新しいクラスIBaseを作成したいのですが、ここで、は from から派生しています)。DerivedBaseIDerivedIDerivedIBase

更新: 簡単に聞こえますが、ウィザードで生成された ATL クラスには、最大 6 つの基本クラス、COM マップ、接続ポイント マップがあります。これらの基本クラスとマップのどれを派生クラスで繰り返す必要がありますか? マップが派生クラスで繰り返される場合、基本クラス マップのコンテンツを含める必要がありますか、それとも追加のアイテムだけを含める必要がありますか? 基本クラスの順序は重要ですか? FinalConstruct()とはどうFinalRelease()ですか?派生クラスで繰り返す必要がDECLARE_PROTECT_FINAL_CONSTRUCTありますか?DECLARE_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)
4

2 に答える 2

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 などの他の形式のパッケージングで、実際のロジックを簡単に再利用できます。
于 2008-12-17T16:07:31.810 に答える
0

ウィザードが生成するコードを編集します。オブジェクトを追加のインターフェイスから派生させたい場合は、これらの基本クラスを結果のクラス宣言に追加します。

于 2008-11-17T23:41:29.110 に答える