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; }
评论