打造自己的双内核浏览器

               最近接触了,libcef外壳,ie外壳的开发。熟悉了浏览器开发的基本方法。因此。我决定了,在未来的岁月里,开发出一个属于自己的双内核浏览器。
               虽然,msdn有关于mfcie的例子去开发ie的例子,但mfc太臃肿,所以我决定采用wtl来开发。

           这是,在wtl探索下,参考wtlbrowser的例子,重新封装的类似于Chtmlview的类。


UIHandler.h
/*
*		author: zyb
*/
#pragma once

#include <mshtml.h>

template<class SubClass>
class CUIHandler : public IDocHostUIHandler,
				   public IOleCommandTarget
{
public:
	//IDocHostUIHandler
	HRESULT OnShowContextMenu(DWORD dwID, POINT *ppt,
		IUnknown *pcmdtReserved, IDispatch *pdispReserved)
	{
		// default tells control that we didn't show a menu,
		// and the control should show the menu
		return S_FALSE;
	}
	HRESULT OnGetHostInfo(DOCHOSTUIINFO *pInfo)
	{
		// default indicates we don't have info
		return S_OK;
	}
	HRESULT OnShowUI(DWORD dwID,
		IOleInPlaceActiveObject *pActiveObject,
		IOleCommandTarget *pCommandTarget,
		IOleInPlaceFrame *pFrame,
		IOleInPlaceUIWindow *pDoc)
	{
		// default means we don't have any UI, and control should show its UI
		return S_FALSE;
	}
	HRESULT OnHideUI()
	{
		// we don't have UI by default, so just pretend we hid it
		return S_OK;
	}
	HRESULT OnUpdateUI()
	{
		// we don't have UI by default, so just pretend we updated it
		return S_OK;
	}
	HRESULT OnEnableModeless(BOOL fEnable)
	{
		// we don't have any UI by default, so pretend we updated it
		return S_OK;
	}
	HRESULT OnDocWinActivate(BOOL fActivate)
	{
		// we don't have any UI by default, so pretend we updated it
		return S_OK;
	}
	HRESULT OnFrameWinActivate(BOOL fActivate)
	{
		// we don't have any UI by default, so pretend we updated it
		return S_OK;
	}
	HRESULT OnResizeBorder(LPCRECT prcBorder,
		IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
	{
		// we don't have any UI by default, so pretend we updated it
		return S_OK;
	}
	HRESULT OnTranslateAccelerator(LPMSG lpMsg,
		const GUID *pguidCmdGroup, DWORD nCmdID)
	{
		// no translation here
		return S_FALSE;
	}
	HRESULT OnGetOptionKeyPath(LPOLESTR *pchKey, DWORD dw)
	{
		// no replacement option key
		return S_FALSE;
	}
	HRESULT OnGetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
	{
		// no additional drop target
		return S_FALSE;
	}
	HRESULT OnGetExternal(IDispatch **ppDispatch)
	{
		// default tells control we don't have an external
		return S_FALSE;
	}
	HRESULT OnTranslateUrl(DWORD dwTranslate,
		LPWSTR pchURLIn, LPWSTR *ppchURLOut)
	{
		// no translation happens by default
		return S_FALSE;
	}
	HRESULT OnFilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
	{
		// no data objects by default
		return S_FALSE;
	}

	// IOleCommandTarget
	HRESULT OnQueryStatus(const GUID *pguidCmdGroup,
		ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
	{
		return S_OK;
	}
	HRESULT OnExec(const GUID *pguidCmdGroup, DWORD nCmdID,
		DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
	{
		return S_OK;
	}

private:
	//IDocHostUIHandler
	HRESULT STDMETHODCALLTYPE ShowContextMenu(
		DWORD dwID,
		POINT *ppt,
		IUnknown *pcmdtReserved,
		IDispatch *pdispReserved)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnShowContextMenu(dwID, ppt, pcmdtReserved, pdispReserved);
	}
	HRESULT STDMETHODCALLTYPE GetHostInfo(DOCHOSTUIINFO *pInfo)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnGetHostInfo(pInfo);
	}
	HRESULT STDMETHODCALLTYPE ShowUI(
		DWORD dwID,
		IOleInPlaceActiveObject *pActiveObject,
		IOleCommandTarget *pCommandTarget,
		IOleInPlaceFrame *pFrame,
		IOleInPlaceUIWindow *pDoc)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnShowUI(dwID, pActiveObject, pCommandTarget, pFrame, pDoc);
	}
	HRESULT STDMETHODCALLTYPE HideUI(void)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnHideUI();
	}
	HRESULT STDMETHODCALLTYPE UpdateUI(void)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnUpdateUI();
	}
	HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnEnableModeless(fEnable);
	}
	HRESULT STDMETHODCALLTYPE OnDocWindowActivate(BOOL fActivate)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnDocWinActivate(fActivate);
	}
	HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(BOOL fActivate)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnFrameWinActivate(fActivate);
	}

	HRESULT STDMETHODCALLTYPE ResizeBorder(
		LPCRECT prcBorder,
		IOleInPlaceUIWindow *pUIWindow,
		BOOL fRameWindow)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnResizeBorder(prcBorder, pUIWindow, fRameWindow);
	}
	HRESULT STDMETHODCALLTYPE TranslateAccelerator(
		LPMSG lpMsg,
		const GUID *pguidCmdGroup,
		DWORD nCmdID)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnTranslateAccelerator(lpMsg, pguidCmdGroup, nCmdID);
	}
	HRESULT STDMETHODCALLTYPE GetOptionKeyPath(
		LPOLESTR *pchKey,
		DWORD dw)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnGetOptionKeyPath(pchKey, dw);
	}
	HRESULT STDMETHODCALLTYPE GetDropTarget(
		IDropTarget *pDropTarget,
		IDropTarget **ppDropTarget)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnGetDropTarget(pDropTarget, ppDropTarget);
	}
	HRESULT STDMETHODCALLTYPE GetExternal(IDispatch **ppDispatch)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnGetExternal(ppDispatch);

	}
	HRESULT STDMETHODCALLTYPE TranslateUrl(
		DWORD dwTranslate,
		LPWSTR pchURLIn,
		LPWSTR *ppchURLOut)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnTranslateUrl(dwTranslate, pchURLIn, ppchURLOut);
	}
	HRESULT STDMETHODCALLTYPE FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnFilterDataObject(pDO, ppDORet);

	}

	// IOleCommandTarget
	HRESULT STDMETHODCALLTYPE QueryStatus(
		const GUID *pguidCmdGroup,
		ULONG cCmds,
		OLECMD prgCmds[],
		OLECMDTEXT *pCmdText)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnQueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
	}
	HRESULT STDMETHODCALLTYPE Exec(
		const GUID *pguidCmdGroup,
		DWORD nCmdID,
		DWORD nCmdexecopt,
		VARIANT *pvaIn,
		VARIANT *pvaOut)
	{
		SubClass* pT = static_cast<SubClass*>(this);
		return pT->OnExec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
	}

	//	IUnknown implementation
	STDMETHODIMP_(ULONG)	AddRef()
	{
		return 1;
	}

	STDMETHODIMP_(ULONG)	Release()
	{
		return 1;
	}

	STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
	{
		HRESULT hr = E_NOINTERFACE;

		if (ppvObject != NULL)
		{
			*ppvObject = NULL;
			if (IID_IUnknown == riid)
				*ppvObject = static_cast<IDocHostUIHandler*>(this);
			else if (IID_IOleCommandTarget == riid)
				*ppvObject = static_cast<IOleCommandTarget*>(this);
			else if (IID_IDocHostUIHandler == riid)
				*ppvObject = static_cast<IDocHostUIHandler*>(this);

			if (*ppvObject != NULL)
			{
				hr = S_OK;
				((LPUNKNOWN)*ppvObject)->AddRef();
			}
		}
		else
		{
			hr = E_POINTER;
		}
		return hr;
	}
};

WebBrowser2.h

 
 
/*
*
*/

#pragma once

#include <ExDispid.h>
#include <Comdef.h>
#include <mshtml.h>
#include <atlmisc.h>
#include "UIHandler.h"

class CWebBrowser2EventsBase
{
protected:
	static _ATL_FUNC_INFO	StatusTextChangeStruct;
	static _ATL_FUNC_INFO	ProgressChangeStruct;
	static _ATL_FUNC_INFO	CommandStateChangeStruct;
	static _ATL_FUNC_INFO	DownloadBeginStruct;
	static _ATL_FUNC_INFO	DownloadCompleteStruct;
	static _ATL_FUNC_INFO	TitleChangeStruct;
	static _ATL_FUNC_INFO	NavigateComplete2Struct;
	static _ATL_FUNC_INFO	BeforeNavigate2Struct;
	static _ATL_FUNC_INFO	PropertyChangeStruct;
	static _ATL_FUNC_INFO	NewWindow2Struct;
	static _ATL_FUNC_INFO	DocumentCompleteStruct;
	static _ATL_FUNC_INFO	NavigateErrorStruct;
	static _ATL_FUNC_INFO	OnQuitStruct;
	static _ATL_FUNC_INFO	OnVisibleStruct;
	static _ATL_FUNC_INFO	OnToolBarStruct;
	static _ATL_FUNC_INFO	OnMenuBarStruct;
	static _ATL_FUNC_INFO	OnStatusBarStruct;
	static _ATL_FUNC_INFO	OnFullScreenStruct;
	static _ATL_FUNC_INFO	OnTheaterModeStruct;
};

template <class SubClass,UINT uiID = 0>
class CWebBrowser2 : public CWebBrowser2EventsBase,
					 public IDispEventSimpleImpl<uiID, CWebBrowser2<SubClass, uiID>, &DIID_DWebBrowserEvents2>,
					 public CUIHandler<SubClass>
{
	typedef CWebBrowser2<SubClass, uiID> _MyClass;

public:

	BEGIN_MSG_MAP(_MyClass)
		MESSAGE_HANDLER(WM_CREATE,OnCreate)
		MESSAGE_HANDLER(WM_DESTROY,OnDestroy)
	END_MSG_MAP()

#define _SINK_ENTRY_INFO(dispid,fn,info) SINK_ENTRY_INFO(uiID,DIID_DWebBrowserEvents2,dispid,fn,info)
	BEGIN_SINK_MAP(_MyClass)
		_SINK_ENTRY_INFO(DISPID_STATUSTEXTCHANGE,__StatusTextChange,&StatusTextChangeStruct)
		_SINK_ENTRY_INFO(DISPID_PROGRESSCHANGE,__ProgressChange,&ProgressChangeStruct)
		_SINK_ENTRY_INFO(DISPID_COMMANDSTATECHANGE,__CommandStateChange,&CommandStateChangeStruct)
		_SINK_ENTRY_INFO(DISPID_DOWNLOADBEGIN,__DownloadBegin,&DownloadBeginStruct)
		_SINK_ENTRY_INFO(DISPID_DOWNLOADCOMPLETE,__DownloadComplete,&DownloadCompleteStruct)
		_SINK_ENTRY_INFO(DISPID_TITLECHANGE,__TitleChange,&TitleChangeStruct)
		_SINK_ENTRY_INFO(DISPID_NAVIGATECOMPLETE2,__NavigateComplete2,&NavigateComplete2Struct)
		_SINK_ENTRY_INFO(DISPID_BEFORENAVIGATE2,__BeforeNavigate2,&BeforeNavigate2Struct)
		_SINK_ENTRY_INFO(DISPID_PROPERTYCHANGE,__PropertyChange,&PropertyChangeStruct)
		_SINK_ENTRY_INFO(DISPID_NEWWINDOW2,__NewWindow2,&NewWindow2Struct)
		_SINK_ENTRY_INFO(DISPID_DOCUMENTCOMPLETE,__DocumentComplete,&DocumentCompleteStruct)
		_SINK_ENTRY_INFO(DISPID_NAVIGATEERROR,__NavigateError,&NavigateErrorStruct)
		_SINK_ENTRY_INFO(DISPID_ONQUIT,__OnQuit,&OnQuitStruct)
		_SINK_ENTRY_INFO(DISPID_ONVISIBLE,__OnVisible,&OnVisibleStruct)
		_SINK_ENTRY_INFO(DISPID_ONTOOLBAR,__OnToolBar,&OnToolBarStruct)
		_SINK_ENTRY_INFO(DISPID_ONMENUBAR,__OnMenuBar,&OnMenuBarStruct)
		_SINK_ENTRY_INFO(DISPID_ONSTATUSBAR,__OnStatusBar,&OnStatusBarStruct)
		_SINK_ENTRY_INFO(DISPID_ONFULLSCREEN,__OnFullScreen,&OnFullScreenStruct)
		_SINK_ENTRY_INFO(DISPID_ONTHEATERMODE,__OnTheaterMode,&OnTheaterModeStruct)
	END_SINK_MAP()
#undef _SINK_ENTRY_INFO

	CWebBrowser2(){ m_bState[Back] = m_bState[Forward] = FALSE; }
	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled);
	void OnCommandStateChange(long nCommand, BOOL bEnable);

	///////////////////Events
public:
	void OnStatusTextChange(const CString& szText){}
	void OnProgressChange(long lProgress, long lProgressMax){}
	void OnDownloadBegin(){}
	void OnDownloadComplete(){}
	void OnTitleChange(const CString& szTitle){}
	void OnNavigateComplete2(const CString& szURL){}
	BOOL OnBeforeNavigate2(const CString& szURL,
		DWORD dwFlags, const CString& szTargetFrameName,
		CSimpleArray<BYTE>& pPostedData, const CString& szHeaders)
	{	//Return TRUE to cancel
		return FALSE;
	}
	void OnPropertyChange(const CString& szProperty){}
	BOOL OnNewWindow2(IDispatch** ppDisp)
	{	//Return TRUE to cancel
		return FALSE;
	}
	void OnDocumentComplete(const CString& szURL){}
	BOOL OnNavigateError(const CString& szURL, const CString& szTargetFrameName, DWORD dwError)
	{	//Return TRUE to cancel
		return FALSE;
	}
	void OnQuit(){}
	void OnVisible(BOOL bVisible){}
	void OnToolBar(BOOL bToolBar){}
	void OnMenuBar(BOOL bMenuBar){}
	void OnStatusBar(BOOL bStatusBar){}
	void OnFullScreen(BOOL bFullScreen){}
	void OnTheaterMode(BOOL bTheaterMode){}
	///////////////////

	
public:
	// DocHostUIHandler overrideables
	HRESULT OnShowContextMenu(DWORD dwID, POINT *ppt,
		IUnknown *pcmdtReserved, IDispatch *pdispReserved)
	{
		return S_FALSE;
	}
	HRESULT OnGetHostInfo(DOCHOSTUIINFO *pInfo)
	{
		return S_OK;
	}
	HRESULT OnShowUI(DWORD dwID,IOleInPlaceActiveObject *pActiveObject,
		IOleCommandTarget *pCommandTarget,IOleInPlaceFrame *pFrame,
		IOleInPlaceUIWindow *pDoc)
	{
		return S_FALSE;
	}
	HRESULT OnHideUI()
	{
		return S_OK;
	}
	HRESULT OnUpdateUI()
	{
		return S_OK;
	}
	HRESULT OnEnableModeless(BOOL fEnable)
	{
		return S_OK;
	}
	HRESULT OnDocWinActivate(BOOL fActivate)
	{
		return S_OK;
	}
	HRESULT OnFrameWinActivate(BOOL fActivate)
	{
		return S_OK;
	}
	HRESULT OnResizeBorder(LPCRECT prcBorder,
		IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
	{
		return S_OK;
	}
	HRESULT OnTranslateAccelerator(LPMSG lpMsg,
		const GUID *pguidCmdGroup, DWORD nCmdID)
	{
		return S_FALSE;
	}
	HRESULT OnGetOptionKeyPath(LPOLESTR *pchKey, DWORD dw)
	{
		return S_FALSE;
	}
	HRESULT OnGetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
	{
		return S_FALSE;
	}
	HRESULT OnGetExternal(IDispatch **ppDispatch)
	{
// 		**ppDispatch = this;		//实现Js调用c++
// 				return S_OK;
 		return S_FALSE;
	}
	HRESULT OnTranslateUrl(DWORD dwTranslate,
		LPWSTR pchURLIn, LPWSTR *ppchURLOut)
	{
		return S_FALSE;
	}
	HRESULT OnFilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
	{
		return S_FALSE;
	}

	// IOleCommandTarget overrideables
	HRESULT OnQueryStatus(const GUID *pguidCmdGroup,
		ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
	{
		return S_OK;
	}
	HRESULT OnExec(const GUID *pguidCmdGroup, DWORD nCmdID,
		DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
	{
		return S_OK;
	}

	///////////////////Attributes
public:
	CString GetType() const;
	LONG	GetLeft() const;
	void	SetLeft(LONG lNewValue);
	LONG	GetTop() const;
	void	SetTop(LONG nNewValue);
	LONG	GetHeight() const;
	void	SetHeight(LONG nNewValue);
	LONG	GetWidth() const;
	void	SetWidth(LONG nNewValue);
	BOOL	GetVisible() const;
	void	SetVisible(BOOL bNewValue);
	CString	GetLocationName() const;
	READYSTATE	GetReadyState() const;
	BOOL	GetOffline() const;
	void	SetOffline(BOOL bNewValue);
	BOOL	GetSilent() const;
	void	SetSilent(BOOL bNewValue);
	BOOL	GetTopLevelContainer() const;
	CString	GetLocationURL() const;
	BOOL	GetBusy() const;
	LPDISPATCH	GetApplication() const;
	LPDISPATCH	GetParentBrowser() const;
	LPDISPATCH	GetContainer() const;
	LPDISPATCH	GetHtmlDocument() const;
	CString	GetFullName() const;
	int		GetToolBar() const;
	void	SetToolBar(int nNewValue);
	BOOL	GetMenuBar() const;
	void	SetMenuBar(BOOL bNewValue);
	BOOL	GetFullScreen() const;
	void	SetFullScreen(BOOL bNewValue);
	OLECMDF QueryStatusWB(OLECMDID cmdID) const;
	BOOL	GetRegisterAsBrowser() const;
	void	SetRegisterAsBrowser(BOOL bNewValue);
	BOOL	GetRegisterAsDropTarget() const;
	void	SetRegisterAsDropTarget(BOOL bNewValue);
	BOOL	GetTheaterMode() const;
	void	SetTheaterMode(BOOL bNewValue);
	BOOL	GetAddressBar() const;
	void	SetAddressBar(BOOL bNewValue);
	BOOL	GetStatusBar() const;
	void	SetStatusBar(BOOL bNewValue);
	BOOL	CanBack() const;
	BOOL	CanForward() const;
	///////////////////

	/////////////////////Operations
public:
	void	GoBack();
	void	GoForward();
	void	GoHome();
	void	GoSearch();
	void	Quit();
	HRESULT	Navigate(LPCTSTR szURL, 
		DWORD dwFlags = 0, LPCTSTR szTargetFrameName = NULL, 
		LPCVOID pPostData = NULL, DWORD dwPostDataLength = 0, 
		LPCTSTR szHeaders = NULL);
	HRESULT	Navigate2(LPCTSTR szURL,
		DWORD dwFlags = 0, LPCTSTR szTargetFrameName = NULL,
		LPCVOID pPostData = NULL, DWORD dwPostDataLength = 0,
		LPCTSTR szHeaders = NULL);
	void	Refresh();
	void	Refresh2(LONG nLevel);
	void	Stop();
	HRESULT PutProperty(LPCTSTR szProperty, const VARIANT& vtValue);
	CComVariant GetProperty(LPCTSTR szProperty);
	void	ExecWB(OLECMDID nCmd, OLECMDEXECOPT nCmdOptions, 
		VARIANT* pvInput = NULL, VARIANT* pvOutput = NULL);
	HRESULT	LoadFromResource(UINT nID);
	HRESULT	LoadFromResource(LPCTSTR szID);
	HRESULT	ClientToWindow(LPPOINT pPoint);
	///////////////////

protected:
	enum 
	{
		Back = 0,
		Forward
	};
	CComPtr<IWebBrowser2> m_pBrowser;
	BOOL	m_bState[2];

private:
	//Events
	void __stdcall __StatusTextChange(BSTR szText);
	void __stdcall __ProgressChange(long nProgress, long nProgressMax);
	void __stdcall __CommandStateChange(long nCommand, VARIANT_BOOL bEnable);
	void __stdcall __DownloadBegin();
	void __stdcall __DownloadComplete();
	void __stdcall __TitleChange(BSTR szText);
	void __stdcall __NavigateComplete2(IDispatch* pDisp, VARIANT* pvURL);
	void __stdcall __BeforeNavigate2(IDispatch* pDisp, VARIANT* pvURL, VARIANT* pvFlags, VARIANT* pvTargetFrameName, VARIANT* pvPostData, VARIANT* pvHeaders, VARIANT_BOOL* pbCancel);
	void __stdcall __PropertyChange(BSTR szProperty);
	void __stdcall __NewWindow2(IDispatch** ppDisp, VARIANT_BOOL* pbCancel);
	void __stdcall __DocumentComplete(IDispatch* pDisp, VARIANT* pvURL);
	void __stdcall __NavigateError(IDispatch* pDisp, VARIANT* pvURL, VARIANT* pvTargetFrameName, VARIANT* pvStatusCode, VARIANT_BOOL* pbCancel);
	void __stdcall __OnQuit();
	void __stdcall __OnVisible(VARIANT_BOOL bVisible);
	void __stdcall __OnToolBar(VARIANT_BOOL bToolBar);
	void __stdcall __OnMenuBar(VARIANT_BOOL bMenuBar);
	void __stdcall __OnStatusBar(VARIANT_BOOL bStatusBar);
	void __stdcall __OnFullScreen(VARIANT_BOOL bFullScreen);
	void __stdcall __OnTheaterMode(VARIANT_BOOL bTheaterMode);
};

template <class SubClass, UINT uiID>
LRESULT CWebBrowser2<SubClass, uiID>::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	SubClass* pT = static_cast<SubClass*>(this);
	LRESULT lResult = pT->DefWindowProc();
	HRESULT hResult = pT->QueryControl(IID_IWebBrowser2, (void**)&m_pBrowser);
	if (SUCCEEDED(hResult))
	{
		if (FAILED(DispEventAdvise(m_pBrowser, &DIID_DWebBrowserEvents2)))
		{
			ATLASSERT(FALSE);
			m_pBrowser.Release();
		}
	}
	return lResult;
}
template <class SubClass, UINT uiID>
LRESULT CWebBrowser2<SubClass, uiID>::OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled)
{
	if (m_pBrowser)
	{
		DispEventUnadvise(m_pBrowser, &DIID_DWebBrowserEvents2);
		m_pBrowser.Release();
	}
	bHandled = FALSE;
	return 0;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::OnCommandStateChange(long nCommand, BOOL bEnable)
{
	switch (nCommand)
	{
	case CSC_NAVIGATEBACK:
		m_bState[Back] = bEnable;
		break;
	case CSC_NAVIGATEFORWARD:
		m_bState[Forward] = bEnable;
		break;
	}
}
template <class SubClass,UINT uiID>
CString CWebBrowser2<SubClass, uiID>::GetType() const
{
	ATLASSERT(m_pBrowser);
	CComBSTR szResult;
	HRESULT hr = m_pBrowser->get_Type(&szResult);
	if (FAILED(hr))
		return CString();
	return szResult;
}
template <class SubClass,UINT uiID>
LONG CWebBrowser2<SubClass, uiID>::GetLeft() const
{
	ATLASSERT(m_pBrowser);
	LONG nResult;
	m_pBrowser->get_Left(&bResult);
	return nResult;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetLeft(LONG lNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_Left(nNewValue);
}
template <class SubClass,UINT uiID>
LONG CWebBrowser2<SubClass, uiID>::GetTop() const
{
	ATLASSERT(m_pBrowser);
	LONG nResult;
	m_pBrowser->get_Top(&bResult);
	return nResult;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetTop(LONG nNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_Top(nNewValue);
}
template <class SubClass,UINT uiID>
LONG CWebBrowser2<SubClass, uiID>::GetHeight() const
{
	ATLASSERT(m_pBrowser);
	LONG nResult;
	m_pBrowser->get_Height(&bResult);
	return nResult;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetHeight(LONG nNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_Height(nNewValue);
}
template <class SubClass,UINT uiID>
LONG	CWebBrowser2<SubClass, uiID>::GetWidth() const
{
	ATLASSERT(m_pBrowser);
	LONG nResult;
	m_pBrowser->get_Width(&bResult);
	return nResult;
}
template <class SubClass,UINT uiID>
void	CWebBrowser2<SubClass, uiID>::SetWidth(LONG nNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_Width(nNewValue);
}
template <class SubClass,UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetVisible() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_Visible(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetVisible(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_Visible(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass,UINT uiID>
CString	CWebBrowser2<SubClass, uiID>::GetLocationName() const
{
	ATLASSERT(m_pBrowser);
	CComBSTR szResult;
	HRESULT hr = m_pBrowser->get_LocationName(&szResult);
	if (FAILED(hr))
		return CString();
	return szResult;
}
template <class SubClass,UINT uiID>
READYSTATE	CWebBrowser2<SubClass, uiID>::GetReadyState() const
{
	ATLASSERT(m_pBrowser);
	READYSTATE result;
	m_pBrowser->get_ReadyState(&result);
	return result;
}
template <class SubClass,UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetOffline() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_Offline(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetOffline(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_Offline(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass,UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetSilent() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_Silent(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetSilent(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_Silent(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass,UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetTopLevelContainer() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	m_pBrowser->get_TopLevelContainer(&bResult);
	return bResult ? TRUE : FALSE;
}
template <class SubClass,UINT uiID>
CString	CWebBrowser2<SubClass, uiID>::GetLocationURL() const
{
	ATLASSERT(m_pBrowser);
	CComBSTR szResult;
	HRESULT hr = m_pBrowser->get_LocationURL(&szResult);
	if (FAILED(hr))
		return CString();
	return szResult;
}
template <class SubClass,UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetBusy() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	m_pBrowser->get_Busy(&bResult);
	return bResult ? TRUE : FALSE;
}
template <class SubClass,UINT uiID>
LPDISPATCH CWebBrowser2<SubClass, uiID>::GetApplication() const
{
	ATLASSERT(m_pBrowser);
	IDispatchPtr pDispatch;
	HRESULT hr m_pBrowser->get_Application(&pDispatch);
	if (FAILED(hr))
		return NULL;
	return pDispatch;
}
template <class SubClass,UINT uiID>
LPDISPATCH CWebBrowser2<SubClass, uiID>::GetParentBrowser() const
{
	ATLASSERT(m_pBrowser);
	LPDISPATCH result;
	HRESULT hr = m_pBrowser->get_Parent(&result);
	if (FAILED(hr))
		return NULL;
	return result;
}
template <class SubClass,UINT uiID>
LPDISPATCH CWebBrowser2<SubClass, uiID>::GetContainer() const
{
	ATLASSERT(m_pBrowser);
	LPDISPATCH result;
	HRESULT hr = m_pBrowser->get_Container(&result);
	if (FAILED(hr))
		return NULL;
	return result;
}
template <class SubClass,UINT uiID>
LPDISPATCH CWebBrowser2<SubClass, uiID>::GetHtmlDocument() const
{
	ATLASSERT(m_pBrowser);
	LPDISPATCH result;
	HRESULT hr = m_pBrowser->get_Document(&result);
	if (FAILED(hr))
		return NULL;
	return result;
}
template <class SubClass,UINT uiID>
CString	CWebBrowser2<SubClass, uiID>::GetFullName() const
{
	ATLASSERT(m_pBrowser);
	CComBSTR szResult;
	HRESULT hr = m_pBrowser->get_FullName(&szResult);
	if (FAILED(hr))
		return CString();
	return szResult;
}
template <class SubClass,UINT uiID>
int	CWebBrowser2<SubClass, uiID>::GetToolBar() const
{
	ATLASSERT(m_pBrowser);
	int iResult;
	m_pBrowser->get_ToolBar(&iResult);
	return iResult;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetToolBar(int nNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_ToolBar(nNewValue);
}
template <class SubClass,UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetMenuBar() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_MenuBar(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetMenuBar(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_MenuBar(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass,UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetFullScreen() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_FullScreen(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass,UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetFullScreen(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_FullScreen(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass,UINT uiID>
OLECMDF CWebBrowser2<SubClass, uiID>::QueryStatusWB(OLECMDID cmdID) const
{
	ATLASSERT(m_pBrowser);
	OLECMDF nResult;
	m_pBrowser->QueryStatusWB(nCmd, &nResult);
	return nResult;
}
template <class SubClass, UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetRegisterAsBrowser() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_RegisterAsBrowser(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetRegisterAsBrowser(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_RegisterAsBrowser(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass, UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetRegisterAsDropTarget() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_RegisterAsDropTarget(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetRegisterAsDropTarget(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_RegisterAsDropTarget(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass, UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetTheaterMode() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_TheaterMode(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetTheaterMode(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_TheaterMode(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass, UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetAddressBar() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_AddressBar(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetAddressBar(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_AddressBar(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass, UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::GetStatusBar() const
{
	ATLASSERT(m_pBrowser);
	VARIANT_BOOL bResult;
	HRESULT hr = m_pBrowser->get_StatusBar(&bResult);
	if (FAILED(hr))
		return FALSE;
	return bResult ? TRUE : FALSE;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::SetStatusBar(BOOL bNewValue)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->put_StatusBar(bNewValue ? VARIANT_TRUE : VARIANT_FALSE);
}
template <class SubClass, UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::CanBack() const
{
	return m_bState[Back];
}
template <class SubClass, UINT uiID>
BOOL CWebBrowser2<SubClass, uiID>::CanForward() const
{
	return m_bState[Forward];
}
///////////////////

/////////////////////Operations
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::GoBack()
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->GoBack();
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::GoForward()
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->GoForward();
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::GoHome()
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->GoHome();
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::GoSearch()
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->GoSearch();
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::Quit()
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->Quit();
}
template <class SubClass, UINT uiID>
HRESULT	CWebBrowser2<SubClass, uiID>::Navigate(LPCTSTR szURL,
	DWORD dwFlags = 0, LPCTSTR szTargetFrameName = NULL,
	LPCVOID pPostData = NULL, DWORD dwPostDataLength = 0,
	LPCTSTR szHeaders = NULL)
{
	USES_CONVERSION;
	ATLASSERT(m_pBrowser);
	ATLASSERT(szURL);
	CComVariant vtTargetFrameName, vtPostData, vtHeaders;
	if (szTargetFrameName)
		vtTargetFrameName = szTargetFrameName;
	if (pPostData && dwPostDataLength > 0)
	{
		vtPostData.ChangeType(VT_ARRAY | VT_UI1);
		SAFEARRAYBOUND Bound;
		Bound.cElements = dwPostDataLength;
		Bound.lLbound = 0;
		vtPostData.parray = SafeArrayCreate(VT_UI1, 1, &Bound);
		ATLASSERT(vtPostData.parray);
		if (vtPostData.parray == NULL)
			return E_OUTOFMEMORY;
		LPVOID pData;
		SafeArrayAccessData(vtPostData.parray, &pData);
		CopyMemory(pData, pPostData, dwPostDataLength);
		SafeArrayUnaccessData(vtPostData.parray);
	}
	if (szHeaders)
		vtHeaders = szHeaders;
	return m_pBrowser->Navigate(T2BSTR(szURL), 
		&CComVariant((LONG)dwFlags), &vtTargetFrameName, 
		&vtPostData, &vtHeaders);

}
template <class SubClass, UINT uiID>
HRESULT	CWebBrowser2<SubClass, uiID>::Navigate2(LPCTSTR szURL,
	DWORD dwFlags = 0, LPCTSTR szTargetFrameName = NULL,
	LPCVOID pPostData = NULL, DWORD dwPostDataLength = 0,
	LPCTSTR szHeaders = NULL)
{
	ATLASSERT(m_pBrowser);
	ATLASSERT(szURL);
	CComVariant vtTargetFrameName, vtPostData, vtHeaders;
	if (szTargetFrameName)
		vtTargetFrameName = szTargetFrameName;
	if (pPostData && dwPostDataLength > 0)
	{
		vtPostData.ChangeType(VT_ARRAY | VT_UI1);
		SAFEARRAYBOUND Bound;
		Bound.cElements = dwPostDataLength;
		Bound.lLbound = 0;
		vtPostData.parray = SafeArrayCreate(VT_UI1, 1, &Bound);
		ATLASSERT(vtPostData.parray);
		if (vtPostData.parray == NULL)
			return E_OUTOFMEMORY;
		LPVOID pData = NULL;
		SafeArrayAccessData(vtPostData.parray, &pData);
		ATLASSERT(pData);
		CopyMemory(pData, pPostData, dwPostDataLength);
		SafeArrayUnaccessData(vtPostData.parray);
	}
	if (szHeaders)
		vtHeaders = szHeaders;
	return m_pBrowser->Navigate2(&CComVariant(szURL), 
		&CComVariant((LONG)dwFlags), &vtTargetFrameName, 
		&vtPostData, &vtHeaders);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::Refresh()
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->Refresh();
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::Refresh2(LONG nLevel)
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->Refresh2(CComVariant(nLevel));
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::Stop()
{
	ATLASSERT(m_pBrowser);
	m_pBrowser->Stop();
}
template <class SubClass, UINT uiID>
HRESULT CWebBrowser2<SubClass, uiID>::PutProperty(LPCTSTR szProperty, const VARIANT& vtValue)
{
	ATLASSERT(m_pBrowser);
	USES_CONVERSION;
	return m_pBrowser->PutProperty(CComBSTR(szProperty), vtValue);
}
template <class SubClass, UINT uiID>
CComVariant CWebBrowser2<SubClass, uiID>::GetProperty(LPCTSTR szProperty)
{
	ATLASSERT(m_pBrowser);
	CComDispatchDriver pDriver(m_pBrowser);
	ATLASSERT(pDriver);
	CComVariant vtResult;
	pDriver.GetPropertyByName(CComBSTR(szProperty), &vtResult);
	return vtResult;
}
template <class SubClass, UINT uiID>
void	CWebBrowser2<SubClass, uiID>::ExecWB(OLECMDID nCmd, OLECMDEXECOPT nCmdOptions,
	VARIANT* pvInput = NULL, VARIANT* pvOutput = NULL)
{
	ATLASSERT(m_pBrowser);
	return m_pBrowser->ExecWB(nCmd, nCmdOptions, pvInput, pvOutput);
}
template <class SubClass, UINT uiID>
HRESULT	CWebBrowser2<SubClass, uiID>::LoadFromResource(UINT nID)
{
	TCHAR szFilename[MAX_PATH];
	GetModuleFileName(_Module.GetModuleInstance(), szFilename, sizeof(szFilename) / sizeof(TCHAR));
	TCHAR szURL[4096];
	_stprintf(szURL, _T("res://%s/%d"), szFilename, nID);
	return Navigate(szURL);
}
template <class SubClass, UINT uiID>
HRESULT	CWebBrowser2<SubClass, uiID>::LoadFromResource(LPCTSTR szID)
{
	TCHAR szFilename[MAX_PATH];
	GetModuleFileName(_Module.GetModuleInstance(), szFilename, sizeof(szFilename) / sizeof(TCHAR));
	TCHAR szURL[4096];
	_stprintf(szURL, _T("res://%s/%s"), szFilename, szID);
	return Navigate(szURL);
}
template <class SubClass, UINT uiID>
HRESULT	CWebBrowser2<SubClass, uiID>::ClientToWindow(LPPOINT pPoint)
{
	ATLASSERT(m_pBrowser);
	ATLASSERT(pPoint);
	return m_pBrowser->ClientToWindow(&(pPoint->x), &(pPoint->y));
}
///////////////////

template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__StatusTextChange(BSTR szText)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnStatusTextChange(szText);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__ProgressChange(long nProgress, long nProgressMax)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnProgressChange(nProgress, nProgressMax);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__CommandStateChange(long nCommand, VARIANT_BOOL bEnable)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnCommandStateChange(nCommand, (bEnable == VARIANT_TRUE) ? TRUE : FALSE);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__DownloadBegin()
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnDownloadBegin();

}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__DownloadComplete()
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnDownloadComplete();
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__TitleChange(BSTR szText)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnTitleChange(szText);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__NavigateComplete2(IDispatch* pDisp, VARIANT* pvURL)
{
	SubClass* pT = static_cast<SubClass*>(this);
	ATLASSERT(V_VT(pvURL) == VT_BSTR);
	pT->OnNavigateComplete2(V_BSTR(pvURL));
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__BeforeNavigate2(IDispatch* pDisp, 
	VARIANT* pvURL, VARIANT* pvFlags, VARIANT* pvTargetFrameName, 
	VARIANT* pvPostData, VARIANT* pvHeaders, VARIANT_BOOL* pbCancel)
{
	SubClass* pT = static_cast<SubClass*>(this);
	ATLASSERT(V_VT(pvURL) == VT_BSTR);
	ATLASSERT(V_VT(pvTargetFrameName) == VT_BSTR);
	ATLASSERT(V_VT(pvPostData) == (VT_VARIANT | VT_BYREF));
	ATLASSERT(V_VT(pvHeaders) == VT_BSTR);
	ATLASSERT(pbCancel != NULL);

	VARIANT* vtPostedData = V_VARIANTREF(pvPostData);
	CSimpleArray<BYTE> pArray;
	if (V_VT(vtPostedData) & VT_ARRAY)
	{
		ATLASSERT(V_ARRAY(vtPostedData)->cDims == 1 && V_ARRAY(vtPostedData)->cbElements == 1);
		long nLowBound = 0, nUpperBound = 0;
		SafeArrayGetLBound(V_ARRAY(vtPostedData), 1, &nLowBound);
		SafeArrayGetUBound(V_ARRAY(vtPostedData), 1, &nUpperBound);
		DWORD dwSize = nUpperBound + 1 - nLowBound;
		LPVOID pData = NULL;
		SafeArrayAccessData(V_ARRAY(vtPostedData), &pData);
		ATLASSERT(pData);

		pArray.m_nSize = pArray.m_nAllocSize = dwSize;
		pArray.m_aT = (BYTE*)malloc(dwSize);
		ATLASSERT(pArray.m_aT);
		CopyMemory(pArray.GetData(), pData, dwSize);
		SafeArrayUnaccessData(V_ARRAY(vtPostedData));
	}
	*pbCancel = pT->OnBeforeNavigate2(V_BSTR(pvURL), V_I4(pvFlags),
		V_BSTR(pvTargetFrameName), pArray, V_BSTR(pvHeaders)) ? VARIANT_TRUE : VARIANT_FALSE;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__PropertyChange(BSTR szProperty)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnPropertyChange(szProperty);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__NewWindow2(IDispatch** ppDisp, VARIANT_BOOL* pbCancel)
{
	SubClass* pT = static_cast<SubClass*>(this);
	*pbCancel = pT->OnNewWindow2(ppDisp) ? VARIANT_TRUE : VARIANT_FALSE;
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__DocumentComplete(IDispatch* pDisp, VARIANT* pvURL)
{
	SubClass* pT = static_cast<SubClass*>(this);
	ATLASSERT(V_VT(pvURL) == VT_BSTR);
	LPDISPATCH pDoc = GetHtmlDocument();
	CComQIPtr<ICustomDoc, &IID_ICustomDoc> spCustomDoc(pDoc);
	if (spCustomDoc)
		spCustomDoc->SetUIHandler(this);				//设置UIHandler
	pT->OnDocumentComplete(V_BSTR(pvURL));
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__NavigateError(IDispatch* pDisp, 
	VARIANT* pvURL, VARIANT* pvTargetFrameName, VARIANT* pvStatusCode, VARIANT_BOOL* pbCancel)
{
	SubClass* pT = static_cast<SubClass*>(this);
	ATLASSERT(V_VT(pvURL) == VT_BSTR);
	ATLASSERT(V_VT(pvTargetFrameName) == VT_BSTR);
	ATLASSERT(V_VT(pvStatusCode) == (VT_I4));
	ATLASSERT(pbCancel != NULL);
	*pbCancel = pT->OnNavigateError(V_BSTR(pvURL), V_BSTR(pvTargetFrameName), V_I4(pvStatusCode));
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__OnQuit()
{
	SubClass* pT = static_cast<SubClass*>(this);

}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__OnVisible(VARIANT_BOOL bVisible)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnVisible(bVisible == VARIANT_TRUE ? TRUE : FALSE);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__OnToolBar(VARIANT_BOOL bToolBar)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnToolBar(bToolBar == VARIANT_TRUE ? TRUE : FALSE);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__OnMenuBar(VARIANT_BOOL bMenuBar)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnMenuBar(bMenuBar == VARIANT_TRUE ? TRUE : FALSE);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__OnStatusBar(VARIANT_BOOL bStatusBar)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnStatusBar(bStatusBar == VARIANT_TRUE ? TRUE : FALSE);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__OnFullScreen(VARIANT_BOOL bFullScreen)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnFullScreen(bFullScreen == VARIANT_TRUE ? TRUE : FALSE);
}
template <class SubClass, UINT uiID>
void CWebBrowser2<SubClass, uiID>::__OnTheaterMode(VARIANT_BOOL bTheaterMode)
{
	SubClass* pT = static_cast<SubClass*>(this);
	pT->OnTheaterMode(bTheaterMode == VARIANT_TRUE ? TRUE : FALSE);
}


__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::StatusTextChangeStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::ProgressChangeStruct = { CC_STDCALL, VT_EMPTY, 2, { VT_I4, VT_I4 } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::CommandStateChangeStruct = { CC_STDCALL, VT_EMPTY, 2, { VT_I4, VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::DownloadBeginStruct = { CC_STDCALL, VT_EMPTY, 0, { NULL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::DownloadCompleteStruct = { CC_STDCALL, VT_EMPTY, 0, { NULL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::TitleChangeStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::NavigateComplete2Struct = { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BYREF | VT_VARIANT } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::BeforeNavigate2Struct = { CC_STDCALL, VT_EMPTY, 7, { VT_DISPATCH, VT_BYREF | VT_VARIANT, VT_BYREF | VT_VARIANT, VT_BYREF | VT_VARIANT, VT_BYREF | VT_VARIANT, VT_BYREF | VT_VARIANT, VT_BYREF | VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::PropertyChangeStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::NewWindow2Struct = { CC_STDCALL, VT_EMPTY, 2, { VT_BYREF | VT_BOOL, VT_BYREF | VT_DISPATCH } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::DocumentCompleteStruct = { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BYREF | VT_VARIANT } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::NavigateErrorStruct = { CC_STDCALL, VT_EMPTY, 5, { VT_BYREF | VT_BOOL, VT_BYREF | VT_VARIANT, VT_BYREF | VT_VARIANT, VT_BYREF | VT_VARIANT, VT_BYREF | VT_DISPATCH } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::OnQuitStruct = { CC_STDCALL, VT_EMPTY, 0, { NULL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::OnVisibleStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::OnToolBarStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::OnMenuBarStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::OnStatusBarStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::OnFullScreenStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CWebBrowser2EventsBase::OnTheaterModeStruct = { CC_STDCALL, VT_EMPTY, 1, { VT_BOOL } };


BrowserView.h
// BrowserView.h : interface of the CBrowserView class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include "IECore/WebBrowser2.h"

class CBrowserView : public CWindowImpl<CBrowserView, CAxWindow>,
					 public CWebBrowser2<CBrowserView>
{
public:
	DECLARE_WND_SUPERCLASS(NULL, CAxWindow::GetWndClassName())

	BOOL PreTranslateMessage(MSG* pMsg)
	{
		if((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
		   (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
			return FALSE;

		// give HTML page a chance to translate this message
		return (BOOL)SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg);
	}

	HRESULT OnGetHostInfo(DOCHOSTUIINFO *pInfo) //外观定制
	{
		pInfo->cbSize = sizeof(DOCHOSTUIINFO);
		pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME | DOCHOSTUIFLAG_DISABLE_HELP_MENU;// | DOCHOSTUIFLAG_DIALOG;
		return S_OK;
	}

	HRESULT OnExec(const GUID *pguidCmdGroup, DWORD nCmdID,
		DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
	{
		if (nCmdID == OLECMDID_SHOWSCRIPTERROR)
		{
			// Don't show the error dialog, but
			// continue running scripts on the page.
			(*pvaOut).vt = VT_BOOL;
			(*pvaOut).boolVal = VARIANT_TRUE;

			return S_OK;
		}
		return S_OK;
	}
	BOOL OnNewWindow2(IDispatch** ppDisp) //不弹出新窗口
	{	
		do{
			CComQIPtr<IHTMLDocument2> spDoc = GetHtmlDocument();
			if (!spDoc)	break;
			IHTMLElement *pHtmlElement;
			spDoc->get_activeElement(&pHtmlElement);
			if (!pHtmlElement) break;
			IHTMLAnchorElement *spAnchorElement;
			pHtmlElement->QueryInterface(IID_IHTMLAnchorElement, (void**)&spAnchorElement);
			if (!spAnchorElement) break;
			BSTR bstrElementHref;
			spAnchorElement->get_href(&bstrElementHref); // 获取当前点击的链接地址  
			Navigate2(bstrElementHref);
		} while (0);
		
		return TRUE;
	}

	BEGIN_MSG_MAP(CBrowserView)
		CHAIN_MSG_MAP(CWebBrowser2<CBrowserView>)
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
};

虽然出了 类似CHtmlView 类似的类,但不够让自己满意,所以,我决定,继续探索,研究一下 ATLBrowser  以及聚合 CAxHostWindow 封装出更让自己满意的类
聚合例子网址:https://www.codeproject.com/Articles/42670/Web-Application-Advanced-Hosting-of-WebBrowser-Con

猜你喜欢

转载自blog.csdn.net/huanongying131/article/details/79316249