创建一个BHO
要创建一个BHO对象,你可以使用支持COM的任何开发语言。我用的是Microsoft Visual C++和ATL来创建一个IEHelper(BHO).
当被加载时,IEHelper创建一个窗口显示所有被IE浏览器触发的事件。IEHelper同样提供一个编辑控件(Edit Box)用来输入一个URL.在输入了URL之后,你可以点击导航按钮来访问你刚才输入的URL.你也可以点击前进和后退按钮在浏览器的历史页面中,向前或者后退。如下图所示:
为了创建一个BHO,首先要使用Visual C++的ATL COM 应用程序向导创建一个新的工程。如图所示:
一个BHO必须是一个DLL,因为它将被加载到跟IE相同的进程空间中。因此在ATL COM 应用程序向导的第一步中,选择动态连接库(DLL)作为服务类型,然后单击Finish按钮。在出现的新工程信息对话框中单击OK。
然后我们将会创建一个简单的ATL对象。在你的工程的类视图中,右键你的工程名并且选择新的 ATL对象。然后选择简单对象图标,如下图所示:
然后单击下一步按钮来打开ATL对象向导的属性对话框。
在Names标签页中,在ShortName中输入IEHlprObj,如下图所示。保留其他区域的默认值,然后点击OK按钮。
现在让我们把精力集中于在一个BHO中如何实现IObjectWithSite接口。
在完成了创建IEHlprObj简单的ATL对象之后,我们必须改变CIEHlprObj类默认的实现过程来实现IObjectWithSite接口。通过IObjectWithSite接口的SetSite方法,我们接收到一个IE的IWebBrowser2接口的一个指针。如果没有这个接口,你就不能够控制IE或者与IE进行通信。事实上,如果你没有实现这个接口,IE甚至不会加载你的BHO.
在ATL中实现IObjectWithSite接口是很容易的。只需要改变CIEHlprObj的申明,这样CIEHlprObj将从IObjectWithSiteImpl继承并且通过使用COM_INTERFACE_ENTRY_IMPL宏,增加IObjectWithSite到你的COM map中。下面的代码显示了CIEHlprObje改变后的申明和他的COM map.
// CIEHlprObj
class ATL_NO_VTABLE CIEHlprObj :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CIEHlprObj, &CLSID_IEHlprObj>,
public IObjectWithSiteImpl<CIEHlprObj>,
public IDispatchImpl<IIEHlprObj,
&IID_IIEHlprObj,
&LIBID_IEHELPERLib>
{
BEGIN_COM_MAP(CIEHlprObj)
COM_INTERFACE_ENTRY(IIEHlprObj)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_IMPL(IObjectWithSite)
END_COM_MAP()
};
接下来,你必须重写IObjectWithSite接口的SetSite方法。当IE加载BHO的时候,IE会调用你的IObjectWithSite::SetSite方法并且传送一个指针给IWebBrowser2接口。SetSite方法的实现过程是很简单的。所有你所需要做的仅仅是保存一份IWebBrowser2接口指针的拷贝,这样你能够在之后来使用他。在下面的代码中展示的这个过程跟拷贝IWebbrowser2接口指针到类的成员中或一个全局变量中一样简单。这段代码同样展示了SetSite方法的部分实现过程。
{
USES_CONVERSION;
HRESULT hr = E_FAIL;
if (!pUnkSite)
ATLTRACE(""nSetSite(): pUnkSite is NULL"n"n");
else
{
// Make sure Internet Explorer is the one calling SetSite
// by querying pUnkSite for the IWebBrowser2 interface.
//
m_spWebBrowser2 = pUnkSite;
if (!m_spWebBrowser2)
{
hr = E_FAIL;
}
else
{
}
}
return hr;
}