BHO入門

BHO(Browser Help Objects),是實現了特定接口的COM組件 開發好的BHO插件在註冊表特定的位置註冊好後,每當微軟的瀏覽器啓動,BHO實例就會被創建。在瀏覽器工作的工程中,BHO會接收到很多事件,

 

比如瀏覽器瀏覽新的地址、前進或後退、生成新的窗口、瀏覽器退出等等;BHO可以在這些事件的響應中實現與瀏覽器的交互。
下面,我們首先來介紹一下BHO的工作原理。上面我們已經提到,BHO是COM組件,而且一定實現了IObjectWithSite接口。這些組件除了在註冊表中註冊爲COM Server外,還必須將它們的CLSID在HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/ CurrentVersion/Explorer/Browser Helper Objects下注冊爲子鍵
微軟在設計瀏覽器的時候,已經給這些組件預留了空間。每當瀏覽器啓動時,瀏覽器會首先在上述註冊表位置查看是否有註冊的 BHO CLSID;如果有則分別創建一個實例,並對BHO實例進行初始化,建立交互連接。(注:BHO實例只有在創建它的瀏覽器窗口銷燬時才被釋放 。)

原理:

 

IE將自己的IUnKnown指針傳遞給BHO,BHO需要建立一個私有的基於COM的通訊通道,目的是響應IE事件。所以BHO最重要的是實現

 

IObjectWithSite 接口。IE 通過這個接口,傳遞自己的IUnknown接口,BHO存儲該接口,進一步通過調用IObjectWithSite 提供的方法。

 

  IE啓動時候會依次執行一些函數,把BHO自己的函數註冊到這裏,書面上稱之爲連接點 。這樣就能調用進入 BHO自己的程序內部了。IObjectWithSite 主要有兩個函數要實現:

  • HRESULT SetSite(IUnknown* pUnkSite)  接收ie瀏覽器的IUnknown指針。典型實現是保存該指針以備將來使用
  • HRESULT GetSite(REFIID riid, void** ppvSite)  從通過SetSite()方法設置的場所中接收並返回指定的接口,典型實現是查詢前面保 存的接口指針以進一步取得指定的接口

成功創建的BHO,不僅可以得到各種標準的瀏覽器操作事件,並做出響應;還可以定製瀏覽器的菜單、工具條等界面元素;更或者可以安裝鉤子函數,監視瀏覽器的一舉一動。值得注意的是,使用BHO插件,Internet瀏覽器要求在4.0以上版本;如果是文件瀏覽器 ,操作系統要求是Windows 95/98/2000或Window NT 4.0以上版本,並且Shell的版本在4.71以上。下面是支持BHO特性的系統一覽表:

 


Shell版本 操作系統版本 支持BHO
4.00 Windows 95 and Windows NT 4.0(IE版本爲 4.0) 僅IE4.0
4.71 Windows 95 and Windows NT 4.0(IE版本爲 4.0) IE和文件瀏覽器
4.72 Windows 98 IE和文件瀏覽器
5.00  Windows 2000 IE和文件瀏覽器

 

-----------------------------------------------------  GO!!!  -------------------------------------------------------


 

a) 首先啓動VC 2005 新建工程 ATL Project
   工程名字: HelloWorld
   Application Settings 中,Server type 選擇 Dynamic-link library (dll) 其他都不選。(簡單總結爲以atl 創建dll工程)

b) 其次在新建好的CLASS VIEW下選擇 工程 HelloWorld 右鍵 add -> class
   選擇創建ATL Simple Object ,下一步 在short name中輸入 HelloWorldBHO 其他都自動補齊不用管。
   下一步在options中 :

  •  Threading mode 選擇 Apartment ;
  •  Aggregation 選擇 no;
  •  Interface 選擇 Dual
  •  support 選擇 IObjectWithSite(IE object support)

點擊Finish ,這是一個最簡單的BHO已經創建好了。

c) 目前要做的就是添磚了
編輯 HelloWorldBHO.h 發現系統已經爲你創建了 CHelloWorldBHO類, 在類的最下行有一個public: 沒後文,這裏就是系統提示你要添加的代碼了。


    CHelloWorldBHO 中SetSite 已經爲你添加將瀏覽器的IUnknown 指針保存下來(見m_spUnkSite);


 現在要做的是註冊到連接點。
 


 

 繼承父類的 SetSite方法,顯示調用父類(SetSite)方法,添加一個註冊函數。(就是前面所述的,添加到連接點)
 

 

 其中成員聲明:

DWORD mCookie;   連接點註冊上去的索引,方便以後反註冊使用。
CComQIPtr<IWebBrowser2> m_spWebBrowser2;
m_spWebBrowser2 用來將瀏覽器IUnknown 指針轉變爲 IWebBrowser2 ,並保存方便後面使用。
我們可以看到將 IDispatch 接口註冊上去了。
查IDispatch 接口,主要核心在於實現 Invoke 函數。


上面是這次實例的範例代碼。有興趣的朋友可以照着敲下,下面還是講下這個函數裏面的一些點:
I.最佳反註冊時機
  case DISPID_QUIT:
      RegisterEventHandler(FALSE);
 在瀏覽器退出的時候,是最佳反註冊時機,不然可能瀏覽器退出後,你的BHO還在運行哦(有可能)
II. 有些宏需要引入頭文件
  #include <exdisp.h >
  #include <ExDispid.h>
III.當要使用ATL 編碼轉換時候在函數開頭引入 USES_CONVERSION; 宏,不過這裏如果沒有轉換應用,可以去掉。
  根據支持BHO特性,爲了不讓資源管理器加載該BHO,所以在dll main 函數里加入如下代碼判斷是否加載:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章