COM组件的接口类添加Event

自己获取有无event的区别是,在向导中是否勾选:连接点。

红色为添加部分:

import "oaidl.idl";
import "ocidl.idl";
 
[
     object,
     uuid(C74F7F62-D315-4BF6-9422-9B80D68DB4FA),
     dual,
     nonextensible,
     helpstring("ISample 接口"),
     pointer_default(unique)
]
interface ISample : IDispatch{
};
[
     uuid(48D59498-7F95-4C2B-B3C3-B5DA3B407025),
     version(1.0),
     helpstring("EventSource 1.0 类型库")
]
library EventSourceLib
{
     importlib("stdole2.tlb");
     [
         uuid(87A653F3-F08F-4C1F-B091-5F8FAA894E3C),
         
     ]
     [
 uuid(def121c4-a87e-484c-bb84-48404e74e490)
helpstring("_ISampleEvents 的 UUID")
     ]
     dispinterface _ISampleEvents
     {
         properties:
         methods:
     };
     [
         uuid(6CC7B493-5F8E-4C08-B66D-D9E5FD2342E0),
         helpstring("Sample Class")
     ]
     coclass Sample
     {
         [defaultinterface ISample;
         [default, source] dispinterface _ISampleEvents;
     };
};
红色的就是本组件首选的事件接口。ISampleEvents接口目前没有提供方法和属性。
 
类的声明如下:
class ATL_NO_VTABLE CSample :
     public CComObjectRootEx,
     public CComCoClass,
     public ISupportErrorInfo,
     public IConnectionPointContainerImpl,
     public CProxy_ISampleEvents,
public IDispatchImpl/*wMajor =*/ 1, /*wMinor =*/ 0>
 
 
IConnectionPointContainerImpl和CProxy_ISampleEvents两个父类是关键。
 
BEGIN_COM_MAP(CSample)
     COM_INTERFACE_ENTRY(ISample)
     COM_INTERFACE_ENTRY(IDispatch)
     COM_INTERFACE_ENTRY(ISupportErrorInfo)
     COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()
 
COM MAP宏表明了对象支持IConnectionPointContainer接口
 
BEGIN_CONNECTION_POINT_MAP(CSample)
     CONNECTION_POINT_ENTRY(__uuidof(_ISampleEvents))
END_CONNECTION_POINT_MAP()
 
上面这个宏将_ISampleEvents接口的IID保存到连接点映射表中。


编译IDL即可

------------------------------------------------------------------------------------------

为对象添加连接点

Visual Studio .NET 2003

ATL 教程说明了如何创建支持连接点的控件、如何添加事件,然后是如何实现连接点。ATL 用 IConnectionPointImpl 类实现连接点。

若要实现连接点,有两种选择:

  • 通过为控件或对象添加连接点,实现自己的输出事件源。
  • 重用其他类型库中定义的连接点接口。

在上述任何一种情况下,“实现连接点向导”都使用类型库来做这项工作。

为控件或对象添加连接点

  1. 在 .idl 文件的库块中定义调度接口。当您用“ATL 控件向导”创建控件时,如果启用了连接点支持,则已经创建了调度接口。如果在创建控件时没有启用连接点支持,则必须将调度接口手动添加到 .idl 文件中。以下是一个调度接口的示例。输出接口不需要是调度接口,但是许多脚本语言(如 VBScript 和 JScript)都要求这一点,因此该示例使用了两个调度接口:
    library DProjLib
    {
       importlib("stdole32.tlb");
       importlib("stdole2.tlb");
       [
          uuid(57BC50F0-780B-11d1-8C44-0060083E866C),
          helpstring("Buddy Events")
       ]
    dispinterface DBuddyEvents
       properties:
       methods:
    };
    

    使用 uuidgen.exe 或 guidgen.exe 实用工具生成 GUID。

  2. 在项目的 .idl 文件中,将调度接口作为 [default,source] 接口添加到对象的 coclass 中。同样,如果在创建控件时启用了连接点支持,则“ATL 控件向导”将创建 [default,source] 项。若要手动添加此项,请添加下面以粗体显示的行:
    coclass Buddy
    {
       [default] interface IBuddy;
       [default,source] dispinterface DBuddyEvents;
    };
    

    有关示例请参见 Circ ATL 示例中的 .idl 文件。

  3. 使用“类视图”将方法和属性添加到事件接口。右击“类视图”中的类,指向快捷菜单上的“添加”,然后单击“添加连接点”。
  4. 在“实现连接点向导”的“源接口”列表框中,选择“项目的接口”。如果为控件选择接口并按“确定”,您将:
    • 生成一个头文件,其中包含一个事件委托类,该类实现将为事件进行输出调用的代码。
    • 将一项添加到连接点映射。

    您还会看到计算机上的所有类型库的列表。仅当希望实现这些其他类型库之一中的完全相同的输出接口时,才应使用该类型库来定义连接点。

重用其他类型库中定义的连接点接口

  1. 在“类视图”中,右击实现 BEGIN_COM_MAP 宏的类,指向快捷菜单上的“添加”,然后单击“添加连接点”。
  2. 在“实现连接点向导”中,选择一个类型库和该类型库中的一个接口,然后单击“添加”。
  3. 编辑 .idl 文件,执行下列任一操作:
    • 从 .idl 文件中复制其事件源正被使用的对象的调度接口。
    • 对该类型库使用 importlib 指令,如下所示。此示例摘自一个使用 Circ 控件中的连接点的 .idl 文件。
      [
         uuid(38BBFD91-7575-11D1-8C3C-0060083E866C),
         version(1.0),
         helpstring("16190 1.0 Type Library")
      ]
      library MY16190Lib
      {
         importlib("stdole32.tlb");
         importlib("stdole2.tlb");
         importlib("D:\\ATL25\\samples\\circ\\circ.tlb");   //**** add this line 
      
         [
            uuid(38BBFD9E-7575-11D1-8C3C-0060083E866C),
            helpstring("Atl16190Ctl Class")
         ]
         coclass Atl16190Ctl
         {
            [default] interface IAtl16190Ctl;
            [default,source] dispinterface _CircEvents;      //**** and this one
         };
      };

你可能感兴趣的:(C++)