通过Visual Studio 2005生成浏览器帮助程序对象(2)

http://developer.51cto.com  2007-02-01 15:52  Tony Schreiner/John Sudds  51CTO.com  我要评论(0)
  • 摘要:本文说明如何使用Visual Studio 2005创建一个简单的“浏览器帮助程序对象”(BHO),即实现IObjectWithSite接口并将其自身附加到Internet Explorer的一种“组件对象模型”(COM)对象。本文逐步说明了如何创建入门级BHO。
  • 标签:Visual Studio  2005  VS  浏览器

实现基本要素

“ATL 项目向导”提供了 SetSite 的默认实现。尽管 IObjectWithSite 的接口合约暗示了此方法可以在必要时被反复调用,但确切来说,Internet Explorer 只调用此方法两次;一次用于建立连接,另一次则是在浏览器退出时。特别要提的是,我们 BHO 中的 SetSite 实现将执行以下操作:

◆存储对站点的引用。在初始化期间,浏览器将 IUnknown 指针传递给顶层 WebBrowser 控件,然后 BHO 将对它的引用存储在一个专用成员变量中。
◆释放目前被占用的站点指针。Internet Explorer 传递 NULL 时,BHO 必须释放所有接口引用并且断开与浏览器的连接。

在处理 SetSite 的过程中,BHO 将根据需要执行其他初始化和非初始化。例如,您可以建立与浏览器的连接点以便接收浏览器事件。

HelloWorldBHO.h

在 Visual Studio 的“解决方案资源管理器”中双击打开 HelloWorldBHO.h。

首先,包含 shlguid.h。此文件定义了 IWebBrowser2 的接口标识符和稍后在项目中使用的事件。

#include // IID_IWebBrowser2、DIID_DWebBrowserEvents2 等。

接下来,在 CHelloWorldBHO 类的公共部分声明 SetSite。

STDMETHOD(SetSite)(IUnknown *pUnkSite);

STDMETHOD 宏是一个将方法标记为虚拟方法并且确保其具有适用于公共 COM 接口的调用约定的 ATL 约定。它有助于区分 COM 接口和该类中可能存在的其他公共方法。实现成员方法时同样也会使用 STDMETHODIMP 宏。

最后,在类声明的专用部分中声明某成员变量以存储浏览器站点。

private:
CComPtr m_spWebBrowser;
HelloWorldBHO.cpp
现在,切换到 HelloWorldBHO.cpp 并为 SetSite 插入以下代码。
STDMETHODIMP CHelloWorldBHO::SetSite(IUnknown* pUnkSite)
{
if (pUnkSite != NULL)
{
// 缓存指向 IWebBrowser2 的指针。
pUnkSite->QueryInterface(IID_IWebBrowser2, (void**)&m_spWebBrowser);
}
else
{
// 在此释放缓存的指针和其他资源。
m_spWebBrowser.Release();
}
// 返回基类实现
return IObjectWithSiteImpl::SetSite(pUnkSite);
}

初始化期间,浏览器将传递一个对其顶层 IWebBrowser2 接口(我们对其进行缓存处理)的引用。非初始化期间,浏览器将传递 NULL。为避免内存泄漏和循环引用计数,此时释放所有指针和资源非常重要。最后,我们调用基类实现以便它可以履行接口合约的其余部分。

HelloWorld.cpp

加载 DLL 后,系统将通过 DLL_PROCESS_ATTACH 通知调用 DllMain 函数。由于 Internet Explorer 大量使用多线程,因此,对 DllMain 的频繁的 DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH 通知会降低扩展和浏览器进程的整体性能。既然该 BHO 不需要线程级的跟踪,我们可以在 DLL_PROCESS_ATTACH 通知期间调用 DisableThreadLibraryCalls 以避免新线程通知的额外开销。

在 HelloWorld.cpp 中,如下编写 DllMain 函数的代码:

extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hInstance);
}
return _AtlModule.DllMain(dwReason, lpReserved);
}

注册 BHO

剩下要做的只是将 BHO 的 CLSID 添加到注册表中。此条目会将 DLL 标记为浏览器帮助程序对象,并使 Internet Explorer 在启动时加载 BHO。Visual Studio 可在生成项目时注册 CLSID。

注意 在 Windows Vista 上,Visual Studio 需要提升的特权才能与注册表进行交互。请确保通过在“开始”菜单中右键单击 Microsoft Visual Studio 2005 并选择“以管理员身份运行”来启动开发环境。

此 BHO 的 CLSID 可在 HelloWorld.idl 中找到(位于如下所示的代码块中):

importlib("stdole2.tlb");
[
uuid(D2F7E1E3-C9DC-4349-B72C-D5A708D6DD77),
helpstring("HelloWorldBHO Class")
]

请注意,此文件包含三个 GUID;我们需要的是用于类的 CLSID,而不是用于库的 CLSID 或接口 ID。

创建自行注册的 BHO:

1.从 Visual Studio 中的“解决方案资源管理器”打开 HelloWorld.rgs。

2.将以下代码添加到文件末尾:

HKLM {
NoRemove SOFTWARE {
NoRemove Microsoft {
NoRemove Windows {
NoRemove CurrentVersion {
NoRemove Explorer {
NoRemove '浏览器帮助程序对象' {
ForceRemove '{D2F7E1E3-C9DC-4349-B72C-D5A708D6DD77}' = s 'HelloWorldBHO' {
val 'NoExplorer' = d '1'
}
}
}
}
}
}
}
}

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 中的“生成”菜单生成解决方案。


共5页: 上一页 [1] 2 [3] [4] [5] 下一页
【内容导航】
 第 1 页:简介  第 2 页:实现基本要素
 第 3 页:进行试用  第 4 页:再一次试用
 第 5 页:最后的注意事项
浏览器的战国时代
体验Visual Studio 2008的魅力
Visual Studio 2005开发基础
VS.NET实用开发专题
SQL Server 2008/2005全解
 
 验证码: (点击刷新验证码)   匿名发表
  • Visual C++ 完全自学宝典

  • 作者:强锋科技,朱洪波
  • Visual C++ 6.0是微软公司为程序人员提供的Visual Studio 6.0工具套件中的重要组成部分。本书由浅入深地介绍使用Visual C++ 6.0..
Copyright©2005-2008 51CTO.COM 版权所有