BHO(Browser Helper Object )简单介绍

来源:互联网 发布:阿里云自建网站 编辑:程序博客网 时间:2024/05/28 05:18

BHO原理:

BHO就是Browser Helper Object(浏览器辅助对象)

BHO关联原理 (BHO关联的是SHDOCVW,也就是说不只关联IE,下面全部用IE来说明)

    1.IE的窗口打开时,先寻找HKLM下的SOFTWARE/Microsoft/Windows/CurrentVersion/Explorer/Browser Helper Objects/ 里的CLSID,这些CLSID,都对应着相应的BHO插件,然后根据这个CLSID到HKCR下的CLSIDs里找到此插件的信息,包括文件位置等。

    2.IE根据找到的CLSID信息创建 BHO 对象,并且查找 IObjectWithSite 接口. (这个接口非常简单,只有SetSite和GetSite两个方法)

    3.IE把IWebBrowser2(浏览器插件)传到 BHO 的 SetSite 方法,用户在此方法中可挂载自己的事件处理方法。

    4.窗口关闭时,IE把 null 传到 BHO 的 SetSite 方法,此方法用来去掉挂载的事件处理方法。


编写BHO流程
1、创建IObjectWithSite显式接口,创建 COM 类型,实现继承IObjectWithSite接口
2、实现此接口并在SetSite方法里加上所要挂载的事件
3、处理事件
4、注册此BHO到注册表中HKLM下的Software//Microsoft//Windows//CurrentVersion//Explorer//Browser Helper Objects;(HKCR下的CLSIDs是根据上面的路径自动注册的)
5、.net 下须设置此BHO项目的 配置属性_>生成 中为Interop注册为True,这样才能将.net 类库文件注册到COM

  // Check who's loading us. 
  // If it's Explorer then "no thanks" and exit...
  TCHAR pszLoader[MAX_PATH];
  GetModuleFileName(NULL, pszLoader, MAX_PATH);
  _tcslwr(pszLoader);
  if (_tcsstr(pszLoader, _T("explorer.exe"))) 
   return FALSE;

        //setsite方法中的代码
 USES_CONVERSION;
 
 if (pUnkSite)
 {
  mWebBrowser2 = pUnkSite;
  if (mWebBrowser2)
  {
   return RegisterEventHandler(TRUE);
  }
 }


//下面是最重要的InVoke函数
//这个回调函数中应该加入自己的操作处理各种事件
Invoke(DISPID dispidMember,REFIID riid, LCID lcid, 
         WORD wFlags, DISPPARAMS * pDispParams, 
         VARIANT * pvarResult,EXCEPINFO * pexcepinfo, 
         UINT * puArgErr)

 USES_CONVERSION;

 if (!pDispParams)
  return E_INVALIDARG;
  
 switch (dispidMember)
 {
  //
  // The parameters for this DISPID are as follows:
  // [0]: Cancel flag  - VT_BYREF|VT_BOOL
  // [1]: HTTP headers - VT_BYREF|VT_VARIANT
  // [2]: Address of HTTP POST data  - VT_BYREF|VT_VARIANT 
  // [3]: Target frame name - VT_BYREF|VT_VARIANT 
  // [4]: Option flags - VT_BYREF|VT_VARIANT
  // [5]: URL to navigate to - VT_BYREF|VT_VARIANT
  // [6]: An object that evaluates to the top-level or frame
  //      WebBrowser object corresponding to the event. 
  //
 case DISPID_BEFORENAVIGATE2:    //在打开浏览页面之前的事件处理
 {
  LPOLESTR lpURL = NULL;
  mWebBrowser2->get_LocationURL(&lpURL);
  char * strurl;
  if (pDispParams->cArgs >= 5 && pDispParams->rgvarg[5].vt == (VT_BYREF|VT_VARIANT))
  {
            CComVariant varURL(*pDispParams->rgvarg[5].pvarVal);
            varURL.ChangeType(VT_BSTR);
   strurl = OLE2A(varURL.bstrVal);
  }
  if (strstr(strurl, "hebianyangliu.cn"))
  {
            *pDispParams->rgvarg[0].pboolVal = TRUE;
   ::MessageBox(NULL, _T("该网页已被禁止!"),_T("Forbidden!"),MB_ICONSTOP);
   return S_OK;
  }
  break;
 }

//这里定义的这些事件都是打开IE时会有的,这样你可以加上自己的处理方法,控制IE了

 case DISPID_NAVIGATECOMPLETE2:     //网页打开完毕
  break;
 case DISPID_DOCUMENTCOMPLETE:       //文档打开完毕 
  break;
 case DISPID_DOWNLOADBEGIN:          //下载开始 
  break;
 case DISPID_DOWNLOADCOMPLETE:       //下载完毕
  break;
 case DISPID_NEWWINDOW2:              //打开新窗口
     break;
        case DISPID_PROGRESSCHANGE:      // 进度条改变
                break;
        case DISPID_STATUSTEXTCHANGE:         // 状态天文字改变
                break;
         case DISPID_TITLECHANGE:            // 标题改变
                break;
 case DISPID_QUIT:                    //退出当前浏览页面
  RegisterEventHandler(FALSE);
  break;
 default:
  break;
 }

 return S_OK;
}

原创粉丝点击