9 Stimmen

Wie wird eine ATL COM-Klasse von einer Basisklasse abgeleitet?

Der Assistent für einfache ATL-Objekte bietet keine Möglichkeit, anzugeben, dass eine neue Klasse von einer vorhandenen Co-Klasse und ihrer Schnittstelle abgeleitet ist. Wie kann ich in Visual Studio 2008 eine neue ATL COM-Klasse erstellen, die von einer vorhandenen Klasse abgeleitet ist (d. h. Base implementiert IBase und ich möchte eine neue Derived Klasse abgeleitet von Base die Folgendes implementiert IDerived , donde IDerived wird abgeleitet von IBase .)

Update: Es klingt einfach, aber eine vom Assistenten erzeugte ATL-Klasse hat bis zu sechs Basisklassen, eine COM-Map und eine Connection Point Map. Welche dieser Basisklassen und Maps sollten in der abgeleiteten Klasse wiederholt werden? Wenn Maps in der abgeleiteten Klasse wiederholt werden, sollten sie dann den Inhalt der Basisklassen-Map oder nur die zusätzlichen Elemente enthalten? Spielt die Reihenfolge der Basisklassen eine Rolle? Was ist mit FinalConstruct() y FinalRelease() ? Sollte DECLARE_PROTECT_FINAL_CONSTRUCT y DECLARE_REGISTRY_RESOURCEID in der abgeleiteten Klasse wiederholt werden?

Hier ist eine Beispiel-Basisklasse, die abgesehen von allen Boilerplates leer ist. Wie sollte nun die abgeleitete Klasse aussehen?

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)

1voto

computinglife Punkte 4227

Nur ein Vorschlag - wenn Ihr COM-Objekt nichts Besonderes mit COM-bezogenem Zeug tun muss, dann können Sie Code so implementieren, dass die eigentliche Logik, die Ihre COM-Basisklasse tut, in einer anderen einfachen alten C++-Klasse gekapselt ist, sagen wir 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;
};

Damit wird erreicht, was Sie anstreben, mit dem zusätzlichen Vorteil, dass

  1. Hält die eigentliche Programmlogik von der Infrastruktur/Paketierung (COM) getrennt
  2. Macht die eigentliche Logik plattformunabhängig.
  3. Zukünftige Betreuer müssen Ihren cleveren COM-Hack nicht verstehen
  4. Hält Ihre Programmlogik sauber und von der COM-Syntax fern, was die Lesbarkeit verbessert
  5. Erleichtert die Wiederverwendung von echter Logik in anderen Verpackungsformen, z. B. als C-DLL

0voto

John Dibling Punkte 96619

Bearbeiten Sie den Code, den die Assistenten erzeugen. Wenn Sie möchten, dass ein Objekt von zusätzlichen Schnittstellen abgeleitet wird, fügen Sie diese Basisklassen zur resultierenden Klassendeklaration hinzu.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X