2008-11-17 8 views
8

El asistente "Objeto simple ATL" no proporciona una forma de especificar que una nueva clase se deriva de un cocllass existente y su interfaz. En Visual Studio 2008, ¿cómo puedo hacer una nueva clase de ATL COM derivado de una existente (es decir, Base implementos IBase, y quiero hacer una nueva clase Derived derivado de Base que implementa IDerived, donde IDerived se deriva de IBase.)¿Cómo hacer una clase COM de ATL derivada de una clase base?

Actualización: suena simple, pero una clase ATL generada por asistente tiene hasta seis clases base, un mapa COM y un mapa de punto de conexión. ¿Cuál de estas clases base y mapas deberían repetirse en la clase derivada? Si los mapas se repiten en la clase derivada, ¿deberían contener el contenido del mapa de la clase base o solo los elementos adicionales? ¿Importa el orden de las clases base? ¿Qué hay de FinalConstruct() y FinalRelease()? ¿Deberían repetirse DECLARE_PROTECT_FINAL_CONSTRUCT y DECLARE_REGISTRY_RESOURCEID en la clase derivada?

Aquí hay una clase de base de muestra que está vacía, excepto en el texto repetido. Ahora, ¿cómo debería ser la clase derivada?

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) 

Respuesta

0

Edite el código que generan los asistentes. Si desea que un objeto se derive de interfaces adicionales, agregue estas clases base a la declaración de clase resultante.

+0

Una clase ATL generada por asistente tiene hasta seis clases base, un mapa COM y un mapa de punto de conexión. ¿Cuál de estas clases base y mapas se deben repetir en la clase derivada, y el orden de las clases base es importante? ¿Qué pasa con FinalConstruct() y FinalRelease()? – Qwertie

1

Solo una sugerencia: si su objeto COM no necesita hacer nada especial con cosas relacionadas con COM, entonces puede implementar código tal que la lógica real que su clase COM base está encapsulada en otra clase simple de C++ es 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; 
}; 

Con ello se consigue lo que usted está tratando de hacer con la ventaja añadida de

  1. mantiene su lógica verdadero programa separado de la infraestructura/envases (COM)
  2. Hace que la plataforma verdadera lógica independiente.
  3. mantenedor futuro no tiene por qué entender su COM inteligente hackear
  4. Mantiene la lógica del programa limpios y alejados de la sintaxis COM, lo que mejora la legibilidad
  5. Hace reutilización de la lógica real, más fácil en otras formas de envasado, por ejemplo como un archivo DLL C
+0

Acabo de ver los enlaces publicados anteriormente de vcfaq, que contienen implementaciones más sofisticadas de básicamente el mismo enfoque. Le sugiero que revise los anteriores y elija los que mejor se adapten a su situación – computinglife

+0

Este enfoque también significa que debe escribir manualmente un conjunto de funciones de reenvío. Terminé usando el enfoque descrito en http://vcfaq.mvps.org/com/8.htm pero no me gusta mucho. – Qwertie

Cuestiones relacionadas