3.将上述 ForceRemove 后面的 GUID 替换为 BHO 的 CLSID(可在 HelloWorld.idl 中找到)。
切勿替换大括号。
4.保存文件,然后重新生成解决方案。(按 F6。)
Visual Studio 将自动注册该对象。
NoRemove 关键字表示取消注册 BHO 时将不删除该注册表项。除非您指定了此关键字,否则将删除空的注册表项。ForceRemove 关键字表示将删除该注册表项以及它所包含的任何值和子项。ForceRemove 还将导致在注册 BHO 后重新创建该注册表项(如果它已存在)。
既然此 BHO 专用于 Internet Explorer,那么我们指定 NoExplorer 值以防止 Windows Explorer 加载它。值和类型是什么都不重要,只要 NoExplorer 条目存在,Windows Explorer 就不会加载 BHO。
现在,您就可以从 Visual Studio 2005 中的“生成”菜单生成解决方案。
进行试用
为了进行快速测试,请在 SetSite 中设置一个断点,然后按 F5 启动调试程序。当出现“调试会话的可执行文件”对话框时,选择“默认的 Web 浏览器”,然后单击“确定”。如果 Internet Explorer 不是您的默认浏览器,则可以浏览查找可执行文件。
注意 在 Windows Vista 上,Internet Explorer 的“保护模式”功能将启动另一个进程,然后退出,这样会给调试带来一点难度。您可以通过以下两种方式轻松关闭当前会话的“保护模式”:从管理进程(例如 Visual Studio)启动浏览器,或者创建一个本地 HTML 文件并将其指定为 Internet Explorer 的命令行参数。
浏览器启动时,将加载 BHO 的 DLL。命中断点时,请注意是否设置了 pUnkSite 参数。再次按 F5 以继续加载主页。
关闭浏览器以验证是否通过 NULL 再次调用了 SetSite。
对事件做出响应
既然已经确认了 Internet Explorer 可以加载和运行 BHO,那就让我们在所举示例的基础上再深入一些,将 BHO 扩展到响应浏览器事件。在本部分中,我们介绍如何使用 ATL 为 DocumentComplete(在页面加载后显示一个消息框)实现一个事件处理程序。
为接到事件通知,BHO 建立一个与浏览器之间的连接点;为响应这些事件,它将实现 IDispatch。根据 DocumentComplete 的文档,该事件有两个参数:pDisp(IDispatch 的指针)和 pUrl。这些参数将作为事件的一部分传递给 IDispatch::Invoke;但手动析取这些事件参数并非一项简单的任务,并且易于出错。幸好 ATL 提供了一个默认实现,可以帮助简化这个事件处理逻辑。
HelloWorldBHO.h
首先通过包含 exdispid.h(为浏览器事件定义调度 ID)处理 HelloWorldBHO.h。
#include
接下来,从 IDispEventImpl 基类进行派生,该基类为处理事件提供了除 Invoke 之外的另一个简单安全的替代方法。IDispEventImpl 与事件汇映射配合工作,以将事件路由到相应的处理程序函数。我们明确说明,想要使用以下类定义(突出显示)处理由 DWebBrowserEvents2 接口定义的事件。
| 以下是引用片段: class ATL_NO_VTABLE CHelloWorldBHO : public CComObjectRootEx, public CComCoClass, public IObjectWithSiteImpl, public IDispatchImpl, public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1> |

