创建一个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下的权限问题.


本文转自leipei博客园博客,原文链接:http://www.cnblogs.com/leipei2352/archive/2012/11/10/2763604.html,如需转载请自行联系原作者

目录
相关文章
|
自然语言处理 安全 C++
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
8731 4
|
5月前
|
人工智能 运维 关系型数据库
|
9月前
|
敏捷开发 存储 数据可视化
团队效率翻倍!2024年最佳协作工具排行榜
在现代职场,高效管理团队任务和优化协作流程至关重要。传统方式已难以应对大规模团队的需求,而团队协作工具正改变这一局面。本文精选了2024年市场上表现突出的几款工具,包括板栗看板、Trello、Asana、Slack、ClickUp,从功能特点、易用性和性价比等方面进行全面解析,助力团队提升效率。这些工具不仅支持任务管理、进度跟踪,还提供即时沟通和文件共享功能,适用于远程办公、跨部门合作等场景。
360 4
|
编译器 Linux C语言
C/C++ 常见函数调用约定(__stdcall,__cdecl,__fastcall等):介绍常见函数调用约定的基本概念、用途和作用
C/C++ 常见函数调用约定(__stdcall,__cdecl,__fastcall等):介绍常见函数调用约定的基本概念、用途和作用
811 0
ly~
|
11月前
|
存储 安全 大数据
数据库的发展趋势是什么?
数据库发展趋势涵盖云化、智能化、分布式及多模型融合等多个方面。云数据库和DBaaS模式使企业能快速调整资源,降低成本;AI和机器学习技术推动智能运维、查询优化等功能;分布式架构和并行计算则提升了数据处理能力和速度。此外,多模型数据库满足了多样化的数据处理需求,而数据安全技术和隐私保护也在不断加强。数据库与大数据、AI、区块链等新兴技术的融合将进一步提升其功能与安全性。
ly~
874 1
|
11月前
|
NoSQL C语言 索引
十二个C语言新手编程时常犯的错误及解决方式
C语言初学者常遇错误包括语法错误、未初始化变量、数组越界、指针错误、函数声明与定义不匹配、忘记包含头文件、格式化字符串错误、忘记返回值、内存泄漏、逻辑错误、字符串未正确终止及递归无退出条件。解决方法涉及仔细检查代码、初始化变量、确保索引有效、正确使用指针与格式化字符串、包含必要头文件、使用调试工具跟踪逻辑、避免内存泄漏及确保递归有基准情况。利用调试器、编写注释及查阅资料也有助于提高编程效率。避免这些错误可使代码更稳定、高效。
1527 12
|
Java Maven Perl
解决Maven父子多模块打包互相引用打包:必须父模块才能打包成功,单个子模块无法打包成功问题(会提示找不到)
解决Maven父子多模块打包互相引用打包:必须父模块才能打包成功,单个子模块无法打包成功问题(会提示找不到)
1759 4
|
人工智能 Oracle jenkins
【Jenkins】新手安装、运行Jenkins(详细教学)
【Jenkins】新手安装、运行Jenkins(详细教学)
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的儿童影楼拍摄管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的儿童影楼拍摄管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
存储 JSON 关系型数据库
MySQL 8.0 功能特性
MySQL 作为最流行的开源关系型数据库管理系统之一,不断推陈出新,满足用户不断增长的需求和期望。在本篇博客中,我们将探讨 MySQL 8.0 版本带来的一些令人振奋的功能特性。
337 0