一直以来,已经写过几个BHO控件,一段时间之后发现,只是记得大概流程,但是由于时间太长,已经不太能记得细节了,所以第二次写的时候就有些困难,明明已经正确生成,但是就是不能再加载项中发现,对于已经接触过的技术,实在是汗颜,于是决心记录下该项技术,以备不时之需

       首先建立一个ATL项目

       

BHO的创建-Window7 VS2010_BHO

     下一步,直接完成即可

  

BHO的创建-Window7 VS2010_成员函数_02

     其次呢,就是添加一个ATL简单对象,如下图所示

BHO的创建-Window7 VS2010_成员函数_03

   然后呢,就是添加ATL简单对象的过程

   

BHO的创建-Window7 VS2010_ci_04

    下一步,如下图所示

   

BHO的创建-Window7 VS2010_ci_05

    只需要填入简称,其他就会自动填好,这样就好,然后点击下一步,->下一步

BHO的创建-Window7 VS2010_ci_06

需要注意的就是支持那一栏IObjectWithSite一定要勾上!!!

然后呢,就是创建类的成员变量和类的成员函数

STDMETHOD(SetSite)(IUnknown*p);
CComQIPtr<IWebBrowser2,&IID_IWebBrowser2>m_spWebBrowser;
HRESULT Connecnt(BOOL);
DWORD m_cookie;
STDMETHODIMP Invoke(DISPID dispidMember,REFIID riid, LCID lcid,
WORD wFlags, DISPPARAMS * pDispParams,
VARIANT * pvarResult,EXCEPINFO * pexcepinfo,
UINT * puArgErr);


其实,SetSite是IObjectWithSite接口的成员函数,然后呢,我们要将其记录下来,也就是IE浏览器的指针。然后再EyeOIE的cpp文件中写入如下代码

STDMETHODIMP CEyeOnIE::SetSite(IUnknown*pSite)
{
m_spWebBrowser=pSite;
if(m_spWebBrowser==NULL)
{
return E_INVALIDARG;
}
return Connecnt(true);
}
HRESULT CEyeOnIE::Connecnt(BOOL pB)
{
CComPtr<IConnectionPoint>spPC;
CComQIPtr<IConnectionPointContainer,&IID_IConnectionPointContainer>spCPC(m_spWebBrowser);
HRESULT hr=spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2,&spPC);
if(FAILED(hr))
{
return hr;
}
if(pB)
{
hr=spPC->Advise(reinterpret_cast<IDispatch*>(this),&m_cookie);
}
else
{
hr=spPC->Unadvise(m_cookie);
}
return hr;
}
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)
{
case 250://DISPID_BEFORENAVIGATE2:
break;
case 252://DISPID_NAVIGATECOMPLETE2:
break;
case 259://DISPID_DOCUMENTCOMPLETE:
::MessageBoxA(NULL,"dada",0,0);
break;
default:
break;
}
return S_OK;
}


其实SetSite和Connect两个函数就是两个功能,一个是记录下IE浏览器的指针,然后呢就是,将浏览器指针强制类型转换,变成连接点管理器,然后,由得到的连接点管理器获得连接点,根据连接点,激活IE浏览器和BHO之间的通信,这样就完成了基本的操作,然后呢就是一些其他与BHO功能本身无关的代码了,但也是必须的

在dllmain.cpp文件中加入

if (dwReason == DLL_PROCESS_ATTACH)
{
TCHAR pszLoader[MAX_PATH];
//返回调用者模块的名称,第一个参数应为NULL,详见msdn。
GetModuleFileName(NULL, pszLoader, MAX_PATH);
_tcslwr(pszLoader);
if (_tcsstr(pszLoader, _T("explorer.exe")))
return FALSE;
}


这样就避免了文件管理器加载该BHO插件,然后呢就是寻找EyeOnIE.rgs文件中加入一个注册表输出

HKLM
{
SOFTWARE
{
Microsoft
{
Windows
{
CurrentVersion
{
Explorer
{
'Browser Helper Objects'
{
{851FBDE4-1953-4B58-AF94-5D072F1E9ED1}
}
}
}
}
}
}
}


上面加粗的内容呢就是该BHO的CLSID,该CLSID的定义在BhoPlugin.idl文件中,


BHO的创建-Window7 VS2010_ci_07

将该文件中的CLSID替换掉EyeOnIE.rgs文件中即可,这样BHO的创建就完成了!!!

PS:::::我在进行网页信息的获取时,有时会将网页中的内容就录下来,想放在txt文档中,但是呢,代码是正确的,就是不执行,经过一系列的文件查找,发现必须使用管理员权限运行IE浏览器,才能执行,对于遇到同样问题的童鞋,予以提醒