自己获取有无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
{
[default] interface 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即可
------------------------------------------------------------------------------------------
为对象添加连接点
ATL 教程说明了如何创建支持连接点的控件、如何添加事件,然后是如何实现连接点。ATL 用 IConnectionPointImpl 类实现连接点。
若要实现连接点,有两种选择:
- 通过为控件或对象添加连接点,实现自己的输出事件源。
- 重用其他类型库中定义的连接点接口。
在上述任何一种情况下,“实现连接点向导”都使用类型库来做这项工作。
为控件或对象添加连接点
- 在 .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。
- 在项目的 .idl 文件中,将调度接口作为
[default,source]
接口添加到对象的 coclass 中。同样,如果在创建控件时启用了连接点支持,则“ATL 控件向导”将创建 [default,source
] 项。若要手动添加此项,请添加下面以粗体显示的行:
coclass Buddy
{
[default] interface IBuddy;
[default,source] dispinterface DBuddyEvents;
};
有关示例请参见 Circ ATL 示例中的 .idl 文件。
- 使用“类视图”将方法和属性添加到事件接口。右击“类视图”中的类,指向快捷菜单上的“添加”,然后单击“添加连接点”。
- 在“实现连接点向导”的“源接口”列表框中,选择“项目的接口”。如果为控件选择接口并按“确定”,您将:
- 生成一个头文件,其中包含一个事件委托类,该类实现将为事件进行输出调用的代码。
- 将一项添加到连接点映射。
您还会看到计算机上的所有类型库的列表。仅当希望实现这些其他类型库之一中的完全相同的输出接口时,才应使用该类型库来定义连接点。
重用其他类型库中定义的连接点接口
- 在“类视图”中,右击实现 BEGIN_COM_MAP 宏的类,指向快捷菜单上的“添加”,然后单击“添加连接点”。
- 在“实现连接点向导”中,选择一个类型库和该类型库中的一个接口,然后单击“添加”。
- 编辑 .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
};
};