第三步,实现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删掉。           
     
  说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。 
  2/2   首页 上一页 1 2  |