zoukankan      html  css  js  c++  java
  • 创建一个BHO

      BHO(Browser Helper Object,浏览器辅助对象,简称BHO)
      BHO是微软推出的作为浏览器对第三方程序员开放交互接口的业界标准,通过简单的代码就可以进入浏览器领域的“交互接口”(INTERACTIVED Interface)。通过这个接口,程序员可以编写代码获取浏览器的行为,比如“后退”、“前进”、“当前页面”等,利用BHO的交互特性,程序员还可以用代码控制浏览器行为,比如修改替换浏览器工具栏,添加自己的程序按钮等。

         --------------引自百度百科 BHO

    在vs中创建一个BHO(使用C++),需要以下步骤:

    1.新建一个ATL工程,起名为BHODemo

    2.工程新建好之后,切换到类视图,新加一个ATL简单对象MyBHO,按照向导所示,添加过程中选中支持IObjectWithSite

    3.可以看到,生成了一个接口实现类CMyBHO,在其中添加一个继承的父类:public  IDispEventImpl<1 ,CMyBHO,&DIID_DWebBrowserEvents2,&LIBID_SHDocVw,1 ,1 > 和两个方法

    STDMETHOD(SetSite)(IUnknown * pUnkSite);  // 覆盖父类IObjectWithSiteImpl的方法
    void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* pDisp, VARIANT* URL);//文档加载完成时的动作

    4.添加事件接收器部分:

    BEGIN_SINK_MAP(CMyBHO)
        SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
    END_SINK_MAP()

    此时第一个参数1,要和IDispEventImpl后面参数中的1的数值要保持一致.这样DISPID_DOCUMENTCOMPLETE消息由IE传过来到BHO时,才会调用对应的OnDocumentComplete.可以继承多IDispEventImpl的,但要保证里面第一个参数,即序号不一样.

    5.实现SetSite和OnDocumentComplete

    由于暂时还不做更多操作,所以SetSite实现直接调用IObjectWithSiteImpl<CMyBHO>::SetSite(pUnkSite);而OnDocumentComplete先放空.

    现在的源文件应该是长这个样子的:

       1:  // MyBHO.h : CMyBHO 的声明
       2:   
       3:  #pragma once
       4:  #include "resource.h"       // 主符号
       5:  #include "ExDispid.h"
       6:   
       7:  #include "BHODemo_i.h"
       8:   
       9:  #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
      10:  #error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
      11:  #endif
      12:   
      13:  using namespace ATL;
      14:   
      15:  // CMyBHO
      16:   
      17:  class ATL_NO_VTABLE CMyBHO :
      18:      public CComObjectRootEx<CComSingleThreadModel>,
      19:      public CComCoClass<CMyBHO, &CLSID_MyBHO>,
      20:      public IObjectWithSiteImpl<CMyBHO>,
      21:      public IDispatchImpl<IMyBHO, &IID_IMyBHO, &LIBID_BHODemoLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
      22:      public  IDispEventImpl<1 ,CMyBHO,&DIID_DWebBrowserEvents2,&LIBID_SHDocVw,1 ,1 > 
      23:  {
      24:  public:
      25:      CMyBHO()
      26:      {
      27:      }
      28:   
      29:  DECLARE_REGISTRY_RESOURCEID(IDR_MYBHO)
      30:   
      31:  BEGIN_COM_MAP(CMyBHO)
      32:      COM_INTERFACE_ENTRY(IMyBHO)
      33:      COM_INTERFACE_ENTRY(IDispatch)
      34:      COM_INTERFACE_ENTRY(IObjectWithSite)
      35:  END_COM_MAP()
      36:   
      37:      //路由表
      38:      BEGIN_SINK_MAP(CMyBHO)
      39:          SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
      40:      END_SINK_MAP()
      41:   
      42:      DECLARE_PROTECT_FINAL_CONSTRUCT()
      43:   
      44:      HRESULT FinalConstruct()
      45:      {
      46:          return S_OK;
      47:      }
      48:   
      49:      void FinalRelease()
      50:      {
      51:      }
      52:   
      53:  public:
      54:      STDMETHOD(SetSite)(IUnknown * pUnkSite);  // 覆盖父类IObjectWithSiteImpl的方法
      55:      void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* pDisp, VARIANT* URL);//文档加载完成时的动作
      56:  };
      57:   
      58:  OBJECT_ENTRY_AUTO(__uuidof(MyBHO), CMyBHO)

    cpp文件应该是这样:

       1:  // MyBHO.cpp : CMyBHO 的实现
       2:   
       3:  #include "stdafx.h"
       4:  #include "MyBHO.h"
       5:   
       6:   
       7:  // CMyBHO
       8:  // 覆盖父类IObjectWithSiteImpl的方法
       9:  STDMETHODIMP CMyBHO::SetSite(IUnknown * pUnkSite)
      10:  {
      11:      //调用基类实现。
      12:      return IObjectWithSiteImpl<CMyBHO>::SetSite(pUnkSite);
      13:  }  
      14:  void STDMETHODCALLTYPE CMyBHO::OnDocumentComplete(IDispatch* pDisp, VARIANT* URL)//文档加载完成时的动作
      15:  {
      16:  }

    6.注册表文件

    修改BHODemo.rgs文件,删除原先内容,改为:

    HKLM
    {
        NoRemove SOFTWARE
        {
            NoRemove Microsoft
            {
                NoRemove Windows
                {
                    NoRemove CurrentVersion
                    {
                        NoRemove Explorer
                        {
                            NoRemove 'Browser Helper Objects'
                            {
                                ForceRemove {E3C599B7-EB1D-462B-9ED8-D3924EF51BE9} = s 'BHO Demo Class'
                                {
                                    val NoExplorer = d '1'
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    其中ForceRemove 后面的值是抄的idl文件中MyBHO的GUID的值.
    7.编译,然后打开IE就能看到是否启用BHODemo的提示了.win7下编译可能会出错,提示权限问题.这个时候,需要以管理员权限运行vs才行的.
    XN_SQ@{YD2G0HVW[I`PXI9H
    卸载:直接去工程debug目录中regsvr32 /u BHODemo.dll就行了.同样要注意win7下的权限问题.
  • 相关阅读:
    windows下 python2 和python3 共存
    利用xshell远程连接centos安装oracle11g时在图形界面登录
    本地导入/导出远程oracle数据库
    centos7安装桌面环境
    普通用户修改.bash_profile 权限问题
    centos7 安装oracle11g
    Unable to fetch some archives ,maybe run apt-get update or try with --fix-missing?
    spring mvc 使用ehcache
    leaflet创建简单地图
    【BZOJ 3958】 3958: [WF2011]Mummy Madness (二分+扫描线、线段树)
  • 原文地址:https://www.cnblogs.com/leipei2352/p/2763604.html
Copyright © 2011-2022 走看看