Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

IDispatchImplEx - Template classes for multi-interface dispatch

0.00/5 (No votes)
24 Jan 2009 2  
C++ template classes for implementing COM objects that perform typeinfo-driven dispatch on multiple interfaces, both dual and pure.

Introduction

Template classes support implementation of scriptable COM objects. Scriptable objects must implement the IDispatch COM interface, and this is supported by ATL through the IDispatchImpl template class. IDispatchImpl will only support dispatch on a single dual interface. If your COM object implements multiple dual interfaces, either directly through aggregation or through inheritance, IDispatchImpl restricts dispatch to one of the interfaces. In addition, if your class implements only non-dual (IUnknown-derived) interfaces, IDispatchImpl will not work at all.

Two template classes are provided that implement multi-interface dispatch:

  • IDispatchImplEx - Replaces ATL::IDispatchImpl and implements typeinfo-driven dispatch on multiple dual interfaces. Useful if the class inheriting from this template implements multiple dual interfaces. The template supports dispatch on aggregated COM objects.
  • PureDispatchImpl - Used to implement a pure IDispatch interface that does typeinfo-driven dispatch on one or more pure (IUnknown-derived) COM interfaces.

Background

ATL contains the template class IDispatchImpl that implements typeinfo-driven dispatch on a single dual (IDispatch-derived) COM interface.

Implementing multi-interface dispatch of dual interfaces

To implement multi-interface dispatch on multiple dual interfaces, use IDispatchImplEx instead of IDispatchImpl:

class ATL_NO_VTABLE CMyClass : 
     public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyModule>,
     public IDispatchImplEx<IMyInterface, &IID_IMyInterface, 
            &CLSID_MyClass, &LIBID_MyModule>,

If the interface is defined in an imported type library, this will still work:

class ATL_NO_VTABLE CMyClass : 
     public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyModule>,
     public IDispatchImplEx<IMyInterface, &IID_IMyInterface, 
            &CLSID_MyClass, &LIBID_ImportedLib>,

If your class supports events, replace GUID_NULL with the IID of your event interface in the IProvideClassInfo2Impl template.

Implementing dispatch on one or more pure interfaces

To implement multi-interface dispatch on one or more pure IUnknown-derived interfaces, use PureDispatchImpl. The implementation adds a single IDispatch implementation to the class, and uses typeinfo to dispatch against the pure interfaces. There is a requirement, however, that there is type info available for the interfaces.

class ATL_NO_VTABLE CMyClassWithNoDuals : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClassWithNoDuals, &CLSID_MyClassWithNoDuals>,
    public PureDispatchImpl<&CLSID_MyClassWithNoDuals, &LIBID_MyLib>,
    public IPure1,
    public IPure2,

Example code

IDL code

importlib("ImportedLib.tlb"); // Interface IC is defined here

//Dual interface definitions
interface IA : IDispatch
{
    HRESULT MethodOnIA();
};
interface IB : IDispatch
{
    HRESULT MethodOnIB();
};

// Pure (non-dual) interface definitions


interface IPure1 : IUnknown
{
    HRESULT DispMe();
};
interface IPure2 : IUnknown
{
    HRESULT DispMeAgain();
};
// Class definitions
// MyClass implements three dual interfaces,
// one defined in an imported type library
coclass MyClass
{
    [default] interface IA;
    interface IB;
    interface IC; // Defined in ImportedLib.tlb
};
// MyClassWithNoDuals implements three pure interfaces, 
// one of them defined in an imported type library 
coclass MyClassWithNoDuals
{
    [default] interface IPure1;
    interface IPure2;
    interface ID; // Defined in ImportedLib.tlb
};

C++ implementation

// Implementation of class with multiple dual interfaces
class ATL_NO_VTABLE CMyClass : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyLib>, 
    public IDispatchImplEx<IA, &IID_IA, &CLSID_MyClass, &LIBID_MyLib>,
    public IDispatchImplEx<IB, &IID_IB, &CLSID_MyClass, &LIBID_MyLib>,
    public IDispatchImplEx<IC, &IID_IC, &CLSID_MyClass, &LIBID_ImportedLib>,
    public CComCoClass<CMyClass, &CLSID_MyClass>,
    public ISupportErrorInfo
{
    ..standard ATL implementation
// Implementation of class with multiple pure interfaces
class ATL_NO_VTABLE CMyClassWithNoDuals : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClassWithNoDuals, &CLSID_MyClassWithNoDuals>,
    public PureDispatchImpl<&CLSID_MyClassWithNoDuals, &LIBID_MyLib>,
    public IPure1,
    public IPure2,
    public ID,
    public ISupportErrorInfo,
{
    ..standard ATL implementation
    BEGIN_COM_MAP(CMyClassWithNoDuals)
        COM_INTERFACE_ENTRY(IPure1)
        COM_INTERFACE_ENTRY(IPure2)
        COM_INTERFACE_ENTRY(ID)
        COM_INTERFACE_ENTRY(IDispatch)
        COM_INTERFACE_ENTRY(ISupportErrorInfo)
    END_COM_MAP()
    ...standard implementation

Scripting example, VB script client

Dim instanceOfMyClass
... got instanceOfMyClass from somewhere
' Regardless of which interface I got hold of, 
' I can script towards all methods on the class:
instanceOfMyClass.MethodOnIA
instanceOfMyClass.MethodOnIB
instanceOfMyClass.MethodOnIC


Dim instanceOfMyClassWithNoDuals
... got instanceOfMyClassWithNoDuals from somewhere
' Regardless of which interface I got hold of, 
' I can script towards all methods on the class:
instanceOfMyClassWithNoDuals.DispMe
instanceOfMyClassWithNoDuals.DispMeAgain
instanceOfMyClassWithNoDuals.MethodOnID

History

  • 1.0 - 1998-05-07: Initial version.
  • 2.0 - 1998-11-19: Converted to ATL 3.0.
  • 3.0 - 1999-07-10: Uses IProvideClassInfo, if implemented.
  • 4.0 - 2002-11-14: Support for implementation of a pure IDispatch implementation; added PureDispatchImpl.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here