創建一個BHO


  BHO(Browser Helper Object,瀏覽器輔助對象,簡稱BHO)
  BHO是微軟推出的作為瀏覽器對第三方程序員開放交互接口的業界標准,通過簡單的代碼就可以進入瀏覽器領域的“交互接口”(INTERACTIVED Interface)。通過這個接口,程序員可以編寫代碼獲取瀏覽器的行為,比如“后退”、“前進”、“當前頁面”等,利用BHO的交互特性,程序員還可以用代碼控制瀏覽器行為,比如修改替換瀏覽器工具欄,添加自己的程序按鈕等。

     --------------引自百度百科 BHO

在vs中創建一個BHO(使用C++),需要以下步驟:

1.新建一個ATL工程,起名為BHODemo

2.工程新建好之后,切換到類視圖,新加一個ATL簡單對象MyBHO,按照向導所示,添加過程中選中支持IObjectWithSite

3.可以看到,生成了一個接口實現類CMyBHO,在其中添加一個繼承的父類:public  IDispEventImpl<1 ,CMyBHO,&DIID_DWebBrowserEvents2,&LIBID_SHDocVw,1 ,1 > 和兩個方法

STDMETHOD(SetSite)(IUnknown * pUnkSite);  // 覆蓋父類IObjectWithSiteImpl的方法
void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* pDisp, VARIANT* URL);//文檔加載完成時的動作

4.添加事件接收器部分:

BEGIN_SINK_MAP(CMyBHO)
    SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
END_SINK_MAP()

此時第一個參數1,要和IDispEventImpl后面參數中的1的數值要保持一致.這樣DISPID_DOCUMENTCOMPLETE消息由IE傳過來到BHO時,才會調用對應的OnDocumentComplete.可以繼承多IDispEventImpl的,但要保證里面第一個參數,即序號不一樣.

5.實現SetSite和OnDocumentComplete

由於暫時還不做更多操作,所以SetSite實現直接調用IObjectWithSiteImpl<CMyBHO>::SetSite(pUnkSite);而OnDocumentComplete先放空.

現在的源文件應該是長這個樣子的:

   1:  // MyBHO.h : CMyBHO 的聲明
   2:   
   3:  #pragma once
   4:  #include "resource.h"       // 主符號
   5:  #include "ExDispid.h"
   6:   
   7:  #include "BHODemo_i.h"
   8:   
   9:  #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
  10:  #error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上無法正確支持單線程 COM 對象。定義 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可強制 ATL 支持創建單線程 COM 對象實現並允許使用其單線程 COM 對象實現。rgs 文件中的線程模型已被設置為“Free”,原因是該模型是非 DCOM Windows CE 平台支持的唯一線程模型。"
  11:  #endif
  12:   
  13:  using namespace ATL;
  14:   
  15:  // CMyBHO
  16:   
  17:  class ATL_NO_VTABLE CMyBHO :
  18:      public CComObjectRootEx<CComSingleThreadModel>,
  19:      public CComCoClass<CMyBHO, &CLSID_MyBHO>,
  20:      public IObjectWithSiteImpl<CMyBHO>,
  21:      public IDispatchImpl<IMyBHO, &IID_IMyBHO, &LIBID_BHODemoLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
  22:      public  IDispEventImpl<1 ,CMyBHO,&DIID_DWebBrowserEvents2,&LIBID_SHDocVw,1 ,1 > 
  23:  {
  24:  public:
  25:      CMyBHO()
  26:      {
  27:      }
  28:   
  29:  DECLARE_REGISTRY_RESOURCEID(IDR_MYBHO)
  30:   
  31:  BEGIN_COM_MAP(CMyBHO)
  32:      COM_INTERFACE_ENTRY(IMyBHO)
  33:      COM_INTERFACE_ENTRY(IDispatch)
  34:      COM_INTERFACE_ENTRY(IObjectWithSite)
  35:  END_COM_MAP()
  36:   
  37:      //路由表
  38:      BEGIN_SINK_MAP(CMyBHO)
  39:          SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
  40:      END_SINK_MAP()
  41:   
  42:      DECLARE_PROTECT_FINAL_CONSTRUCT()
  43:   
  44:      HRESULT FinalConstruct()
  45:      {
  46:          return S_OK;
  47:      }
  48:   
  49:      void FinalRelease()
  50:      {
  51:      }
  52:   
  53:  public:
  54:      STDMETHOD(SetSite)(IUnknown * pUnkSite);  // 覆蓋父類IObjectWithSiteImpl的方法
  55:      void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* pDisp, VARIANT* URL);//文檔加載完成時的動作
  56:  };
  57:   
  58:  OBJECT_ENTRY_AUTO(__uuidof(MyBHO), CMyBHO)

 

cpp文件應該是這樣:

   1:  // MyBHO.cpp : CMyBHO 的實現
   2:   
   3:  #include "stdafx.h"
   4:  #include "MyBHO.h"
   5:   
   6:   
   7:  // CMyBHO
   8:  // 覆蓋父類IObjectWithSiteImpl的方法
   9:  STDMETHODIMP CMyBHO::SetSite(IUnknown * pUnkSite)
  10:  {
  11:      //調用基類實現。
  12:      return IObjectWithSiteImpl<CMyBHO>::SetSite(pUnkSite);
  13:  }  
  14:  void STDMETHODCALLTYPE CMyBHO::OnDocumentComplete(IDispatch* pDisp, VARIANT* URL)//文檔加載完成時的動作
  15:  {
  16:  }

 

6.注冊表文件

修改BHODemo.rgs文件,刪除原先內容,改為:

HKLM
{
    NoRemove SOFTWARE
    {
        NoRemove Microsoft
        {
            NoRemove Windows
            {
                NoRemove CurrentVersion
                {
                    NoRemove Explorer
                    {
                        NoRemove 'Browser Helper Objects'
                        {
                            ForceRemove {E3C599B7-EB1D-462B-9ED8-D3924EF51BE9} = s 'BHO Demo Class'
                            {
                                val NoExplorer = d '1'
                            }
                        }
                    }
                }
            }
        }
    }
}
其中ForceRemove 后面的值是抄的idl文件中MyBHO的GUID的值.
7.編譯,然后打開IE就能看到是否啟用BHODemo的提示了.win7下編譯可能會出錯,提示權限問題.這個時候,需要以管理員權限運行vs才行的.
XN_SQ@{YD2G0HVW[I`PXI9H
卸載:直接去工程debug目錄中regsvr32 /u BHODemo.dll就行了.同樣要注意win7下的權限問題.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM