C++开发BHO之HelloWorld

C++开发BHO之HelloWorld原文 http msdn microsoft com en us library bb v vs 85 aspx 开发工具 VS2010 步骤如图 生成的 HelloWor



原文:

步骤如图:

C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


C++开发BHO之HelloWorld


生成的HelloWorldBHO.h的代码如下:

[cpp] view plain copy print ?

  1. // HelloWorldBHO.h : CHelloWorldBHO 的声明  
  2.   
  3. #pragma once  
  4. #include “resource.h”       // 主符号  
  5.   
  6.   
  7.   
  8. #include “HelloWorld_i.h”  
  9.   
  10.   
  11.   
  12. #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)  
  13. #error “Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。”  
  14. #endif  
  15.   
  16. using namespace ATL;  
  17.   
  18.   
  19. // CHelloWorldBHO  
  20.   
  21. class ATL_NO_VTABLE CHelloWorldBHO :  
  22.     public CComObjectRootEx

    ,  
  23.     public CComCoClass

    ,  
  24.     public IObjectWithSiteImpl

    ,  
  25.     public IDispatchImpl

    /*wMajor =*/ 1, 
    /*wMinor =*/ 0>  
  26. {  
  27. public:  
  28.     CHelloWorldBHO()  
  29.     {  
  30.     }  
  31.   
  32. DECLARE_REGISTRY_RESOURCEID(IDR_HELLOWORLDBHO)  
  33.   
  34. DECLARE_NOT_AGGREGATABLE(CHelloWorldBHO)  
  35.   
  36. BEGIN_COM_MAP(CHelloWorldBHO)  
  37.     COM_INTERFACE_ENTRY(IHelloWorldBHO)  
  38.     COM_INTERFACE_ENTRY(IDispatch)  
  39.     COM_INTERFACE_ENTRY(IObjectWithSite)  
  40. END_COM_MAP()  
  41.   
  42.   
  43.   
  44.     DECLARE_PROTECT_FINAL_CONSTRUCT()  
  45.   
  46.     HRESULT FinalConstruct()  
  47.     {  
  48.         return S_OK;  
  49.     }  
  50.   
  51.     void FinalRelease()  
  52.     {  
  53.     }  
  54.   
  55. public:  
  56.   
  57.   
  58.   
  59. };  
  60.   
  61. OBJECT_ENTRY_AUTO(__uuidof(HelloWorldBHO), CHelloWorldBHO)  
// HelloWorldBHO.h : CHelloWorldBHO 的声明 #pragma once #include "resource.h" // 主符号 #include "HelloWorld_i.h" #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) #error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。" #endif using namespace ATL; // CHelloWorldBHO class ATL_NO_VTABLE CHelloWorldBHO : public CComObjectRootEx 
    
      , public CComCoClass 
     
       , public IObjectWithSiteImpl 
      
        , public IDispatchImpl 
       
         { public: CHelloWorldBHO() { } DECLARE_REGISTRY_RESOURCEID(IDR_HELLOWORLDBHO) DECLARE_NOT_AGGREGATABLE(CHelloWorldBHO) BEGIN_COM_MAP(CHelloWorldBHO) COM_INTERFACE_ENTRY(IHelloWorldBHO) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IObjectWithSite) END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } public: }; OBJECT_ENTRY_AUTO(__uuidof(HelloWorldBHO), CHelloWorldBHO) 
        
       
      
    

HelloWorldBHO.cpp的代码如下:

[cpp] view plain copy print ?

  1. // HelloWorldBHO.cpp : CHelloWorldBHO 的实现  
  2.   
  3. #include “stdafx.h”  
  4. #include “HelloWorldBHO.h”  
  5.   
  6.   
  7. // CHelloWorldBHO  
// HelloWorldBHO.cpp : CHelloWorldBHO 的实现 #include "stdafx.h" #include "HelloWorldBHO.h" // CHelloWorldBHO 

HelloWorld.cpp的代码如下:

[cpp] view plain copy print ?

  1. // HelloWorld.cpp : DLL 导出的实现。  
  2.   
  3.   
  4. #include “stdafx.h”  
  5. #include “resource.h”  
  6. #include “HelloWorld_i.h”  
  7. #include “dllmain.h”  
  8.   
  9.   
  10. // 用于确定 DLL 是否可由 OLE 卸载。  
  11. STDAPI DllCanUnloadNow(void)  
  12. {  
  13.             return _AtlModule.DllCanUnloadNow();  
  14.     }  
  15.   
  16. // 返回一个类工厂以创建所请求类型的对象。  
  17. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)  
  18. {  
  19.         return _AtlModule.DllGetClassObject(rclsid, riid, ppv);  
  20. }  
  21.   
  22. // DllRegisterServer – 在系统注册表中添加项。  
  23. STDAPI DllRegisterServer(void)  
  24. {  
  25.     // 注册对象、类型库和类型库中的所有接口  
  26.     HRESULT hr = _AtlModule.DllRegisterServer();  
  27.         return hr;  
  28. }  
  29.   
  30. // DllUnregisterServer – 在系统注册表中移除项。  
  31. STDAPI DllUnregisterServer(void)  
  32. {  
  33.     HRESULT hr = _AtlModule.DllUnregisterServer();  
  34.         return hr;  
  35. }  
  36.   
  37. // DllInstall – 按用户和计算机在系统注册表中逐一添加/移除项。  
  38. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)  
  39. {  
  40.     HRESULT hr = E_FAIL;  
  41.     static const wchar_t szUserSwitch[] = L“user”;  
  42.   
  43.     if (pszCmdLine != NULL)  
  44.     {  
  45.         if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0)  
  46.         {  
  47.             ATL::AtlSetPerUserRegistration(true);  
  48.         }  
  49.     }  
  50.   
  51.     if (bInstall)  
  52.     {     
  53.         hr = DllRegisterServer();  
  54.         if (FAILED(hr))  
  55.         {  
  56.             DllUnregisterServer();  
  57.         }  
  58.     }  
  59.     else  
  60.     {  
  61.         hr = DllUnregisterServer();  
  62.     }  
  63.   
  64.     return hr;  
  65. }  
// HelloWorld.cpp : DLL 导出的实现。 #include "stdafx.h" #include "resource.h" #include "HelloWorld_i.h" #include "dllmain.h" // 用于确定 DLL 是否可由 OLE 卸载。 STDAPI DllCanUnloadNow(void) { return _AtlModule.DllCanUnloadNow(); } // 返回一个类工厂以创建所请求类型的对象。 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { return _AtlModule.DllGetClassObject(rclsid, riid, ppv); } // DllRegisterServer - 在系统注册表中添加项。 STDAPI DllRegisterServer(void) { // 注册对象、类型库和类型库中的所有接口 HRESULT hr = _AtlModule.DllRegisterServer(); return hr; } // DllUnregisterServer - 在系统注册表中移除项。 STDAPI DllUnregisterServer(void) { HRESULT hr = _AtlModule.DllUnregisterServer(); return hr; } // DllInstall - 按用户和计算机在系统注册表中逐一添加/移除项。 STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine) { HRESULT hr = E_FAIL; static const wchar_t szUserSwitch[] = L"user"; if (pszCmdLine != NULL) { if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0) { ATL::AtlSetPerUserRegistration(true); } } if (bInstall) { hr = DllRegisterServer(); if (FAILED(hr)) { DllUnregisterServer(); } } else { hr = DllUnregisterServer(); } return hr; } 

dllmain.cpp的代码如下:

[cpp] view plain copy print ?

  1. // dllmain.cpp : DllMain 的实现。  
  2.   
  3. #include “stdafx.h”  
  4. #include “resource.h”  
  5. #include “HelloWorld_i.h”  
  6. #include “dllmain.h”  
  7.   
  8. CHelloWorldModule _AtlModule;  
  9.   
  10. // DLL 入口点  
  11. extern “C” BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)  
  12. {  
  13.     hInstance;  
  14.     return _AtlModule.DllMain(dwReason, lpReserved);   
  15. }  
// dllmain.cpp : DllMain 的实现。 #include "stdafx.h" #include "resource.h" #include "HelloWorld_i.h" #include "dllmain.h" CHelloWorldModule _AtlModule; // DLL 入口点 extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { hInstance; return _AtlModule.DllMain(dwReason, lpReserved); } 

HelloWorld.rgs的内容如下:

[plain] view plain copy print ?

  1. HKCR  
  2. {  
  3. }  
HKCR { } 

HelloWorldBHO.rgs的内容如下:

[plain] view plain copy print ?

  1. HKCR  
  2. {  
  3.     NoRemove CLSID  
  4.     {  
  5.         ForceRemove {22024CC8-9043-49C7-AC80-A803A2912BF6} = s ‘HelloWorldBHO Class’  
  6.         {  
  7.             ForceRemove Programmable  
  8.             InprocServer32 = s ‘%MODULE%’  
  9.             {  
  10.                 val ThreadingModel = s ‘Apartment’  
  11.             }  
  12.             TypeLib = s ‘{D05D8B0F-8126-4FE2-BC3D-D5A5248E7025}’  
  13.             Version = s ‘1.0’  
  14.         }  
  15.     }  
  16. }  
HKCR { NoRemove CLSID { ForceRemove {22024CC8-9043-49C7-AC80-A803A2912BF6} = s 'HelloWorldBHO Class' { ForceRemove Programmable InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } TypeLib = s '{D05D8B0F-8126-4FE2-BC3D-D5A5248E7025}' Version = s '1.0' } } } 

[plain] view plain copy print ?

  1. // HelloWorld.idl : HelloWorld 的 IDL 源  
  2. //  
  3.   
  4. // 此文件将由 MIDL 工具处理以  
  5. // 产生类型库(HelloWorld.tlb)和封送处理代码。  
  6.   
  7. import “oaidl.idl”;  
  8. import “ocidl.idl”;  
  9.   
  10. [  
  11.     object,  
  12.     uuid(9C44C518-EEBE-4126-B368-5B901F),  
  13.     dual,  
  14.     nonextensible,  
  15.     pointer_default(unique)  
  16. ]  
  17. interface IHelloWorldBHO : IDispatch{  
  18. };  
  19. [  
  20.     uuid(D05D8B0F-8126-4FE2-BC3D-D5A5248E7025),  
  21.     version(1.0),  
  22. ]  
  23. library HelloWorldLib  
  24. {  
  25.     importlib(“stdole2.tlb”);  
  26.     [  
  27.         uuid(22024CC8-9043-49C7-AC80-A803A2912BF6)        
  28.     ]  
  29.     coclass HelloWorldBHO  
  30.     {  
  31.         [default] interface IHelloWorldBHO;  
  32.     };  
  33. };  
// HelloWorld.idl : HelloWorld 的 IDL 源 // // 此文件将由 MIDL 工具处理以 // 产生类型库(HelloWorld.tlb)和封送处理代码。 import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(9C44C518-EEBE-4126-B368-5B901F), dual, nonextensible, pointer_default(unique) ] interface IHelloWorldBHO : IDispatch{ }; [ uuid(D05D8B0F-8126-4FE2-BC3D-D5A5248E7025), version(1.0), ] library HelloWorldLib { importlib("stdole2.tlb"); [ uuid(22024CC8-9043-49C7-AC80-A803A2912BF6) ] coclass HelloWorldBHO { [default] interface IHelloWorldBHO; }; }; 

HelloWorld.idl中的CLSID是22024CC8-9043-49C7-AC80-A803A2912BF6

其他的文件,暂时不重要。

修改HelloWorldBHO.h:

1、增加头文件

[cpp] view plain copy print ?

  1. #include 
      
  2. #include 
      
#include 
                 
                   #include 
                   
                 

2、增加一个公有的SetSite方法:

[cpp] view plain copy print ?

  1. public:  
  2.   
  3.     STDMETHOD(SetSite)(IUnknown *pUnkSite);  
public: STDMETHOD(SetSite)(IUnknown *pUnkSite);

3、增加私有的成员变量:

[cpp] view plain copy print ?

  1. private:  
  2.   
  3.     CComPtr

      m_spWebBrowser;  
  4.     BOOL m_fAdvised;  
private: CComPtr 
                   
                     m_spWebBrowser; BOOL m_fAdvised; 
                   

4、多继承一个类:

[cpp] view plain copy print ?

  1. public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>  
public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>

5、增加公有的方法OnDocumentComplete:

[cpp] view plain copy print ?

  1. BEGIN_SINK_MAP(CHelloWorldBHO)  
  2.     SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)  
  3. END_SINK_MAP()  
  4.   
  5.     // DWebBrowserEvents2  
  6.     void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);  
BEGIN_SINK_MAP(CHelloWorldBHO) SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete) END_SINK_MAP() // DWebBrowserEvents2 void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);

修改HelloWorldBHO.cpp,实现那两个方法:

[cpp] view plain copy print ?

  1. STDMETHODIMP CHelloWorldBHO::SetSite(IUnknown* pUnkSite)  
  2. {  
  3.     if (pUnkSite != NULL)  
  4.     {  
  5.         // Cache the pointer to IWebBrowser2.  
  6.         HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void )&m_spWebBrowser);  
  7.         if (SUCCEEDED(hr))  
  8.         {  
  9.             // Register to sink events from DWebBrowserEvents2.  
  10.             hr = DispEventAdvise(m_spWebBrowser);  
  11.             if (SUCCEEDED(hr))  
  12.             {  
  13.                 m_fAdvised = TRUE;  
  14.             }  
  15.         }  
  16.     }  
  17.     else  
  18.     {  
  19.         // Unregister event sink.  
  20.         if (m_fAdvised)  
  21.         {  
  22.             DispEventUnadvise(m_spWebBrowser);  
  23.             m_fAdvised = FALSE;  
  24.         }  
  25.   
  26.         // Release cached pointers and other resources here.  
  27.         m_spWebBrowser.Release();  
  28.     }  
  29.   
  30.     // Call base class implementation.  
  31.     return IObjectWithSiteImpl

    ::SetSite(pUnkSite);  
  32. }  
  33.   
  34. void STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)  
  35. {  
  36.     // Retrieve the top-level window from the site.  
  37.     HWND hwnd;  
  38.     HRESULT hr = m_spWebBrowser->get_HWND((LONG_PTR*)&hwnd);  
  39.     if (SUCCEEDED(hr))  
  40.     {  
  41.         // Output a message box when page is loaded.  
  42.         MessageBox(hwnd, L“Hello World!”, L“BHO”, MB_OK);  
  43.     }  
  44. }  
STDMETHODIMP CHelloWorldBHO::SetSite(IUnknown* pUnkSite) { if (pUnkSite != NULL) { // Cache the pointer to IWebBrowser2. HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void )&m_spWebBrowser); if (SUCCEEDED(hr)) { // Register to sink events from DWebBrowserEvents2. hr = DispEventAdvise(m_spWebBrowser); if (SUCCEEDED(hr)) { m_fAdvised = TRUE; } } } else { // Unregister event sink. if (m_fAdvised) { DispEventUnadvise(m_spWebBrowser); m_fAdvised = FALSE; } // Release cached pointers and other resources here. m_spWebBrowser.Release(); } // Call base class implementation. return IObjectWithSiteImpl 
                       
                         ::SetSite(pUnkSite); } void STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL) { // Retrieve the top-level window from the site. HWND hwnd; HRESULT hr = m_spWebBrowser->get_HWND((LONG_PTR*)&hwnd); if (SUCCEEDED(hr)) { // Output a message box when page is loaded. MessageBox(hwnd, L"Hello World!", L"BHO", MB_OK); } } 
                       

dllmain.cpp的DllMain修改成:

[cpp] view plain copy print ?

  1. extern “C” BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)  
  2. {  
  3.     if (dwReason == DLL_PROCESS_ATTACH)  
  4.     {  
  5.         DisableThreadLibraryCalls(hInstance);  
  6.     }  
  7.     return _AtlModule.DllMain(dwReason, lpReserved);   
  8. }  
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hInstance); } return _AtlModule.DllMain(dwReason, lpReserved); }

修改HelloWorld.rgs:

修改成:

[plain] view plain copy print ?

  1. HKLM {  
  2.   NoRemove SOFTWARE {  
  3.     NoRemove Microsoft {     
  4.       NoRemove Windows {  
  5.         NoRemove CurrentVersion {  
  6.           NoRemove Explorer {  
  7.             NoRemove ‘Browser Helper Objects’ {  
  8.               ForceRemove ‘{D2F7E1E3-C9DC-4349-B72C-D5A708D6DD77}’ = s ‘HelloWorldBHO’ {  
  9.                 val ‘NoExplorer’ = d ‘1’  
  10.               }  
  11.             }  
  12.           }  
  13.         }  
  14.       }  
  15.     }  
  16.   }  
  17. }  
HKLM { NoRemove SOFTWARE { NoRemove Microsoft { NoRemove Windows { NoRemove CurrentVersion { NoRemove Explorer { NoRemove 'Browser Helper Objects' { ForceRemove '{D2F7E1E3-C9DC-4349-B72C-D5A708D6DD77}' = s 'HelloWorldBHO' { val 'NoExplorer' = d '1' } } } } } } } }

其中的{D2F7E1E3-C9DC-4349-B72C-D5A708D6DD77},需要改成HelloWorld.idl中的CLSID,当前文件的CLSID是

修改完后:

[cpp] view plain copy print ?

  1. // HelloWorldBHO.h : CHelloWorldBHO 的声明  
  2.   
  3. #pragma once  
  4. #include “resource.h”       // 主符号  
  5.   
  6. #include 
      
  7. #include 
      
  8.   
  9. #include “HelloWorld_i.h”  
  10.   
  11.   
  12.   
  13. #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)  
  14. #error “Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。”  
  15. #endif  
  16.   
  17. using namespace ATL;  
  18.   
  19.   
  20. // CHelloWorldBHO  
  21.   
  22. class ATL_NO_VTABLE CHelloWorldBHO :  
  23.     public CComObjectRootEx

    ,  
  24.     public CComCoClass

    ,  
  25.     public IObjectWithSiteImpl

    ,  
  26.     public IDispatchImpl

    /*wMajor =*/ 1, 
    /*wMinor =*/ 0>,  
  27.     public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>  
  28. {  
  29. public:  
  30.     CHelloWorldBHO()  
  31.     {  
  32.     }  
  33.   
  34. DECLARE_REGISTRY_RESOURCEID(IDR_HELLOWORLDBHO)  
  35.   
  36. DECLARE_NOT_AGGREGATABLE(CHelloWorldBHO)  
  37.   
  38. BEGIN_COM_MAP(CHelloWorldBHO)  
  39.     COM_INTERFACE_ENTRY(IHelloWorldBHO)  
  40.     COM_INTERFACE_ENTRY(IDispatch)  
  41.     COM_INTERFACE_ENTRY(IObjectWithSite)  
  42. END_COM_MAP()  
  43.   
  44.   
  45.   
  46.     DECLARE_PROTECT_FINAL_CONSTRUCT()  
  47.   
  48.     HRESULT FinalConstruct()  
  49.     {  
  50.         return S_OK;  
  51.     }  
  52.   
  53.     void FinalRelease()  
  54.     {  
  55.     }  
  56.    
  57. public:  
  58.   
  59.     STDMETHOD(SetSite)(IUnknown *pUnkSite);  
  60.   
  61. BEGIN_SINK_MAP(CHelloWorldBHO)  
  62.     SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)  
  63. END_SINK_MAP()  
  64.   
  65.     // DWebBrowserEvents2  
  66.     void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);  
  67.   
  68. private:  
  69.   
  70.     CComPtr

      m_spWebBrowser;  
  71.     BOOL m_fAdvised;  
  72. };  
  73.   
  74. OBJECT_ENTRY_AUTO(__uuidof(HelloWorldBHO), CHelloWorldBHO)  
// HelloWorldBHO.h : CHelloWorldBHO 的声明 #pragma once #include "resource.h" // 主符号 #include 
                           
                             #include 
                            
                              #include "HelloWorld_i.h" #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) #error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。" #endif using namespace ATL; // CHelloWorldBHO class ATL_NO_VTABLE CHelloWorldBHO : public CComObjectRootEx 
                             
                               , public CComCoClass 
                              
                                , public IObjectWithSiteImpl 
                               
                                 , public IDispatchImpl 
                                
                                  , public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1> { public: CHelloWorldBHO() { } DECLARE_REGISTRY_RESOURCEID(IDR_HELLOWORLDBHO) DECLARE_NOT_AGGREGATABLE(CHelloWorldBHO) BEGIN_COM_MAP(CHelloWorldBHO) COM_INTERFACE_ENTRY(IHelloWorldBHO) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IObjectWithSite) END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } public: STDMETHOD(SetSite)(IUnknown *pUnkSite); BEGIN_SINK_MAP(CHelloWorldBHO) SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete) END_SINK_MAP() // DWebBrowserEvents2 void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL); private: CComPtr 
                                 
                                   m_spWebBrowser; BOOL m_fAdvised; }; OBJECT_ENTRY_AUTO(__uuidof(HelloWorldBHO), CHelloWorldBHO) 
                                  
                                 
                                
                               
                              
                             
                           

HelloWorldBHO.cpp:

[cpp] view plain copy print ?

  1. // HelloWorldBHO.cpp : CHelloWorldBHO 的实现  
  2.   
  3. #include “stdafx.h”  
  4. #include “HelloWorldBHO.h”  
  5.   
  6.   
  7. // CHelloWorldBHO  
  8.   
  9. STDMETHODIMP CHelloWorldBHO::SetSite(IUnknown* pUnkSite)  
  10. {  
  11.     if (pUnkSite != NULL)  
  12.     {  
  13.         // Cache the pointer to IWebBrowser2.  
  14.         HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void )&m_spWebBrowser);  
  15.         if (SUCCEEDED(hr))  
  16.         {  
  17.             // Register to sink events from DWebBrowserEvents2.  
  18.             hr = DispEventAdvise(m_spWebBrowser);  
  19.             if (SUCCEEDED(hr))  
  20.             {  
  21.                 m_fAdvised = TRUE;  
  22.             }  
  23.         }  
  24.     }  
  25.     else  
  26.     {  
  27.         // Unregister event sink.  
  28.         if (m_fAdvised)  
  29.         {  
  30.             DispEventUnadvise(m_spWebBrowser);  
  31.             m_fAdvised = FALSE;  
  32.         }  
  33.   
  34.         // Release cached pointers and other resources here.  
  35.         m_spWebBrowser.Release();  
  36.     }  
  37.   
  38.     // Call base class implementation.  
  39.     return IObjectWithSiteImpl

    ::SetSite(pUnkSite);  
  40. }  
  41.   
  42. void STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)  
  43. {  
  44.     // Retrieve the top-level window from the site.  
  45.     HWND hwnd;  
  46.     HRESULT hr = m_spWebBrowser->get_HWND((LONG_PTR*)&hwnd);  
  47.     if (SUCCEEDED(hr))  
  48.     {  
  49.         // Output a message box when page is loaded.  
  50.         MessageBox(hwnd, L“Hello World!”, L“BHO”, MB_OK);  
  51.     }  
  52. }  
// HelloWorldBHO.cpp : CHelloWorldBHO 的实现 #include "stdafx.h" #include "HelloWorldBHO.h" // CHelloWorldBHO STDMETHODIMP CHelloWorldBHO::SetSite(IUnknown* pUnkSite) { if (pUnkSite != NULL) { // Cache the pointer to IWebBrowser2. HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void )&m_spWebBrowser); if (SUCCEEDED(hr)) { // Register to sink events from DWebBrowserEvents2. hr = DispEventAdvise(m_spWebBrowser); if (SUCCEEDED(hr)) { m_fAdvised = TRUE; } } } else { // Unregister event sink. if (m_fAdvised) { DispEventUnadvise(m_spWebBrowser); m_fAdvised = FALSE; } // Release cached pointers and other resources here. m_spWebBrowser.Release(); } // Call base class implementation. return IObjectWithSiteImpl 
                             
                               ::SetSite(pUnkSite); } void STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL) { // Retrieve the top-level window from the site. HWND hwnd; HRESULT hr = m_spWebBrowser->get_HWND((LONG_PTR*)&hwnd); if (SUCCEEDED(hr)) { // Output a message box when page is loaded. MessageBox(hwnd, L"Hello World!", L"BHO", MB_OK); } } 
                             

dllmain.cpp:

[cpp] view plain copy print ?

  1. // dllmain.cpp : DllMain 的实现。  
  2.   
  3. #include “stdafx.h”  
  4. #include “resource.h”  
  5. #include “HelloWorld_i.h”  
  6. #include “dllmain.h”  
  7.   
  8. CHelloWorldModule _AtlModule;  
  9.   
  10. // DLL 入口点  
  11. extern “C” BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)  
  12. {  
  13.     if (dwReason == DLL_PROCESS_ATTACH)  
  14.     {  
  15.         DisableThreadLibraryCalls(hInstance);  
  16.     }  
  17.     return _AtlModule.DllMain(dwReason, lpReserved);   
  18. }  
// dllmain.cpp : DllMain 的实现。 #include "stdafx.h" #include "resource.h" #include "HelloWorld_i.h" #include "dllmain.h" CHelloWorldModule _AtlModule; // DLL 入口点 extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hInstance); } return _AtlModule.DllMain(dwReason, lpReserved); }

HelloWorld.rgs:

[plain] view plain copy print ?

  1. HKLM {  
  2.   NoRemove SOFTWARE {  
  3.     NoRemove Microsoft {     
  4.       NoRemove Windows {  
  5.         NoRemove CurrentVersion {  
  6.           NoRemove Explorer {  
  7.             NoRemove ‘Browser Helper Objects’ {  
  8.               ForceRemove ‘{22024CC8-9043-49C7-AC80-A803A2912BF6}’ = s ‘HelloWorldBHO’ {  
  9.                 val ‘NoExplorer’ = d ‘1’  
  10.               }  
  11.             }  
  12.           }  
  13.         }  
  14.       }  
  15.     }  
  16.   }  
  17. }  
HKLM { NoRemove SOFTWARE { NoRemove Microsoft { NoRemove Windows { NoRemove CurrentVersion { NoRemove Explorer { NoRemove 'Browser Helper Objects' { ForceRemove '{22024CC8-9043-49C7-AC80-A803A2912BF6}' = s 'HelloWorldBHO' { val 'NoExplorer' = d '1' } } } } } } } }

目前要修改的也就那么几个文件,然后关闭安全软件,进行build,生成的dll会自动注册到注册表里去,如图:

before:

C++开发BHO之HelloWorld


after:

C++开发BHO之HelloWorld


然后打开IE,如图:

C++开发BHO之HelloWorld


也可以在IE的管理加载项中看到,工具-管理加载项:

C++开发BHO之HelloWorld


可以启用或者禁用BHO。

这样,就完成了HelloWorld版本的BHO的开发。





























































版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229861.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午3:42
下一篇 2026年3月16日 下午3:43


相关推荐

  • 新浪微博模仿的是_微博随便看看在哪

    新浪微博模仿的是_微博随便看看在哪这几天学会了ListView组件,希望能帮到你们。    程序测试图如下:       1.代码如下:   MainActivity.java  packagecom.example.weibokankan;importjava.util.ArrayList;importjava.util.List;

    2025年7月23日
    5
  • 专业公司OpenCLAW本地部署实践分享

    专业公司OpenCLAW本地部署实践分享

    2026年3月16日
    2
  • soapui 使用 java_SoapUI的进阶使用

    soapui 使用 java_SoapUI的进阶使用关于SoapUI的简单使用,大家可以参考网上并自己摸索下,这里就不说了,下面说的是一些不常见的用法(但是又很有用),再加一些性能测试方面的经验。FileImport很多时候会有FileImport(Upload)类的Functions的,如果要用SoapUI做集成测试的话,免不了要处理byte[]类型的参数,那么如何通过SoapUI传递byte[](File)的参数了,实际上,也很简单,…

    2022年6月17日
    32
  • 10个JS常见算法题目

    10个JS常见算法题目1、冒泡排序调优(从小到大排序)2、输出九九乘法表3、输出水仙花数4、1–10的阶乘和5、输出1900年至2100年中的所有闰年6、输出10–100之间的所有素数7、1,2,3,4四个数字,能组合成多少种互不相同且没有重复的三位数8、取出四位数中的各个位上的数字9、猴子吃桃问题10、用星号输出菱形。源码如下:js算法题目练习&…

    2022年6月29日
    52
  • setContentView的时候,到底发生了什么

    setContentView的时候,到底发生了什么关于setContentView方法,想必大家对这个方法既熟悉又陌生,熟悉的原因是因为基本上我们每创建一个activity,都会调用这个方法,比如:“`@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}“`而且这种写法已经是创建activity的模版了

    2022年6月26日
    25
  • 初探treap

    初探treaptreap 的基本操作 treap 类似二分查找树 只是加了一个堆 用随机值维护平衡 只是期望平衡 小数据下表现并不是特别优秀 但是足够用了 先水两发 之后再继续搞 poj1338UglyN 把质因子只含 2 3 5 的数叫 UglyNumber 通式为 x 2i 3j 5kx 2 i times3 j times5 k 注意到是一个幂次计算 因此大致地有 0 i j k 3

    2026年3月19日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号