Click here to Skip to main content
Click here to Skip to main content
Go to top

IDispatchImplEx - Template classes for multi-interface dispatch

, 24 Jan 2009
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

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

Comments and Discussions

 
QuestionGreat article. Pinmemberoleg6319-Oct-11 4:52 
QuestionIn Case of Aggregation PinmemberSharjith16-Sep-09 5:52 
AnswerRe: In Case of Aggregation PinmemberKjell Tangen16-Sep-09 6:30 
GeneralAwesome! Pinmemberyafan29-Jan-09 9:57 
GeneralRe: Awesome! PinmemberKjell Tangen29-Jan-09 17:59 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140922.1 | Last Updated 24 Jan 2009
Article Copyright 2009 by Kjell Tangen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid