IDispatchImplEx - 用于多接口分派的模板类






4.65/5 (9投票s)
用于实现 COM 对象的多接口分发的 C++ 模板类,基于 typeinfo 进行驱动,支持双接口和纯接口。
引言
模板类支持实现可脚本化的 COM 对象。可脚本化的对象必须实现 COM 接口 IDispatch,而 ATL 通过模板类 IDispatchImpl 支持此接口。IDispatchImpl 仅支持对单个双接口进行分发。如果您的 COM 对象通过聚合或继承直接实现多个双接口,则 IDispatchImpl 会将分发限制为其中一个接口。此外,如果您的类仅实现非双接口(派生自 IUnknown 的接口),则 IDispatchImpl 将根本不起作用。
提供了两个模板类来实现多接口分发
- IDispatchImplEx- 替换- ATL::IDispatchImpl,并基于 typeinfo 对多个双接口进行分发。如果继承自此模板的类实现多个双接口,则很有用。该模板支持对聚合 COM 对象进行分发。
- PureDispatchImpl- 用于实现纯- IDispatch接口,该接口基于 typeinfo 对一个或多个纯接口(派生自- IUnknown的接口)进行分发。
背景
ATL 包含模板类 IDispatchImpl,它基于 typeinfo 对单个双接口(派生自 IDispatch 的接口)进行分发。
实现双接口的多接口分发
要实现多个双接口的多接口分发,请使用 IDispatchImplEx 代替 IDispatchImpl
class ATL_NO_VTABLE CMyClass : 
     public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyModule>,
     public IDispatchImplEx<IMyInterface, &IID_IMyInterface, 
            &CLSID_MyClass, &LIBID_MyModule>,
如果接口定义在导入的类型库中,这仍然有效
class ATL_NO_VTABLE CMyClass : 
     public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyModule>,
     public IDispatchImplEx<IMyInterface, &IID_IMyInterface, 
            &CLSID_MyClass, &LIBID_ImportedLib>,
如果您的类支持事件,请在 IProvideClassInfo2Impl 模板中将 GUID_NULL 替换为您的事件接口的 IID。
实现对一个或多个纯接口的分发
要实现对一个或多个派生自 IUnknown 的纯接口的多接口分发,请使用 PureDispatchImpl。该实现向类添加单个 IDispatch 实现,并使用 typeinfo 对纯接口进行分发。但是,有一个要求,即接口必须提供 type info。
class ATL_NO_VTABLE CMyClassWithNoDuals : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClassWithNoDuals, &CLSID_MyClassWithNoDuals>,
    public PureDispatchImpl<&CLSID_MyClassWithNoDuals, &LIBID_MyLib>,
    public IPure1,
    public IPure2,
示例代码:
IDL 代码
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 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
脚本示例,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
历史
- 1.0 - 1998-05-07:初始版本。
- 2.0 - 1998-11-19:转换为 ATL 3.0。
- 3.0 - 1999-07-10:如果已实现,则使用 IProvideClassInfo。
- 4.0 - 2002-11-14:支持实现纯 IDispatch实现;添加了PureDispatchImpl。


