您的位置:首页 > 编程语言 > C语言/C++

(转)C++开发BHO(以HelloWorld对话框为例子)

2014-07-13 16:26 369 查看
原文:

http://msdn.microsoft.com/en-us/library/bb250489(v=vs.85).aspx

开发工具VS2010。

步骤如图:





















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

[cpp]
view plaincopyprint?

// 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<CComSingleThreadModel>,

public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,

public IObjectWithSiteImpl<CHelloWorldBHO>,

public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib,
/*wMajor =*/ 1, /*wMinor =*/ 0>

{
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.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<CComSingleThreadModel>,
	public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,
	public IObjectWithSiteImpl<CHelloWorldBHO>,
	public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
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 plaincopyprint?

// HelloWorldBHO.cpp : CHelloWorldBHO 的实现


#include "stdafx.h"

#include "HelloWorldBHO.h"



// CHelloWorldBHO

// HelloWorldBHO.cpp : CHelloWorldBHO 的实现

#include "stdafx.h"
#include "HelloWorldBHO.h"

// CHelloWorldBHO


HelloWorld.cpp的代码如下:

[cpp]
view plaincopyprint?

// 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;
}

// 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 plaincopyprint?

// 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);

}

// 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 plaincopyprint?

HKCR
{
}

HKCR
{
}


HelloWorldBHO.rgs的内容如下:

[plain]
view plaincopyprint?

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'
}
}
}

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'
		}
	}
}


HelloWorld.idl的内容:

[plain]
view plaincopyprint?

// HelloWorld.idl : HelloWorld 的 IDL 源
//

// 此文件将由 MIDL 工具处理以
// 产生类型库(HelloWorld.tlb)和封送处理代码。

import "oaidl.idl";
import "ocidl.idl";

[
object,
uuid(9C44C518-EEBE-4126-B368-5B901F840255),
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 : HelloWorld 的 IDL 源
//

// 此文件将由 MIDL 工具处理以
// 产生类型库(HelloWorld.tlb)和封送处理代码。

import "oaidl.idl";
import "ocidl.idl";

[
	object,
	uuid(9C44C518-EEBE-4126-B368-5B901F840255),
	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 plaincopyprint?

#include <shlguid.h>

#include <exdispid.h>

#include <shlguid.h>
#include <exdispid.h>


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

[cpp]
view plaincopyprint?

public:

STDMETHOD(SetSite)(IUnknown *pUnkSite);

public:

	STDMETHOD(SetSite)(IUnknown *pUnkSite);


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

[cpp]
view plaincopyprint?

private:

CComPtr<IWebBrowser2> m_spWebBrowser;
BOOL m_fAdvised;

private:

    CComPtr<IWebBrowser2>  m_spWebBrowser;
	BOOL m_fAdvised;


4、多继承一个类:

[cpp]
view plaincopyprint?

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

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


5、增加公有的方法OnDocumentComplete:

[cpp]
view plaincopyprint?

BEGIN_SINK_MAP(CHelloWorldBHO)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)

END_SINK_MAP()

// DWebBrowserEvents2

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 plaincopyprint?

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<CHelloWorldBHO>::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);

}
}

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<CHelloWorldBHO>::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 plaincopyprint?

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance,
DWORD dwReason, LPVOID lpReserved)

{
if (dwReason == DLL_PROCESS_ATTACH)

{
DisableThreadLibraryCalls(hInstance);
}
return _AtlModule.DllMain(dwReason, lpReserved);

}

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 plaincopyprint?

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'
}
}
}
}
}
}
}
}

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是

{22024CC8-9043-49C7-AC80-A803A2912BF6}

修改完后:
HelloWorldBHO.h:

[cpp]
view plaincopyprint?

// HelloWorldBHO.h : CHelloWorldBHO 的声明


#pragma once

#include "resource.h" // 主符号


#include <shlguid.h>
#include <exdispid.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<CComSingleThreadModel>,

public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,

public IObjectWithSiteImpl<CHelloWorldBHO>,

public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib,
/*wMajor =*/ 1, /*wMinor =*/ 0>,

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<IWebBrowser2> m_spWebBrowser;
BOOL m_fAdvised;

};

OBJECT_ENTRY_AUTO(__uuidof(HelloWorldBHO), CHelloWorldBHO)

// HelloWorldBHO.h : CHelloWorldBHO 的声明

#pragma once
#include "resource.h" // 主符号

#include <shlguid.h> #include <exdispid.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<CComSingleThreadModel>,
public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,
public IObjectWithSiteImpl<CHelloWorldBHO>,
public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
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<IWebBrowser2> m_spWebBrowser; BOOL m_fAdvised;
};

OBJECT_ENTRY_AUTO(__uuidof(HelloWorldBHO), CHelloWorldBHO)


HelloWorldBHO.cpp:

[cpp]
view plaincopyprint?

// 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<CHelloWorldBHO>::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);

}
}

// 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<CHelloWorldBHO>::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 plaincopyprint?

// 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);

}

// 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 plaincopyprint?

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'
}
}
}
}
}
}
}
}

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:



after:



然后打开IE,如图:



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



可以启用或者禁用BHO。

这样,就完成了HelloWorld版本的BHO的开发。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: