创建一个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方法的部分实现过程。

STDMETHODIMP CIEHlprObj::SetSite(IUnknown *pUnkSite)
{
   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;
}

posted on 2008-06-02 13:56  飞天名猪  阅读(2195)  评论(1编辑  收藏  举报