IE插件開發(fā)用BHO(BrowserHelperObjects)定制瀏覽器_第1頁
IE插件開發(fā)用BHO(BrowserHelperObjects)定制瀏覽器_第2頁
IE插件開發(fā)用BHO(BrowserHelperObjects)定制瀏覽器_第3頁
IE插件開發(fā)用BHO(BrowserHelperObjects)定制瀏覽器_第4頁
IE插件開發(fā)用BHO(BrowserHelperObjects)定制瀏覽器_第5頁
已閱讀5頁,還剩25頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、目錄TOC o 1-5 h z HYPERLINK l bookmark0如何使用BHO定制你的InternetExplorer瀏覽器2 HYPERLINK l bookmark2一、簡介(Introduction)2 HYPERLINK l bookmark4二、關(guān)于軟件定制(ProgramCustomization)2 HYPERLINK l bookmark6三、什么是BHO?(WhatAreBrowserHelperObjects?)2 HYPERLINK l bookmark8四、BHO的生存周期(TheLifecycleofHelperObjects)4 HYPERLINK l b

2、ookmark10五、關(guān)于lObjectWithSite接口(ThelObjectWithSiteInterface)5 HYPERLINK l bookmark12六、構(gòu)造自己的BHO對象(WritingaBrowserHelperObject)6 HYPERLINK l bookmark14七、探測誰在調(diào)用這個(gè)對象DetectingWhosCalling7 HYPERLINK l bookmark16八、與Web瀏覽器取得聯(lián)系GetinTouchwithWebBrowser8 HYPERLINK l bookmark18九、從InternetExplorer瀏覽器取得事件GettingEv

3、entsfromtheBrowser9十、存取文檔對象AccessingtheDocumentObject10十一、管理代碼窗口ManagingtheCodeWindow12 HYPERLINK l bookmark20十二、注冊BHO對象RegistrationofHelperObjects13 HYPERLINK l bookmark22十三、總結(jié)Summary13 HYPERLINK l bookmark24BrowserHelperObjects:TheBrowsertheWayYouWantIt13Introduction簡介)14 HYPERLINK l bookmark26Pro

4、gramCustomization關(guān)于軟件定制)14 HYPERLINK l bookmark28WhatAreBrowserHelperObjects?(什么是BHO?)15 HYPERLINK l bookmark30TheLifecycleofHelperObjects(BHO的生存周期)17 HYPERLINK l bookmark32TheIObjectWithSiteInterface(關(guān)于lObjectWithSite接口)19 HYPERLINK l bookmark34WritingaBrowserHelperObject(構(gòu)造自己的BHO對象)20 HYPERLINK l

5、bookmark36DetectingWhosCalling(七探測誰在調(diào)用這個(gè)對象)22 HYPERLINK l bookmark38GetinTouchwithWebBrowser(八與Web瀏覽器取得聯(lián)系)23GettingEventsfromtheBrowser(九從InternetExplorer瀏覽器取得事件).24 HYPERLINK l bookmark42AccessingtheDocumentObject(十存取文檔對象)25 HYPERLINK l bookmark44ManagingtheCodeWindow(十一管理代碼窗口)29 HYPERLINK l bookma

6、rk46RegistrationofHelperObjects(十二注冊BHO對象)30 HYPERLINK l bookmark48Summary(總結(jié))30如何使用BHO定制你的InternetExplorer瀏覽器原文:微軟公司DinoEsposito編譯:朱先中原文出處:BrowserHelperObjects:TheBrowsertheWayYouWantIt一、簡介(Introduction)有時(shí),你可能需要一個(gè)定制版本的瀏覽器。在這種情況下,你可以自由地把一些新穎但又不標(biāo)準(zhǔn)的特征增加到一個(gè)瀏覽器上。結(jié)果,你最終有的只是一個(gè)新但不標(biāo)準(zhǔn)的瀏覽器。Web瀏覽器控件只是瀏覽器的分析引擎。

7、這意味著仍然存在若干的與用戶接口相關(guān)的工作等待你做一一增加一個(gè)地址欄,工具欄,歷史記錄,狀態(tài)欄,頻道欄和收藏夾等。如此,要產(chǎn)生一個(gè)定制的瀏覽器,你可以進(jìn)行兩種類型的編程一一一種象微軟把Web瀏覽器控件轉(zhuǎn)變成一個(gè)功能齊全的瀏覽器如InternetExplorer;一種是在現(xiàn)有的基礎(chǔ)上加一些新的功能。如果有一個(gè)直接的方法定制現(xiàn)有的InternetExplorer該多好?BHO(BrowserHelperObjects,我譯為瀏覽器幫助者對象,以下皆簡稱BHO)正是用來實(shí)現(xiàn)此目的的。二、關(guān)于軟件定制(ProgramCustomization)以前,定制一個(gè)軟件的行為主要是通過子類化方法實(shí)現(xiàn)的。通過這

8、種辦法,你可以改變一個(gè)窗口的外表與行為。子類化雖然被認(rèn)為是一種有點(diǎn)暴力方式受害者根本不知道發(fā)生的事情但它還是長時(shí)間以來的唯一的選擇。隨著微軟Win32API的到來,進(jìn)程間子類化不再被鼓勵(lì)使用并愈發(fā)變得困難起來。當(dāng)然,如果你是勇敢的-指針從未嚇倒你,而最重要的是,如果你已經(jīng)游刃于系統(tǒng)鉤子之間,你可能覺得這一問題太簡單了。但是情形并不總是這樣。暫放下這點(diǎn)不管,問題在于每一個(gè)進(jìn)程運(yùn)行在自己的地址空間中,而且打破進(jìn)程邊界略微有些不正確性。另一方面,你可能需要對定制進(jìn)行更好的管理。更經(jīng)常情況下,定制可能是程序本身強(qiáng)烈要求實(shí)現(xiàn)的。在后者情況下,已安裝的軟件只需在既定的磁盤位置查詢另外的組件模塊,然后裝載、

9、設(shè)定初值,最后讓它們自由地按照既定的設(shè)計(jì)工作。這正是InternetExplorer瀏覽器和它的BHO所要實(shí)現(xiàn)的。三、什么是BHO?(WhatAreBrowserHelperObjects?)從某種觀點(diǎn)看InternetExplorer同普通的Win32程序沒有什么兩樣。借助于BHO,你可以寫一個(gè)進(jìn)程內(nèi)COM對象,這個(gè)對象在每次啟動(dòng)時(shí)都要加載。這樣的對象會(huì)在與瀏覽器相同的上下文中運(yùn)行,并能對可用的窗口和模塊執(zhí)行任何行動(dòng)。例如,一個(gè)BHO能夠探測到典型的事件,如GoBack、GoForward、DocumentComplete等;另外BHO能夠存取瀏覽器的菜單與工具欄并能做出修改,還能夠產(chǎn)生新窗

10、口來顯示當(dāng)前網(wǎng)頁的一些額外信息,還能夠安裝鉤子以監(jiān)控一些消息和動(dòng)作。簡而言之,BHO的工作如我們打入瀏覽器領(lǐng)地的一位間諜(注意這是微軟允許的合法工作)。在進(jìn)一步了解BHO細(xì)節(jié)之前,有幾點(diǎn)我需要進(jìn)一步闡述。首先,BHO對象依托于瀏覽器主窗口。實(shí)際上,這意味著一旦一個(gè)瀏覽器窗口產(chǎn)生,一個(gè)新的BHO對象實(shí)例就要生成。任何BHO對象與瀏覽器實(shí)例的生命周期是一致的。其次,BHO僅存在于InternetExplorer4.0及以后版本中。如果你在使用MicrosoftWindows?98,Windows2000,Windows95,orWindowsNT版本4.0操作系統(tǒng)的話,也就一塊運(yùn)行了活動(dòng)桌面外殼4

11、.71,BHO也被Windows資源管理器所支持。BHO是一個(gè)COM進(jìn)程內(nèi)服務(wù),注冊于注冊表中某一鍵下。在啟動(dòng)時(shí),InternetExplorer查詢那個(gè)鍵并把該鍵下的所有對象預(yù)以加載。InternetExplorer瀏覽器初始化這一對象并要求某一接口功能。如果發(fā)現(xiàn)這一接口,InternetExplorer使用其提供的方法傳遞IUnknown指針到BHO對象。見圖一:圖一ie瀏覽器如何裝入和初始化BHO對象,BHO場所(site)是用于實(shí)現(xiàn)通信的COM接口瀏覽器可能在注冊表中發(fā)現(xiàn)一系列的CLSID,并由此為每個(gè)CLSID建立一個(gè)進(jìn)程中實(shí)例。結(jié)果是,這些對象被裝載至瀏覽器上下文中并運(yùn)行起來,好象

12、它們是本地組件一樣。但是,由于InternetExplorer的COM特性,即使被裝入到它的進(jìn)程空間中于事(你的野心實(shí)現(xiàn))也不一定會(huì)有多大幫助。用另一說法,BHO的確能夠做許多潛在的有用的事情,如子類化組成窗口或者安裝線程局部鉤子,但是它確實(shí)遠(yuǎn)離瀏覽器的核心活動(dòng)。為了鉤住瀏覽器的事件或者自動(dòng)化瀏覽器,BHO需要建立一個(gè)私有的基于COM的通訊通道。為此,該BHO應(yīng)該實(shí)現(xiàn)一個(gè)稱為IObjectWithSite的接口。事實(shí)上,通過接口IobjectWithSite,InternetExplorer可以傳遞它的IUnknown接口。BHO反過來能夠存儲(chǔ)該接口并進(jìn)一步查詢更專門的接口,如IWebBrow

13、ser2、IDispatch和IConnectionPointContainer。另外一種分析BHO對象的途徑與InternetExplorer外殼擴(kuò)展有關(guān)。我們知道,一個(gè)WINDOWS外殼擴(kuò)展即是一個(gè)進(jìn)程內(nèi)的COM服務(wù)器,它在Windows資源管理器執(zhí)行某種動(dòng)作時(shí)裝入內(nèi)存如顯示上下文菜單。通過建立一個(gè)實(shí)現(xiàn)幾個(gè)COM接口的COM模塊,你就給上下文菜單加上一些項(xiàng)并能預(yù)以正確處理。一個(gè)外殼擴(kuò)展必須以Windows資源管理器能夠發(fā)現(xiàn)的方法注冊。一個(gè)BHO對象遵循同樣的模式唯一的改變在于要實(shí)現(xiàn)的接口。然而,盡管實(shí)現(xiàn)方式有所不同,外殼擴(kuò)展與BHO仍有許多共同的特點(diǎn)。如下表一:表一外殼擴(kuò)展與BHO相近特性

14、比較特性外殼擴(kuò)展BHO對象加載者Windows資源管理器InternetExplorer(和外殼4.17及以上版本的Windows資源管理器)擊活動(dòng)作在某類文檔上的用戶動(dòng)作(即單擊右鍵)打開瀏覽器窗口何時(shí)卸載參考計(jì)數(shù)達(dá)到0的幾秒之后導(dǎo)致它加載的窗口關(guān)閉時(shí)實(shí)現(xiàn)形式COM進(jìn)程中DLLCOM進(jìn)程中DLL注冊需求常常是為一個(gè)COM服務(wù)器設(shè)置的入口處,另加的入口依賴于外殼類型及它要應(yīng)用至的文檔類型常常是為一個(gè)COM服務(wù)器設(shè)置的入口處,另加一個(gè)把它申請為BHO的注冊入口接口需求依賴于外殼擴(kuò)展的類型IObjectWithSite如果你對SHELL擴(kuò)展編程有興趣的話,可以參考MSDN有關(guān)資料。四、BHO的生存

15、周期(TheLifecycleofHelperObjects)前面已經(jīng)說過,BHO不僅僅為InternetExplorer所支持。如果你在使用外殼4.71或者更高版本,你的BHO對象也會(huì)被Windows資源管理器所加載。下表二展示了我們可以使用的不同版本的外殼產(chǎn)品情況,Windows外殼版本號存于庫文件shell32.dll中。表二不同版本的Windows外殼對于BHO的支持情況外殼版本安裝的產(chǎn)品BHO的支持情況4.00Windows95,WindowsNT4.0帶或不帶InternetExplorer4.0或更老版本。注意沒有安裝外殼更新InternetExplorer4.04.71Wind

16、ows95,WindowsNT4.0帶InternetExplorer4.0和活動(dòng)桌面外殼更新InternetExplorer與Windows資源管理器4.72Windows98InternetExplorer與Windows資源管理器5.00Windows2000InternetExplorer與Windows資源管理器BHO對象隨著瀏覽器主窗口的顯示而裝入,隨著瀏覽器主窗口的銷毀而缷載。如果你打開多個(gè)瀏覽器窗口,多個(gè)BHO實(shí)例也一同產(chǎn)生。無論瀏覽器以什么樣的命令行啟動(dòng),BHO對象都被加載。舉例來說,即使你只是想要見到特定的HTML頁或一個(gè)給定的文件夾,BHO對象也被加載。一般地,當(dāng)expl

17、orer.exe或iexplore.exe運(yùn)行的時(shí)候,BHO都要被考慮在內(nèi)。如果你設(shè)置了Openeachfolderinitsownwindow(對每一個(gè)文件夾以一個(gè)獨(dú)立窗口打開)文件夾選項(xiàng),那么你每次打開一個(gè)文件夾,BHO對象都要被加載。見圖二。圖二經(jīng)過這樣設(shè)置,你每次打開一個(gè)文件夾時(shí),執(zhí)行一個(gè)獨(dú)立的explorer.exe實(shí)例,并裝入已注冊的BHO對象。但是注意,這種情形僅適于當(dāng)你從桌面上的我的電腦圖標(biāo)中打開文件夾的情況。在這種情況下,每次你移到另外一個(gè)文件夾時(shí)外殼都要調(diào)用explorer.exeo這種情況在你同時(shí)用兩個(gè)窗格進(jìn)行瀏覽時(shí)是不會(huì)發(fā)生的。事實(shí)上,當(dāng)你改變文件夾時(shí),外殼是不會(huì)啟動(dòng)瀏

18、覽器的新的實(shí)例的而僅是簡單創(chuàng)建嵌入視圖對象的另外一個(gè)實(shí)例。奇怪的是,如果你在地址欄中輸入一個(gè)新的名字來改變文件夾時(shí),在同一個(gè)窗口中同樣可以達(dá)到瀏覽之目的,無論Windows資源管理器視圖是單個(gè)的還是雙視圖形式。對于InternetExplorer的情形,事情要更簡單一些。只有你顯式地多次運(yùn)行iexplore.exe瀏覽器時(shí),你才有多個(gè)InternetExplorer的拷貝。當(dāng)你從InternetExplorer中打開新的窗口時(shí),每一個(gè)窗口在一個(gè)新的線程中被復(fù)制而不是創(chuàng)建一個(gè)新的進(jìn)程,因此也就不需要重新載入BHO對象。首先,BHO最有趣的地方是,它是極度動(dòng)態(tài)的。每次Windows資源管理器或者I

19、nternetExplorer打開,裝載器從注冊表中讀取已安裝的BHO對象的CLSID然后處理它們。如果你在打開的瀏覽器多個(gè)實(shí)例中間編輯注冊表的話,你可以隨著多個(gè)瀏覽器拷貝的載入而裝入多個(gè)不同的BHOo這就是說,如果你選擇從頭創(chuàng)建一個(gè)新的屬于自己的瀏覽器,那么你可以把它內(nèi)嵌在一個(gè)VisualBasic或者M(jìn)FC框架窗口中。同時(shí)你有相當(dāng)?shù)臋C(jī)會(huì)來靈活安排瀏覽程序。如果它們能滿足你的需要的話,你可以依賴于InternetExplorer的強(qiáng)大的功能并且加上你想要的盡可能多的插件。五、關(guān)于IObjectWithSite接口(TheIObjectWithSiteInterface)從一個(gè)高起點(diǎn)來看,BH

20、O即是一個(gè)DLL,它能夠依附于InternetExplorer瀏覽器的一個(gè)新建的實(shí)例,在某些情況下也適用于Windows資源管理器。一般地,一個(gè)場所(site)是一個(gè)中間對象,它位于容器對象與被包容對象之間。通過它,容器對象管理被包容對象的內(nèi)容,也因此使得對象的內(nèi)部功能可用。為此,容器方要實(shí)現(xiàn)接口IoleClientSite,被包容對象要實(shí)現(xiàn)接口IOleObject。通過調(diào)用IOleObject提供的方法,容器對象使得被包容對象清楚地了解其HOST的環(huán)境。一旦容器對象成為InternetExplorer(或是具有WEB能力的Windows資源管理器),被包容對象只需實(shí)現(xiàn)一個(gè)輕型的IObject

21、WithSite接口。該接口提供了以下方法:表三IObjectWithSite定義方法描述HRESULTSetSite(IUnknown*pUnkSite)接收ie瀏覽器的IUnknown指針。典型實(shí)現(xiàn)是保存該指針以備將來使用。HRESULTGetSite(REFIIDriid,void*ppvSite)從通過SetSite()方法設(shè)置的場所中接收并返回指定的接口,典型實(shí)現(xiàn)是查詢前面保存的接口指針以進(jìn)一步取得指定的接口。對BHO的唯一嚴(yán)格的要求正在于必須實(shí)現(xiàn)這一個(gè)接口。注意你應(yīng)該避免在調(diào)用以上任何一個(gè)函數(shù)時(shí)返回E_NOTIMPL。要么你不實(shí)現(xiàn)這一接口,要么應(yīng)保證在調(diào)用這些方法時(shí)進(jìn)行正確地編碼。

22、六、構(gòu)造自己的BHO對象(WritingaBrowserHelperObject)一個(gè)BHO對象就是一個(gè)進(jìn)程中服務(wù)器DLL,選用ATL創(chuàng)建它是再恰當(dāng)不過的了。我們選擇ATL的另外一個(gè)原因是因?yàn)樗呀?jīng)提供了缺省的而且提供了IObjectWithSite接口的足夠好的實(shí)現(xiàn)。另外,在ATLCOM向?qū)П镜刂С值囊讯x好的對象類型當(dāng)中,有一個(gè),就是InternetExplorer對象,這正是一個(gè)BHO應(yīng)該具有的類型。一個(gè)ATLInternetExplorer對象,事實(shí)上是一個(gè)簡單對象也就是說,是一個(gè)支持IUnknown和自注冊,還有接口IObjectWithSite的COM服務(wù)器。如果你在ATL工程中添

23、加一個(gè)這樣的對象,并調(diào)用相應(yīng)的類CViewSource,你將從向?qū)е械玫较铝写a:classATL_NO_VTABLECViewSource:publicCComObjectRootEx,publicCComCoClass,publicIObjectWithSiteImpl,publicIDispatchImpl正如你所見,向?qū)б呀?jīng)使類從接口IObjectWithSiteImpl繼承,這是一個(gè)ATL模板類,它提供了接口IObjectWithSite的基本實(shí)現(xiàn)。一般情況下,沒有必要重載成員函數(shù)GetSite()。取而代之的是,SetSite()實(shí)現(xiàn)代碼經(jīng)常需要加以定制。ATL實(shí)際上僅僅把一個(gè)IU

24、nknown接口指針存儲(chǔ)在成員變量m_spUnkSite中。在文章的剩余部分,我將討論一個(gè)BHO的相當(dāng)復(fù)雜而豐富的例子。該BHO對象將依附于InternetExplorer,并顯示一個(gè)文本框來顯示當(dāng)前正瀏覽的網(wǎng)頁源碼。該代碼窗口將隨著你改變網(wǎng)頁而自動(dòng)更新,如果瀏覽器顯示的不是一個(gè)HTML網(wǎng)頁時(shí),它將變灰。你對于原始HTML代碼的任何改動(dòng)立即反映在瀏覽器中。HTML(DHTML)使得這一看似魔術(shù)般的實(shí)現(xiàn)成為可能。該代碼窗口可被隱藏和通過按動(dòng)熱鍵重現(xiàn)。在可見情況下,它與InternetExplorer共享整個(gè)桌面空間,見圖三。探測誰在裝入這個(gè)對象,是InternetExplorer還是Window

25、s資源管理器;獲取接口IWebBrowser2以實(shí)現(xiàn)Web瀏覽器對象;捕捉Web瀏覽器的特定事件;存取當(dāng)前文檔對象,確定它是一份HTML類型的文件;管理對話框窗口以實(shí)現(xiàn)HTML源碼的顯示;第一個(gè)步驟是在DllMain()中完成的。SetSite()是取得指向WebBrowser對象指針的適當(dāng)位置。請?jiān)敿?xì)分析以下步驟。七、探測誰在調(diào)用這個(gè)對象DetectingWhosCalling如前所述,一個(gè)BHO對象會(huì)被InternetExplorer或者Windows資源管理器(前提:外殼版本4.71或者更高)所加載。所以我專門設(shè)計(jì)了一個(gè)BHO來處理HTML網(wǎng)頁,因此這個(gè)BHO與資源管理器毫無關(guān)系。如果一

26、個(gè)Dll不想被調(diào)用者一起加載,只需在DllMain()中實(shí)現(xiàn)了探明誰在調(diào)用該對象后返回FALSE即可。參看下面代碼:if(dwReason=DLL_PROCESS_ATTACH)TCHARpszLoaderMAX_PATH;返回調(diào)用者模塊的名稱,第一個(gè)參數(shù)應(yīng)為NULL,詳見msdn。GetModuleFileName(NULL,pszLoader,MAX_PATH);_tcslwr(pszLoader);if(_tcsstr(pszLoader,_T(explorer.exe)returnFALSE;一旦知道了當(dāng)前進(jìn)程是Windows資源管理器,可立即退出。注意,再多加一些條件語句是危險(xiǎn)的!事

27、實(shí)上,另外一些進(jìn)程試圖裝入該DLL時(shí)將被放棄。如果你做另外一個(gè)試驗(yàn),比方說針對InternetExplorer的執(zhí)行文件iexplorer.exe,這時(shí)第一個(gè)受害者就是regsvr32.exe(該程序用于自動(dòng)注冊對象)。if(!_tcsstr(pszLoader,_T(iexplore.exe)你不能夠再次注冊該DLL庫了。事實(shí)上,當(dāng)regsvr32.exe試圖裝入DLL以激活函數(shù)DllRegisterServer()時(shí),該調(diào)用將被放棄。八、與Web瀏覽器取得聯(lián)系GetinTouchwithWebBrowserSetSite()方法正是BHO對象被初始化的地方,此外,在這個(gè)方法中你可以執(zhí)行所有

28、的僅僅允許發(fā)生一次的任務(wù)。當(dāng)你用InternetExplorer打開一個(gè)URL時(shí),你應(yīng)該等待一系列的事件以確保要求的文檔已完全下載并被初始化。唯有在此時(shí),你才可以通過對象模型暴露的接口(如果存在的話)存取文檔內(nèi)容。這就是說你要取得一系列的指針。第一個(gè)就是指向IWebBrowser2(該接口用來生成WebBrowser對象)的指針。第二個(gè)指針與事件有關(guān)。該模塊必須作為一個(gè)瀏覽器的事件偵聽器來實(shí)現(xiàn),目的是為接收下載以及與文檔相關(guān)的事件。下面用ATL靈敏指針加以封裝:CComQIPtrm_spWebBrowser2;CComQIPtrm_spCPC;源代碼部分如下所示:HRESULTCViewSou

29、rce:SetSite(IUnknown*pUnkSite)/檢索并存儲(chǔ)IWebBrowser2指針m_spWebBrowser2=pUnkSite;if(m_spWebBrowser2=NULL)returnE_INVALIDARG;/檢索并存儲(chǔ)IConnectionPointerContainer指針m_spCPC=m_spWebBrowser2;if(m_spCPC=NULL)returnE_POINTER;/檢索并存儲(chǔ)瀏覽器的句柄HWND.并且安裝一個(gè)鍵盤鉤子備后用RetrieveBrowserWindow();/為接受事件通知連接到容器returnConnect();為了取得IWeb

30、Browser2接口指針,你可以進(jìn)行查詢。當(dāng)然也可以在事件剛剛發(fā)生時(shí)查詢IConnectionPointContainer。這里,SetSite()檢索了瀏覽器的句柄HWND,并且在當(dāng)前線程中安裝了一個(gè)鍵盤鉤子。HWND用于后面InternetExplorer窗口的移動(dòng)或尺寸調(diào)整。這里的鉤子用來實(shí)現(xiàn)熱鍵功能,用戶可以按動(dòng)熱鍵來顯示/隱藏代碼窗口。九、從InternetExplorer瀏覽器取得事件GettingEventsfromtheBrowser當(dāng)你導(dǎo)向一個(gè)新的URL時(shí),瀏覽器最需要完成的是兩種事件:下載文檔并為之準(zhǔn)備HOST環(huán)境。也就是說,它必須初始化某對象并使該對象從外部可以利用。針對

31、不同的文檔類型,或者裝入一個(gè)已注冊的MicrosoftActiveX?服務(wù)器來處理該文檔(如Word對于.doc文件的處理)或者初始化一些內(nèi)部組件來分析文檔內(nèi)容并生成和顯示該文檔。對于HTML網(wǎng)頁就是這樣,其內(nèi)容由于DHTML對象作用而變得可用。當(dāng)文檔全部下載結(jié)束,DownloadComplete事件被激活。這并不是說,這樣利用對象模型就可以安全地管理文檔的內(nèi)容了。事實(shí)上,DocumentComplete事件僅指明一切已經(jīng)結(jié)束,文檔已準(zhǔn)備好了(注意DocumentComplete事件僅在你第一次存取URL時(shí)到達(dá),如果你執(zhí)行了刷新動(dòng)作,你僅僅收到一個(gè)DocumentComplete事件)。為了截

32、獲瀏覽器發(fā)出的事件,BHO需要通過IConnectionPoint接口連接到瀏覽器上并且實(shí)現(xiàn)傳遞接口IDispatch指針以處理各種事件?,F(xiàn)在利用前面取得的IConnectionPointContainer指針來調(diào)用FindConnectionPoint方法它返回一個(gè)指針指向連接點(diǎn)對象(正是通過這個(gè)連接點(diǎn)對象來取得要求的外向接口,此時(shí)是DIID_DWebBrowserEvent2)。下列代碼顯示了連接點(diǎn)的發(fā)生情況:HRESULTCViewSource:Connect(void)HRESULThr;CComPtrspCP;為Web瀏覽器事件而接收(receive)連接點(diǎn)hr=m_spCPC-Fi

33、ndConnectionPoint(DIID_DWebBrowserEvent2,&spCP);if(FAILED(hr)returnhr;/把事件處理器傳遞到容器。每次事件發(fā)生容器都將激活我們實(shí)現(xiàn)的IDispatch接口上的相應(yīng)的函數(shù)。hr=spCP-Advise(reinterpret_cast(this),&m_dwCookie);returnhr;通過調(diào)用接口IConnectionPoint的Advise()方法,BHO告訴瀏覽器它對它產(chǎn)生的事件很感興趣。由于COM事件處理機(jī)制,所有這些意味著BHO把IDispatch接口指針提供給瀏覽器。瀏覽器將回調(diào)IDispatch接口的Invok

34、e()方法,以事件的ID值作為第一參數(shù):HRESULTCViewSource:Invoke(DISPIDdispidMember,REFIIDriid,LCIDlcid,WORDwFlags,DISPPARAMS*pDispParams,VARIANT*pvarResult,EXCEPINFO*pExcepInfo,UINT*puArgErr)if(dispidMember=DISPID_DOCUMENTCOMPLETE)OnDocumentComplete();m_bDocumentCompleted=true;切記,當(dāng)事件不再需要時(shí),應(yīng)該使之與瀏覽器分離。如果你忘記了做這件事情,BHO對象

35、將被鎖定,即使在你關(guān)閉瀏覽器窗口之后。很明顯,實(shí)現(xiàn)分離的最佳時(shí)機(jī)是收到O事件lit時(shí)。十、存取文檔對象AccessingtheDocumentObject此時(shí),該BHO已經(jīng)有一個(gè)參照指向InternetExplorer的Web瀏覽器控件并被連接到瀏覽器控件以接收所有它產(chǎn)生的事件。當(dāng)網(wǎng)頁被全部下載并正確初始化后,我們就可以通過DHTML文檔模型存取它。Web瀏覽器的文檔屬性返回一個(gè)指向文檔對象的IDispatch接口的指針:CComPtrpDisp;HRESULThr=m_spWebBrowser2-get_Document(&pDisp);get_Document()方法取得的僅僅是一個(gè)接口指

36、針。我們要進(jìn)一步確定在IDispatch指針背后存在一個(gè)HTML文檔對象。用VB實(shí)現(xiàn)的話,可以用下面代碼:DimdocAsObjectSetdoc=WebBrowser1.DocumentIfTypeName(doc)=HTMLDocumentThen獲取文檔內(nèi)容并予以顯示ElseDisablethedisplaydialogEndIf現(xiàn)在要了解一下get_Document()返回的IDispatch指針。InternetExplorer不僅僅是一個(gè)HTML瀏覽器,而且還是一個(gè)ActiveX文檔容器。這樣一來,難以保證當(dāng)前瀏覽對象就是一個(gè)HTML文檔。不過辦法還是有的你想,如果IDispatc

37、h指針真正指向一個(gè)HTML文檔,查詢IHTMLDocument2接口一定成功。IHTMLDocument2接口包裝了DHTML對象模型用來展現(xiàn)HTML頁面的所有功能。下面代碼實(shí)現(xiàn)這些功能:CComPtrpDisp;HRESULThr=m_spWebBrowser2-get_Document(&pDisp);CComQIPtrspHTML;spHTML=pDisp;if(spHTML)/獲取文檔內(nèi)容并予以顯示else/disabletheCodeWindowcontrols如果IHTMLDocument2接口查詢失敗,spHTML指針將是NULL。現(xiàn)在考慮如何獲得當(dāng)前顯示窗口的源代碼。正如一個(gè)H

38、TML頁把它所有的內(nèi)容封裝在標(biāo)簽中,DHTML對象模型要求你取得一個(gè)指向Body對象的指針:CComPtrm_pBody;hr=spHTML-get_body(&m_pBody);奇怪的是,DHTML對象模型不讓你取得標(biāo)簽之前的原始內(nèi)容,如。其內(nèi)容被處理并存于一些屬性中,但你還是不能從HTML原始文件中提取這部分的RAW文本。這過,僅從BODY部分取得的內(nèi)容足夠了。為了取得包含在.間的HTML代碼部分,可以把outerHTML屬性內(nèi)容讀取到一個(gè)BSTR變量中:BSTRbstrHTMLText;hr=m_pBody-get_outerHTML(&bstrHTMLText);在此基礎(chǔ)上,在代碼窗口

39、中顯示源碼就是一種簡單的事情了:生成一個(gè)窗口,進(jìn)行字符的UNICODE至ANSI轉(zhuǎn)化和設(shè)置編輯框控件的問題。下面代碼實(shí)現(xiàn)這些功能:HRESULTCViewSource:GetDocumentContent()USES_CONVERSION;/獲取WebBrowser的文檔對象CComPtrpDisp;HRESULThr=m_spWebBrowser2-get_Document(&pDisp);if(FAILED(hr)returnhr;/確保我們?nèi)〉玫氖且粋€(gè)IHTMLDocument2接口指針/讓我們查詢一下IHTMLDocument2接口(使用靈敏指針)CComQIPtrspHTML;spH

40、TML=pDisp;/抽取文檔源代碼if(spHTML)/取得BODY對象hr=spHTML-get_body(&m_pBody);if(FAILED(hr)returnhr;/取得HTML文本BSTRbstrHTMLText;hr=m_pBody-get_outerHTML(&bstrHTMLText);if(FAILED(hr)returnhr;/進(jìn)行文本的Unicode到ANSI的轉(zhuǎn)換LPTSTRpsz=newTCHARSysStringLen(bstrHTMLText);lstrcpy(psz,OLE2T(bstrHTMLText);/文本進(jìn)行相應(yīng)的調(diào)整HWNDhwnd=m_dlgCo

41、de.GetDlgItem(IDC_TEXT);EnableWindow(hwnd,true);hwnd=m_dlgCode.GetDlgItem(IDC_APPLY);EnableWindow(hwnd,true);/設(shè)置代碼窗口中的文本m_dlgCode.SetDlgItemText(IDC_TEXT,psz);deletepsz;else/文檔不是一個(gè)HTML頁m_dlgCode.SetDlgItemText(IDC_TEXT,);HWNDhwnd=m_dlgCode.GetDlgItem(IDC_TEXT);EnableWindow(hwnd,false);hwnd=m_dlgCode

42、.GetDlgItem(IDC_APPLY);EnableWindow(hwnd,false);returnS_OK;因?yàn)槲乙\(yùn)行這段代碼來響應(yīng)DocumentComplete事件通知,每個(gè)新的頁自動(dòng)地而且敏捷地被處理。DHTML對象模型使你能夠隨意修改網(wǎng)頁的結(jié)構(gòu),但這一變化在按F5刷新后全部復(fù)原。你還要處理一下DownloadComplete事件以刷新代碼窗口(注意,DownloadComplete事件發(fā)生在DocumentComplete事件之前)。你應(yīng)該忽略網(wǎng)頁的首次DownloadComplete事件,而是在執(zhí)行刷新動(dòng)作時(shí)才關(guān)注這一事件。布爾成員變量m_bDocumentComplet

43、ed正是用來區(qū)別這兩種情形的。十一、管理代碼窗口ManagingtheCodeWindow用來顯示當(dāng)前HTML頁原始碼的代碼窗口涉及另外一個(gè)ATL基本編程問題-對話框窗口,它位于ATL對象向?qū)У腗iscellaneous選項(xiàng)卡下。我調(diào)整了代碼窗口的大小來響應(yīng)WM_INITDIALOG消息,使它占居桌面空間的下部區(qū)域,正好是在任務(wù)欄的上面。在瀏覽器啟動(dòng)時(shí)你可以選擇顯示或不顯示這個(gè)窗口。缺省情況下是顯示的,但這可以通過清除Showwindowatstartup復(fù)選框項(xiàng)來實(shí)現(xiàn)。當(dāng)然喜歡的話,你可以隨時(shí)關(guān)閉。按鍵F12即可重新顯示代碼窗口。F12是通過在SetSite()中安裝的鍵盤鉤子實(shí)現(xiàn)的。啟動(dòng)環(huán)

44、境存于WINDOWS注冊表中,我選擇外殼庫文件shlwapi.dll中函數(shù)SHGetValue來實(shí)現(xiàn)注冊表的讀寫操作。這同使用Reg開頭的Win32函數(shù)操作相比,簡單極了。請看:DWORDdwType,dwVal;DWORDdwSize=sizeof(DWORD);SHGetValue(HKEY_CURRENT_USER,_T(SoftwareMSDNBHO),_T(ShowWindowAtStartup),&dwType,&dwVal,&dwSize);這個(gè)DLL文件是同InternetExplorer4.0和活動(dòng)桌面的誕生一起產(chǎn)生的,是WIN98及以后版本的標(biāo)準(zhǔn)組成,你可以放心使用。Sum

45、mary:DescribeshowtouseBHOstocustomizeyourbrowser.(16printedpages)Covers:十二、注冊BHO對象RegistrationofHelperObjects因?yàn)锽HO是一個(gè)COM服務(wù)器,所以既應(yīng)該作為COM服務(wù)器注冊又應(yīng)該作為BHO對象注冊。ATL向?qū)ё詣?dòng)生成.rgs文件,第一種情況的注冊就免除了。下面的文件代碼段是用來實(shí)現(xiàn)作為BHO對象注冊的(CLSID為例中生成)。HKLMSOFTWAREMicrosoftWindowsCurrentVersionExplorerBHOForceRemove1E1B2879-88FF-11D2-

46、8D96-D7ACAC95951F注意ForceRemove詞能夠?qū)崿F(xiàn)在卸載對象時(shí)刪除這一行相應(yīng)的鍵值。BHO鍵下聚集了所有的BHO對象。對于這么多的一串家伙是從來不作緩沖調(diào)用的。這樣以來,安裝與測試BHO就是不費(fèi)時(shí)的事情了。十三、總結(jié)Summary本文描述了BHO對象,通過它你可以把自己的代碼注入瀏覽器的地址空間中。你必須做的事情是寫一個(gè)支持IObjectWithSite接口的COM服務(wù)器。在這一點(diǎn)上,你的BHO對象可以實(shí)現(xiàn)瀏覽器機(jī)制范圍內(nèi)的各種合法目的。本文所及示例涉及了COM事件,DHTML對象模型以及WEB瀏覽器編程接口。雖然內(nèi)容稍寬一些,但它正顯示了現(xiàn)實(shí)世界中的BHO對象的應(yīng)用。女如

47、你想知道瀏覽器在顯示什么,那么您就需要了解接收事件并要熟悉WEB瀏覽器才行。另外:Windows資源管理器也是與BHO對象交互的,這一點(diǎn)在編程時(shí)要特別注意。本文所附源程序?yàn)镸SDN所帶,在Windows2000/VC6下調(diào)試通過(編譯通過后,重新啟動(dòng)IE即得到結(jié)果)。BrowserHelperObjects:TheBrowsertheWayYouWantItDinoEspositoMicrosoftCorporationJanuary1999April9,2004securityupdate:PleasealsoseeSecurityConsiderationsReusingthteoleaB

48、rnrmoorwesabeourtaddressingbrowsersecurityissues.IntroductionProgramCustomizationWhatAreBrowserHelperObjects?TheLifecycleofHelperObjectsTheIObjectWithSiteInterfaceWritingaBrowserHelperObjectDetectingWhosCallingGettinginTouchwithWebBrowserGettingEventsfromtheBrowserAccessingtheDocumentObjectManagingt

49、heCodeWindowRegistrationofHelperObjectsSummaryTherearesometimescircumstancesinwhichyouneedamoreorlessspecializedversionofthebrowser.SometimesyouworkaroundthisbydevelopingacompletelycustommodulebuiltontopoftheWebBrowsercontrol,completewithbuttons,labels,andwhateverelsetheuserinterfacerequires.Inthisc

50、ase,yourefreetoaddtothatbrowseranynew,nonstandardfeatureyouwant.Butwhatyouactuallyhaveisjustanew,nonstandardbrowser.TheWebBrowsercontrolisjusttheparsingengineofthebrowser.ThismeanstherestillremainsanumberofUI-relatedtasksforyoutodo:addinganaddressbar,toolbar,history,statusbar,channels,andfavorites,j

51、usttonameafew.So,tocreateacustombrowseryouhavetowritetwotypesofcode:thecodethattransformstheWebBrowsercontrolintoafull-fledgedbrowserlikeMicrosoftInternetExplorer,andthecodethatimplementsthenewfeaturesyouwantittosupport.WouldntitbeniceiftherewasastraightforwardwaytocustomizeInternetExplorerinstead?B

52、rowserHelperObjects(BHO)dojustthat.ProgramCustomization(關(guān)于軟件定制)Historicallyspeaking,thefirstwaytocustomizethebehaviorofaprogramwasthroughsubclassing.Bythismeans,youcouldchangethewayagivenwindowinaprogramprocessedmessagesandactuallyobtainadifferentbehavior.Althoughconsideredabrute-forceapproach,becau

53、sethevictimislargelyunawareofwhathappens,itsbeentheonlychoiceforalongtime.WiththeadventoftheMicrosoftWin32API,interprocesssubclassingwasdiscouragedandmadeabithardertocode.Ifyourebrave-hearted,however,pointershaveneverscaredyou;aboveall,ifyoureusedtolivinginsymbiosiswithsystem-widehooks,youmightevenf

54、indittoosimple.Butthisisnotalwaysthecase.Despitetheclevernessoftheprogramming,thepointisthateachWin32processrunsinitsownaddressspaceandbreakingtheprocessboundariesissomewhatincorrect.Ontheotherhand,theremightbecircumstancesthatrequireyoutodothiswiththebestofintentions.Moreoften,customizationmightbea

55、specificfeaturetheprogramitselfallowsbydesign.Inthelattercase,theprogramssearchforadditionalmodulesinwell-knownandprefixeddiskzones,load,initialize,andthenleavethemfreetodothejobtheyhavebeendesignedtodo.ThisisexactlywhathappenswiththeInternetExplorerbrowseranditshelperobjects.WhatAreBrowserHelperObj

56、ects?(什么是bho?)Fromthispointofview,InternetExplorerisjustlikeanyotherWin32-basedprogramwithitsownmemoryspacetopreserve.WithBrowserHelperObjectsyoucanwritecomponentsspecifically,in-processComponentObjectModel(COM)componentsthatInternetExplorerwillloadeachtimeitstartsup.Suchobjectsruninthesamememorycon

57、textasthebrowserandcanperformanyactionontheavailablewindowsandmodules.Forexample,aBHOcoulddetectthebrowserstypicalevents,suchasGoBack,GoForward,andDocumentComplete;accessthebrowsersmenuandtoolbarandmakechanges;createwindowstodisplayadditionalinformationonthecurrentlyviewedpage;andinstallhookstomonit

58、ormessagesandactions.Beforegoinganyfurtherwiththenitty-grittydetailsofBHO,thereareacoupleofpointsIneedtoilluminatefurther.First,theBHOistiedtothebrowsersmainwindow.Inpractice,thismeansanewinstanceoftheobjectiscreatedassoonasanewbrowserwindowiscreated.AnyinstanceoftheBHOlivesanddieswiththebrowsersins

59、tance.Second,BHOsonlyexistinInternetExplorer,version4.0andlater.IfyourerunningtheMicrosoftWindows98,Windows2000,Windows95,orWindowsNTversion4.0operatingsystemwiththeActiveDesktopShellUpdate(shellversion4.71),BHOsaresupportedalsobyWindowsExplorer.ThishassomeimplicationsthatIlltalkmoreaboutlaterwhenma

60、kingperformanceconsiderationsandevaluatingtheimpactofBHOs.Initssimplestform,aBHOisaCOMin-processserverregisteredunderacertainregistryskey.Uponstartup,InternetExplorerlooksupthatkeyandloadsalltheobjectswhoseCLSIDisstoredthere.Thebrowserinitializestheobjectandasksitforacertaininterface.Ifthatinterface

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論