BHO浏览器辅助对象.docx
- 文档编号:23966224
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:20
- 大小:65.97KB
BHO浏览器辅助对象.docx
《BHO浏览器辅助对象.docx》由会员分享,可在线阅读,更多相关《BHO浏览器辅助对象.docx(20页珍藏版)》请在冰豆网上搜索。
BHO浏览器辅助对象
浏览器辅助对象:
浏览器你想要的方式
116的165的额定帮助- 评价此主题
截至2011年12月,这个话题已被封存。
因此,它不再是积极维护。
有关详细信息,请参阅存档内容。
的信息,建议和指导当前版本的InternetExplorer,IE开发中心。
微软公司恐龙埃斯波西托
1999年1月
2004年4月9日安全更新:
请也看到安全注意事项:
编程和重复使用的浏览器,以了解更多有关解决浏览器的安全问题。
摘要:
介绍了如何使用的BHO可以自定义你的浏览器。
(16页)封面:
简介
方案定制
什么是浏览器辅助对象?
器辅助对象的生命周期
IObjectWithSite接口
编写一个浏览器辅助对象
检测是谁在呼叫
,接触web浏览器
从浏览器中获取事件
介绍
有时情况下,你需要更专业化程度较低版本的浏览器。
有时你解决这个问题,开发一个完全自定义模块内置的WebBrowser控件,完成与按钮,标签,和其他任何用户界面要求。
在这种情况下,你可以自由添加任何新的,非标准的功能,你想要的,浏览器。
但是你真正拥有的是一个新的,非标准的浏览器。
WebBrowser控件只是浏览器的分析引擎。
这意味着仍然存在一些为你做的UI相关的任务:
添加一个地址栏,工具栏,历史记录,状态栏,频道,和我的最爱,只是仅举几例。
所以,要创建一个自定义的浏览器有两种类型的代码写入转换成一个完整的浏览器,如MicrosoftInternetExplorerWebBrowser控件的代码,和代码,以实现新的功能,你希望它支持。
那岂不是很好,如果有自定义InternetExplorer,而不是一个简单的方法吗?
浏览器辅助对象(BHO)做到这一点。
方案定制
从历史的角度来看,第一种方式是通过子类化的自定义程序的行为。
通过这种方法,你可以改变一个给定的窗口程序处理的消息,并获得不同的行为。
虽然被认为是暴力破解的方法,因为受害者主要是不知道发生了什么,它已经很长一段时间的唯一选择。
的MicrosoftWin32API的到来,进程间子类化很沮丧,有点难以代码。
如果你是勇敢的,善良的,然而,指针从来没有害怕你,最重要的是,如果你习惯了生活在共生与全系统钩子,你甚至可以找到它太简单了。
但是,这并非总是如此。
尽管聪明的编程,这一点是每一个Win32进程都运行在自己的地址空间,打破进程边界是有点不正确的。
另一方面,有可能的情况下,要求你做到这一点的最好的意图。
更多的时候,客制化的设计允许程序本身可能是一个特定的功能。
在后一种情况下,知名的前缀磁盘区,额外的模块加载,初始化,然后让他们自由地做工作,他们的目的是为了做节目搜索。
这是InternetExplorer浏览器和它的辅助对象到底发生了什么。
什么是浏览器辅助对象?
从这个角度来看,InternetExplorer是,就像任何其他基于Win32的程序与它自己的内存空间来保存。
浏览器辅助对象,你可以编写组件-特别是,在进程内组件对象模型(COM)组件,InternetExplorer将每次启动时加载。
这样的对象在相同的内存的浏览器中运行,并且可以执行任何操作上可用的窗口和模块。
例如,一个BHO可以检测浏览器的典型事件,如GoBack的,GoForward,和一个DocumentComplete访问浏览器的菜单和工具栏进行修改,创建窗口,以显示更多的信息当前查看的页面上,并安装挂钩,以监视的消息和行动。
在进一步讨论之前BHO的细枝末节,有一对夫妇点,我需要进一步照亮。
首先,BHO连接到浏览器的主窗口。
在实践中,这意味着只要一个新的浏览器窗口中创建一个新的对象实例被创建。
任何BHO实例的生活和死亡与浏览器的实例。
其次,在InternetExplorer4.0及更高版本的BHO只存在。
如果你正在运行在MicrosoftWindows98,Windows2000中的Windows95,或WindowsNT版本4.0操作系统的活动桌面外壳更新程序(shell版本4.71),也支持通过Windows资源管理器的BHO。
这有一些影响,我会更多的讨论后,当性能方面的考虑和评估的BHO的影响。
在其最简单的形式,一个BHO是一个COM进程内服务器特定的注册表键下注册。
在启动时,InternetExplorer查找键和加载的所有对象的CLSID是储存在那里。
浏览器初始化对象,并要求它为一个特定的接口。
如果发现该接口,InternetExplorer使用的方法,通过辅助对象的IUnknown指针。
该过程的图示于图1。
图1。
InternetExplorer如何加载和初始化器辅助对象。
BHO的网站是COM接口,用于建立通信。
浏览器可能会找到一个列表中的CLSID在注册表中创建一个进程内的每个实例。
其结果是,这样的对象被加载在浏览器的上下文中,可以操作,就好像它们是本地组件。
但是,由于InternetExplorer的基于COM的性质,进程空间内被加载并帮助不大。
换句话说,它是真实的,BHO可以做许多潜在的有用的东西,就像子类成分的窗户或安装线程局部钩子,但它肯定是离开了浏览器的核心活动。
在浏览器的事件挂钩或自动辅助对象需要建立一个特权和基于COM的沟通渠道。
出于这个原因,BHO应该实现一个称为IObjectWithSite的接口。
通过的IObjectWithSite的,其实,InternetExplorer将一个指针传递到它的IUnknown接口。
BHO可以,反过来,存储和查询更具体的接口,,,如IWebBrowser2的,IDispatch的,和IConnectionPointContainer。
另一种方式来看待的BHO的互联网资源管理器外壳扩展。
正如你所知道的,一个Windows外壳扩展是一个COM进程内服务器时,是要执行某个特定的动作上,Windows资源管理器加载一个文件,例如,显示其上下文菜单。
通过写一个实现几个COM接口的COM模块,你将有机会添加新的上下文菜单项,然后加以妥善处理。
注册一个shell扩展,也必须在这样一种方式,Windows资源管理器中可以找到它。
浏览器辅助对象遵循相同的模式,唯一的改变是要实现的接口。
稍有不同的是触发,导致一个BHO被加载。
然而,尽管执行上的差异,外壳扩展的BHO都有一个共同的性质,下表显示。
表1中。
外壳扩展和浏览器辅助对象是如何实现的共同特点
特点
Shell扩展
浏览器辅助对象
载入的
Windows资源管理器。
的InternetExplorer(Windows资源管理器外壳版本4.71和更高版本)。
触发条件
用户的操作某一类的文件(即,用鼠标右键单击)。
打开的浏览器窗口。
卸载时
几秒钟后,引用计数为0。
,造成它的浏览器窗口被关闭。
实行
COM进程内DLL。
COM进程内DLL
注册要求
通常的COM服务器,加上其他项目,根据项目的类型的外壳扩展名和文件类型,它适用于。
通常的COM服务器加一个条目有资格作为一个BHO项。
接口需要
依赖于外壳扩展的类型。
IObjectWithSite的。
如果你有兴趣在外壳扩展,请参阅MSDNLibrary在线或CD文件的底漆。
覆盖面更广,看看我最近出版的书,专业的Shell编程的Windows(Wrox出版社出版,1-861001-84-3)。
助手对象的生命周期
正如我前面提到的,的BHO不只是InternetExplorer支持的。
你至少外壳版本4.71,你的BHO也将被加载Windows资源管理器,这意味着一个独特的浏览器,可以浏览网页和本地磁盘类似的用户体验。
下表提供了一个以产品为导向的观点,当今的各种shell版本。
外壳版本号的版本信息存储在SHELL32.DLL。
表2中。
支持各种shell版本浏览器辅助对象
Shell版本
已安装的产品
的BHO的支持
4.00
带或不带InternetExplorer4.0或更早版本的Windows95和WindowsNT4.0。
注意 没有安装壳牌更新。
InternetExplorer4.0中
4.71
使用InternetExplorer4.0和活动桌面外壳更新版本的Windows95和WindowsNT4.0。
InternetExplorer和Windows资源管理器
4.72
Windows98中。
InternetExplorer和Windows资源管理器
5.00
Windows2000中
InternetExplorer和Windows资源管理器
浏览器辅助对象是将要显示和卸载时,窗口被销毁时被加载浏览器的主窗口。
如果你的浏览器窗口中打开多个副本,更多的BHO实例就会被创建。
尽管在命令行启动浏览器的BHO加载。
例如,它就会被加载,即使你只是想看到的只是一个特定的HTML页或一个给定的文件夹中。
在一般情况下,考虑到BHO时的explorer.exe和iexplore.exe的执行。
如果你设置了“打开每个文件夹在它自己的窗口中的”文件夹设置,BHO加载每次你打开一个文件夹。
图2。
使用此设置,每次打开一个文件夹时,explorer.exe的一个单独的实例的执行,并加载已注册的BHO。
但是,请注意,这仅适用于当你在桌面上“我的电脑”图标,从打开的文件夹。
在这种情况下,的外壳调用explorer.exe的每次移动到另一个文件夹。
同样也不会发生,如果你开始从两个窗格浏览。
事实上,当你改变文件夹的外壳不推出一个新的浏览器实例,但只是简单地创建嵌入视图对象的另一个实例。
奇怪的是,如果你在地址栏中键入一个新的名称,更改文件夹,浏览总是发生在同一个窗口,是否是单或双窗格的窗口资源管理器的视图。
使用InternetExplorer简单得多。
您有多个副本,只有当你明确地多次运行iexplore.exe的。
当你从InternetExplorer中打开新的窗口,每个窗口中复制一个新的线程,而不发起一个新的进程,因此无需重新加载的BHO。
最重要的,最有趣的功能的BHO的是,他们是非常动态的。
每个时间窗口资源管理器或IE浏览器的窗口被打开,加载器读取从注册表中和交易与他们所安装的辅助对象的CLSID。
你可以有不同的BHO浏览器加载不同的副本,如果您编辑注册表打开浏览器实例之间。
这意味着,现在你有一个很好的替代写一个新的浏览器从头开始,你可以嵌入web浏览器在MicrosoftVisualBasic或Microsoft基础类(MFC)框架窗口。
在同一时间,你给出一个很好的机会,安排非常可扩展的浏览器应用程式。
你可以依靠的全功率的InternetExplorer,并添加许多附加产品,只要你想,当它适合您的需求。
IObjectWithSite接口
从这个高层次的概述,浏览器辅助对象的概念中明显出现了:
一个BHO是一个动态链接库(DLL),可以将其自身附加到任何新的InternetExplorer实例,在某些情况下,Windows资源管理器。
这种模块可以通过浏览器容器的站点取得联系。
一般来说,一个站点是一个放置在中间的容器和每个包含的对象的中间对象。
通过它,容器管理的内容所包含的对象,作为回报,使得对象的内部功能。
基于站点的容器和对象之间的关系涉及类似的IOleClientSite容器侧上的,并IOleObject在物体侧上的接口执行。
容器通过调用IOleObject上的方法,让对象知道它的主机环境。
当容器是InternetExplorer(或基于Web的版本的Windows资源管理器)中,性能问题,降低了通信模式的基本。
现在需要实现一个称为IObjectWithSite的接口更简单,更轻的对象。
它提供了两个方法。
表3中。
IObjectWithSite接口定义
方法
描述
HRESULTSetSite(
的IUnknown*pUnkSite)
接收的浏览器的IUnknown指针。
典型的实现将简单地存储这样的指针以供进一步使用。
HRESULTGetSite(
REFIIDriid的,
无效**ppvSite)
检索并返回通过SetSite()的最后一个站点设置指定的接口。
典型的实现将查询存储pUnkSite指定的接口的指针。
一个BHO的唯一严格的要求,实现了这个接口。
请注意,你应该避免返回E_NOTIMPL从前面的任何功能。
要么你不实现该接口,或者你应该能够正确地进行编码的方法。
编写一个浏览器辅助对象
浏览器辅助对象是一个COM进程内服务器,所以什么比活动模板库(ATL)建立一个更好的?
选择ATL的另一个原因是,它已经提供了一个默认的IObjectWithSite的接口和足够好的执行。
另外,在ATLCOM向导原生支持的预定义类型的对象,有一个InternetExplorer对象,这仅仅是一个BHO对象的类型应该是。
ATL InternetExplorer对象,其实是一个简单的对象,也就是说,一个COM服务器,它支持的IUnknown和自注册加IObjectWithSite的。
如果您到您的ATL项目中添加这样的对象,调用相应类CViewSource,你的向导从下面的代码:
类ATL_NO_VTABLECViewSource:
公共CComObjectRootEx
公共CComCoClass
公共IObjectWithSiteImpl
公众的IDispatchImpl 与LIBID_HTMLEDITLib> 正如你可以看到的,向导已经从IObjectWithSiteImpl,这是一个ATL模板类,它提供了一个基本的实现IObjectWithSite的类继承。 (见atlcom.h在ATL\include目录中的MicrosoftVisualStudio98)。 通常没有必要覆盖的GetSite的()成员函数。 相反,SetSite()编码的行为的时候,如果不总是,需要的定制。 事实上,ATL,简单的存储的IUnknown指针的成员称为m_spUnkSite的变量。 其余的文章中,我将讨论一个相当复杂和丰富的BHO的例子。 该对象将其自身附加到InternetExplorer,并与正在浏览的页面的源代码显示一个文本框。 当您更改页面,并显示为灰色,如果InternetExplorer正在显示的文件是不是一个HTML页面,该代码窗口将自动更新。 适用于原始的HTML代码的任何更改会立即反映在浏览器中。 这种魔法是通过动态HTML(DHTML)。 这样的代码窗口中,可以通过热键隐藏,然后回忆。 可见,它与InternetExplorer,调整大小如图3所示的正确共享整个桌面工作区。 图3。 浏览器辅助对象的行动。 它连接到InternetExplorer,并显示正在浏览的页面的源代码。 它也允许你进入(但不保存)的变化。 这个例子的关键点是访问InternetExplorer的浏览机制,这只不过是比WebBrowser控件的一个实例。 这个例子可以分解成五个主要步骤: 1.,检测加载对象,它是InternetExplorer或Windows资源管理器。 2.获取IWebBrowser2的接口,使WebBrowser对象。 3.捕获的Web浏览器的特定事件。 4.访问的文件被查看,确认它是一个HTML文件。 5.管理对话框窗口的HTML源代码。 第一步是在DllMain()中的代码来完成。 SetSite() ,取而代之的是在正确的地方得到的WebBrowser对象的指针。 让我们来看看所有这些步骤更详细一点。 什么是不包括在这里的信息,你可以参考MSDNOnlineWeb站点上可用的源代码。 检测的呼叫 正如前面提到的,一个BHO可以通过InternetExplorer或Windows资源管理器,如果你正在运行至少外壳版本4.71。 在这种情况下,我设计一个专门针对与HTML页面的辅助对象,所以它会与Windows资源管理器什么都没有做。 一个DLL,它不希望被加载一定的呼叫者可以简单地在它的DllMain()函数返回False,一旦检测到是谁在呼叫。 GetModuleFileName() API函数返回调用者模块的名称,如果你传递NULL作为第一个参数。 这样的参数是你想知道他的名字的模块的句柄。 的NULL意味着你要调用的进程的名称。 (dwReason==DLL_PROCESS_ATTACH调用) { 和TCHARpszLoader[MAX_PATH]; GetModuleFileName(NULL,pszLoader,MAX_PATH); _tcslwr(pszLoader); (_tcsstr(pszLoader,_T(的“explorer.exe”))) 返回FALSE; } 一旦你知道这个名字的过程中,你可以退出装载,如果它是Windows资源管理器。 请注意,更有选择性的选择可能是危险的。 事实上,其他进程可能会尝试加载的DLL正当理由,被拒绝。 这种情况下的第一个受害者是Regsvr32.exe的,该程序用于自动注册对象。 如果你犯了一个不同的测试,也就是说,只针对IE浏览器可执行文件: (_tcsstr(pszLoader,_T(“IEXPLORE.EXE”))) 您将无法再注册的DLL。 事实上,Regsvr32.exe的尝试加载DLL 中的DllRegisterServer()函数调用时,呼叫将被拒绝。 获取触摸的web浏览器 SetSite()方法是在初始化的BHO,在那里你将仅出现一次执行所有的任务。 当您导航到一个URL与InternetExplorer,你应该等待几个事件,以确保已经完全下载所需的文件,然后初始化。 只有在这一点上,你可以安全地访问它的内容通过公开的对象模型,如果有的话。 这意味着你需要获得两个指针。 第一个是IWebBrowser2的指针,呈现的WebBrowser对象的接口。 第二个指针事件。 该模块必须注册为一个事件侦听器的浏览器,以便接收通知的下载和文档的特定事件。 通过使用ATL智能指针: CComQIPtr CComQIPtr IID_IConnectionPointContainer>m_spCPC; 源代码看起来像下面这样: HRESULTCViewSource: : SetSite(的IUnknown*pUnkSite) { //检索和存储的IWebBrowser2指针 m_spWebBrowser2=pUnkSite; 如果(m_spWebBrowser2==NULL) 返回E_INVALIDARG; //检索,和存储的IConnectionPointerContainer的指针 m_spCPC=m_spWebBrowser2; 如果(m_spCPC==NULL) 返回E_POINTER; //检索并存储浏览器的HWND。 另外安装 //为进一步利用键盘钩子 RetrieveBrowserWindow(); //连接到容器的接收事件通知 返回CONNECT(); } 为了获得一个指向IWebBrowser2的接口,您只需查询。 同样IConnectionPointContainer,事件处理的第一步骤,用于发生。 SetSite()的代码检索的HWND的浏览器,并安装一个键盘钩子在当前线程上。 以后将用于移动和调整InternetExplorer窗口的HWND。 钩,而不是供应提供快捷键,使代码窗口出现和消失在用户的休闲的目的。 从浏览器中获取事件 当你浏览到一个新的URL,浏览器需要主要完成两件事: 下载所引用的文件,并准备主机环境。 换句话说,它必须初始化和使外部可用的对象模型。 根据文件的类型,这意味着要么一个MicrosoftActiveX服务器应用程序注册为处理该文件(例如,MicrosoftWord的doc文件)加载或初始化一些内部组件分析的文档内容,并填写元素的对象模型呈现它。 这是发生什么事HTML网页的内容可通过DHTML对象模型。 当文件完全下载后,一个DownloadComplete事件被激活。 这并不意味着它是安全地管理文档的内容通过其对象模型。 相反,DocumentComplete事件表示一切已经完成,文件准备就绪。 (请注意,一个DocumentComplete只到达你第一次访问的URL。 随后,如果按F5键或单击刷新按钮,您会收到只有一个DownloadComplete事件。 ) 拦截浏览器所触发的事件,BHO需要连接到它通过的IConnectionPoint接口的功能,将处理的各种事件,并通过IDispatch的表。 以前的指针IConnectionPointContainer所得用于调用的FindConnectionPoint方法,它返回一个指针,指向所需的输出接口连接点对象: 在这种情况下,DIID_DWebBrowserEvents2。 下面的代码显示了如何连接发生: HRESULTCViewSource: : 连接(空) { HRESULT小时; 但是CComPtr //接收web浏览器事件的连接点 HR=m_spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2,SPCP); (FAILED(HR)) 返回小时; //我们的事件处理程序传递到容器中。 每个事件发生时的时间 //容器将调用IDispatch接口的功能 //我们实现了。 HR=SPCP建议(reinterpret_cast的 返回小时; } 通过调用的IConnectionPoint的建议()方法,的BHO让浏览器知道它感兴趣的接收事件通知。 由于COM的事件处理机制,这实际上意味着,BHO浏览器的IDispatch接口的指针。 然后浏览器将调用的IDispatch的Invoke()方法方法,作为第一个参数传递的事件ID。 HRESULTCViewSource: : 调用(REFIIDriid的DISPIDdispidMember, LCIDLCID,WORDwFlags,DISPPARAMS*pDispParams的, VARIANT*pvarResult,EXCEPINFOpExcepInfo,UINT*puArgErr) { 如果(dispidMember==DISPID_DOCUMENTCOMPLETE) 的OnDocumentComplete(); m_bDocumentCompleted=TRUE; } : } 重要的是要记住断开事件时不再需要从浏览器。 如果您忘记了这样做,BHO将保持锁定,即使你关闭浏览器窗口。 (除其他事项外,这意味着你可以不重新编译或删除对象)的好时机断开时,您收到OnQuit的事件。 访问文档对象 在这一点上,BHOIE的WebBrowser控件的引用,浏览器连接到接收它生成的所有事件。 当网
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- BHO 浏览器 辅助 对象