Internet Explorer 事件
IWebBrowser2 的属性和方法给了你确切的控制导航和用户接口的途径,但是如果你不能够检测到浏览器正在处理什么以及何时处理什么,你还是没有全面的控制它.因此,WebBrowser控件和Internet Explorer暴露出事件,通过此你可以必要时监视活动以及处理某些活动. 举例来说,假设你建立一个intranet应用程序, 你想限制用户用户访问某些web页.利用Internet Explorer的时间处理句柄,你可以指令应用程序在用户试图访问受限的URL时候取消导航完成。
事件 和 引出的接口
无论何时一个COM 对象需要客户应用程序一个事件发生了, COM 对象发送一个叫做事件的消息. 发送消息的处理过程会激发一个事件. 但如果事件没有任何监听者会如何? 事件每次都发生吗? 显然, 客户应用程序监听这些事件并控制COM对象.如果一个客户应用想接收来自COM 对象的事件,它"advises" 实际的COM 对象的.
一个COM 对象为了通客户通信, 对象自身必须支持一个或者多个外引接口.一个 COM 对象支持的外引接口是作为可连接对象引用. 要成为一个可连接对象,COM对象必须实现IConnectionPointContainer 接口。通过此接口,客户可认识到那些外引接口被服务器支持. 外引接口实际通过连接点由客户挂接入COM实现。实现外引接口的客户部分众所周知是通过事件接收槽(event sink)实现的.
单一的连接点由服务器支持每一个外引接口.每一个连接点能够操纵一种类型的外引接口且至少支持IConnectionPoint 接口. 图7-1 描述了可连接的对象和它的客户之间的关系.
Figure 7-1. Connectable object and its client.
每一个服务器必须实现2个接口以便实现客户可以接收事件—IConnectionPointContainer 和IConnectionPoint. 我们将先看看这些接口之后将检视实现事件的不同途径.
IConnectionPointContainer
每一个可连接对象实现了IConnectionPointContainer. 通过此接口, 试图接收事件的客户可找出关于可连接对象支持的不同的连接点. 通过调用QueryInterface using 客户可以获得服务器支持的任何接口的指针. (你可以使用任何接口指针调用QueryInterface, 因为全部 COM 接口继承自IUnknown.) 之后客户可以使用IConnectionPointContainer 接口的2个方法中的之一获取可连接点。 如表7-1, 获得可连接点
Table 7-1 Methods of the IConnectionPointContainer Interface
方法 | 描述 |
EnumConnectionPoints | 列举可连接对象支持的全部可连接对象 |
FindConnectionPoint | 让客户查询可连接对象关于它是否支持一个特殊接口。客户指定特殊的接口(可连接点)的接口标示 (IID) 。如果可连接对象支持此接口,返回IConnectionPoint 接口的指针。 |
IConnectionPoint
一旦客户知道哪个连接点可被连接对象服务器支持, 客户就可建立同可连接对象的连接。客户通知可连接对象将要在全部事件中接收那些事件.当客户不再需要接收来自可连接对象的事件,客户解除对对象的通知. 表7-2 展示了 IConnectionPoint 接口可被客户连接的. (大多数时候,你将连接到仅仅表中头两个)
Table 7-2 Methods of the IConnectionPoint Interface
方法 | 描述 |
Advise | 在客户和可连接对象的某一个可连接点间建立连接。 客户必须传递它的事件接收槽的IUnknown 接口。 事件接收槽必须实现IDispatch 接口以接收事件。 典型地,党课连接对象激发事件,可连接对象将调用 IDispatch 接口的Invoke 方法。 Advise方法返回一个 cookie ,当客户中断连接时候,调用Unadvise方法时候需要携带此cookie |
Unadvise | 中断连接. |
GetConnectionInterface | 返回由连接点管理的外发接口的IID . GetConnectionInterface 方法让客户将IConnectionPoint翻译为一个IID. |
GetConnectionPointContainer | 得到刻连接对象的IConnectionPointContainer 接口 |
EnumConnections | 枚举刻连接对象的当前可连接点. |
接收事件的途径
依靠开发工具你创建客户应用程序,你可以接收事件通过不同的途径. 显然, 在Vb中接收事件同在VC中接收事件相比是如此不同和容易.在 C++ 应用中,你可以用不同的技术,通过使用 ATL, MFC, 或者标准C++.
Visual Basic 中接收事件
Visual Basic是创建大多数类型应用的最轻松的工具, 所以我告诉你VB是处理事件最溶的工具时也不要惊奇. ATL 和 Visual Basic 示例我们同样的工作,但是ATL花费了我4个小时, 而 Visual Basic 例子仅仅只花20 分钟.别说我错了—我是ATL, 和 MFC, C++的忠实信徒, 尤其是你建立一个接口的时候.但是 Visual Basic当建立客户应用程序从类似IE这样的服务器接收事件时是伟大的工具.
OK,如何从Visual Basic 应用程序中接收事件?当宿主WebBrowser 控件,你不必做任何特别的事. Visual Basic 在form上为WebBrowser 控件接收事件.你所需要做的全部事情就是未你要接收的任何事件创建一个事件处理句柄.
你象创建其他事件句柄一样创建句柄 (例如Form_Load event). 从Procedure下拉列表框中选择你象控制的句柄, 在事件句柄中,加入任何你型在事件激发时执行的任何代码.
当自动化服务器时候接收事件, 例如在VB应用中的Internet Explorer,过程直截了当.首先设置对服务器的类型库的引用, 你可以访问Project/References 菜单.之后,采用WithEvents 关键字声明服务器对象的变量.举例, 如果你自动化Internet Explorer, 你将声明变量如下:
Dim WithEvents InternetExplorer1 As InternetExplorer |
下一步,采用new或者其他 关键字创建实例变量 ,如下::
Set InternetExplorer1 = CreateObject("InternetExplorer.Application.1") |
或者:
Set InternetExplorer1 = New InternetExplorer |
当你采用以上途径生成实例接收事件, Visual Basic 自动为你初始化和管理事件接收.你不必担心连接点问题,VB为你处理它们.
在你输入建立服务器的代码之后,你插入符合服务器事件的方法调用. 举例来说, 如果你想控制由IE激活的DownloadBegin event, 你应当声明类似如下的方法声明:
Private Sub InternetExplorer1_DownloadBegin() ' Insert your best Visual Basic code here. End Sub |
当你不再想接收来自服务器的事件,简单设置变量为Nothing:
Set InternetExplorer1 = Nothing |