Click here to Skip to main content
15,867,949 members
Articles / Desktop Programming / ATL

IDispatchImplEx - Template classes for multi-interface dispatch

Rate me:
Please Sign up or sign in to vote.
4.65/5 (10 votes)
24 Jan 2009CPOL2 min read 36.3K   363   17   5
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:

C++
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:

C++
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.

C++
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

C++
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

C++
// 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

VB
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Norway Norway
ATL/COM, C#/.NET, IL, WCF

Comments and Discussions

 
QuestionGreat article. Pin
oleg6319-Oct-11 4:52
professionaloleg6319-Oct-11 4:52 
QuestionIn Case of Aggregation Pin
Sharjith16-Sep-09 5:52
professionalSharjith16-Sep-09 5:52 
AnswerRe: In Case of Aggregation Pin
Kjell Tangen16-Sep-09 6:30
Kjell Tangen16-Sep-09 6:30 
GeneralAwesome! Pin
yafan29-Jan-09 9:57
yafan29-Jan-09 9:57 
GeneralRe: Awesome! Pin
Kjell Tangen29-Jan-09 17:59
Kjell Tangen29-Jan-09 17:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.