VC++开发BHO插件(2)——定制你的浏览器

来源:百度文库 编辑:神马文学网 时间:2024/04/29 08:49:16
第三步,实现IDispatch接口方法。事件处理也就在IDispatch::Invoke中实现(各个事件的ID在ExDispID.h中定义)。BHO可能会接收到很多事件,但我们只需要响应我们感兴趣的那一部分。首先在EyeOnIE.h中增加该函数的声明,在EyeOnIE.cpp的实现中,笔者试着响应浏览器浏览一个地址之前发出的事件DISPID_BEFORENAVIGATE2,以此来实现简单的网址过滤功能,代码参考如下:

STDMETHODIMP CEyeOnIE::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, "girl.com"))
   {
    *pDispParams->rgvarg[0].pboolVal = TRUE;
    ::MessageBox(NULL, _T("该网页已被禁止!"),_T("Warning"),MB_ICONSTOP);
    return S_OK;
   }
   break;
  }

  case DISPID_NAVIGATECOMPLETE2:
   break;
  case DISPID_DOCUMENTCOMPLETE:
   break;
  case DISPID_DOWNLOADBEGIN:
   break;
  case DISPID_DOWNLOADCOMPLETE:
   break;
  case DISPID_NEWWINDOW2:
   break;
  case DISPID_QUIT:
   RegisterEventHandler(FALSE);
   break;
  default:
   break;
 }

 return S_OK;
}
  我们看到,当用户浏览的新地址包含"girl.com"字符的时候,浏览器就会弹出一个警告对话框,并且停止进一步的动作。另外值得注意的是,在DISPID_QUIT事件(浏览器将要退出)的响应中,我们将BHO事件处理器进行了注销。

  第四步,因为BHO可能会被文件浏览器加载。如果我们不想这样,我们就要在DllMain中对加载者进行判断,参考如下:

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
 if (dwReason == DLL_PROCESS_ATTACH)
 {
  // 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;

  _Module.Init(ObjectMap, hInstance, &LIBID_BHOPLUGINLib);
  DisableThreadLibraryCalls(hInstance);
 }
 else if (dwReason == DLL_PROCESS_DETACH)
  _Module.Term();
  return TRUE; // ok
}
  最后,别忘了修改注册表文件,追加BHO的注册信息。在EyeOnIE.rgs文件的下面增加如下代码:

HKLM
{
 SOFTWARE
 {
  Microsoft
  {
   Windows
   {
    CurrentVersion
    {
     Explorer
     {
      'Browser Helper Objects'
      {
       {6E28339B-7A2A-47B6-AEB2-46BA53782379}
      }
     }
    }
   }
  }
 }
}
  注意,{6E28339B-7A2A-47B6-AEB2-46BA53782379}是笔者这个BHO的CLSID,如果你自己开发BHO,这里应该正确填写你的CLSID。

  好了,一个简单的BHO开发完成了。(可以到本人的个人主页 http://hqtech.nease.net 下载实例源代码。)BHO插件可以实现的功能还有很多,比如网页内容分析、IE界面定制等等。作为总结,笔者还要提醒读者一点的是,如果不想让BHO起作用了,可以注销该插件,如下格式:regsvr32 /u yourpath\yourbho.dll,或者直接在注册表中将“Browser Helper Objects”目录下注册的CLSID删掉。