当前位置: 代码迷 >> Web前端 >> c++编纂webui内核
  详细解决方案

c++编纂webui内核

热度:716   发布时间:2012-10-17 10:25:46.0
c++编写webui内核

     这篇文章我一直想写,但是一直没有动笔,因为这里面牵扯的内容太多,而且有一部分并非我原创,拿出来有班门弄斧之嫌,所以一拖再拖,现在感觉可以把自己的一些经验心得和大家分享一下了。

       现在webui的使用范围很广,在一些大型软件上随处可见,其实这东西说白了也不难,就是c++(当然,也可以是其他语言)加个webbrowser,然后客户端与网页进行通信,牵扯到的主要是com技术。

webbro.h

#pragma once
#include <mshtmhst.h>
#include <mshtml.h>
#include <Exdisp.h>
#include <exdispid.h>
#include <MsHtmdid.h>
#include   <initguid.h> 
#include <map>
#include <vector>
using namespace std;
#define RECTWIDTH(r) ((r).right-(r).left)
#define RECTHEIGHT(r) ((r).bottom-(r).top)
class CExternal;
class CWebControl;
class CWebDialog;
struct CWebPar
{
	typedef void (*Func)(CWebDialog*,DISPPARAMS*,VARIANT*);
	CWebPar(CWebDialog* d,Func f):dlg(d),pfn(f){}
	Func pfn;
	CWebDialog* dlg;
};
DEFINE_GUID(CGID_IWebBrowser,0xED016940L,0xBD5B,0x11cf,0xBA,0x4E,0x00,0xC0,0x4F,0xD7,0x08,0x16);
#define ONWEBEVENT(obj,e,func)\
{\
	this->m_Par.push_back(new CWebPar((CWebDialog*)this,func)); \
	(obj).OnNewEvent((e),(this->m_Par[this->m_Par.size()-1]),CComBSTR(#func));\
}
#define  ONFUNCEVEVT(func)\
{\
	this->m_Par.push_back(new CWebPar((CWebDialog*)this,func)); \
	CComBSTR bstr;\
	bstr+=#func;\
	m_mFunc[bstr]=(this->m_Par[this->m_Par.size()-1]);\
}
class CWebDialog :
	public IDispatch,
	public IOleClientSite,
	public IOleInPlaceSite,
	public IOleInPlaceFrame,
	public IDocHostUIHandler,
	public IDropTarget
{
public:
	typedef void (*pFunc)(LPVOID);
	friend CExternal;
	friend CWebControl;
	CWebDialog(void);
	virtual ~CWebDialog(void);
	virtual STDMETHODIMP QueryInterface(REFIID iid,void**ppvObject);
	virtual STDMETHODIMP_(ULONG) AddRef();
	virtual STDMETHODIMP_(ULONG) Release();
	// IDispatch Methods
	HRESULT _stdcall GetTypeInfoCount(unsigned int * pctinfo);
	HRESULT _stdcall GetTypeInfo(unsigned int iTInfo,LCID lcid,ITypeInfo FAR* FAR* ppTInfo);
	HRESULT _stdcall GetIDsOfNames(REFIID riid,OLECHAR FAR* FAR* rgszNames,unsigned int cNames,LCID lcid,DISPID FAR* rgDispId);
	HRESULT _stdcall Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pDispParams,VARIANT FAR* pVarResult,EXCEPINFO FAR* pExcepInfo,unsigned int FAR* puArgErr);

	// IOleClientSite methods
	virtual STDMETHODIMP SaveObject();
	virtual STDMETHODIMP GetMoniker(DWORD dwA,DWORD dwW,IMoniker**pm);
	virtual STDMETHODIMP GetContainer(IOleContainer**pc);
	virtual STDMETHODIMP ShowObject();
	virtual STDMETHODIMP OnShowWindow(BOOL f);
	virtual STDMETHODIMP RequestNewObjectLayout();


	// IOleInPlaceSite methods
	virtual STDMETHODIMP GetWindow(HWND *p);
	virtual STDMETHODIMP ContextSensitiveHelp(BOOL);
	virtual STDMETHODIMP CanInPlaceActivate();
	virtual STDMETHODIMP OnInPlaceActivate();
	virtual STDMETHODIMP OnUIActivate();
	virtual STDMETHODIMP GetWindowContext(IOleInPlaceFrame** ppFrame,IOleInPlaceUIWindow **ppDoc,LPRECT r1,LPRECT r2,LPOLEINPLACEFRAMEINFO o);
	virtual STDMETHODIMP Scroll(SIZE s);
	virtual STDMETHODIMP OnUIDeactivate(int);
	virtual STDMETHODIMP OnInPlaceDeactivate();
	virtual STDMETHODIMP DiscardUndoState();
	virtual STDMETHODIMP DeactivateAndUndo();
	virtual STDMETHODIMP OnPosRectChange(LPCRECT);

	// IOleInPlaceFrame methods
	virtual STDMETHODIMP GetBorder(LPRECT l);
	virtual STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS);
	virtual STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS w);
	virtual STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*pV,LPCOLESTR s);
	virtual STDMETHODIMP InsertMenus(HMENU h,LPOLEMENUGROUPWIDTHS x);
	virtual STDMETHODIMP SetMenu(HMENU h,HOLEMENU hO,HWND hw);
	virtual STDMETHODIMP RemoveMenus(HMENU h);
	virtual STDMETHODIMP SetStatusText(LPCOLESTR t);
	virtual STDMETHODIMP EnableModeless(BOOL f);
	virtual STDMETHODIMP TranslateAccelerator(LPMSG,WORD);
	virtual HRESULT STDMETHODCALLTYPE ShowContextMenu(DWORD dwID,POINT *ppt,IUnknown *pcmdtReserved,IDispatch *pdispReserved);
	virtual HRESULT STDMETHODCALLTYPE GetHostInfo(DOCHOSTUIINFO *pInfo);
	virtual HRESULT STDMETHODCALLTYPE ShowUI(DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget, IOleInPlaceFrame *pFrame,IOleInPlaceUIWindow *pDoc);
	virtual HRESULT STDMETHODCALLTYPE HideUI( void);
	virtual HRESULT STDMETHODCALLTYPE UpdateUI( void);
	virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate(BOOL fActivate);
	virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate( BOOL fActivate);
	virtual HRESULT STDMETHODCALLTYPE ResizeBorder(LPCRECT prcBorder,IOleInPlaceUIWindow *pUIWindow,BOOL fRameWindow);
	virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpMsg,const GUID *pguidCmdGroup,DWORD nCmdID);
	virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw);
	virtual HRESULT STDMETHODCALLTYPE GetDropTarget(IDropTarget *pDropTarget,IDropTarget **ppDropTarget);
	virtual HRESULT STDMETHODCALLTYPE GetExternal( IDispatch **ppDispatch);
	virtual HRESULT STDMETHODCALLTYPE TranslateUrl(DWORD dwTranslate,OLECHAR *pchURLIn,OLECHAR **ppchURLOut);
	virtual HRESULT STDMETHODCALLTYPE FilterDataObject(IDataObject *pDO,IDataObject **ppDORet);
	//IDropTarget
	virtual HRESULT STDMETHODCALLTYPE DragEnter(
		IDataObject * pDataObject,
		//Pointer to the interface of the source data 
		// object
		DWORD grfKeyState, //Current state of keyboard modifier keys
		POINTL pt,         //Current cursor coordinates
		DWORD * pdwEffect  //Pointer to the effect of the drag-and-drop 
		// operation
		)
	{
		return m_pDrop->DragEnter(pDataObject,grfKeyState,pt,pdwEffect);
	}
	virtual HRESULT STDMETHODCALLTYPE DragOver(
		DWORD grfKeyState, //Current state of keyboard modifier keys
		POINTL pt,         //Current cursor coordinates
		DWORD * pdwEffect  //Pointer to the effect of the drag-and-drop 
		// operation
		)
	{
		return m_pDrop->DragOver(grfKeyState,pt,pdwEffect);
	}
	virtual HRESULT STDMETHODCALLTYPE DragLeave()
	{
		return m_pDrop->DragLeave();
	}
	virtual HRESULT STDMETHODCALLTYPE Drop(
		IDataObject * pDataObject,
		//Pointer to the interface for the source data
		DWORD grfKeyState, //Current state of keyboard modifier keys
		POINTL pt,         //Current cursor coordinates
		DWORD * pdwEffect  //Pointer to the effect of the drag-and-drop 
		// operation
		)
	{
// 		STGMEDIUM stgmed;
// 		// ask the IDataObject for some CF_TEXT data, stored as a HGLOBAL
// 		IEnumFORMATETC *enumetc;
// 		pDataObject->EnumFormatEtc(1,&enumetc);
// 		enumetc->Reset();
// 		FORMATETC etc;
// 		ULONG p;
// 		int nMaxFormat=0,nFormat=0;
// 		HRESULT hr=enumetc->Next(1,&etc,&p);
// 		while(hr==S_OK)
// 		{
// 		
// 				TCHAR szFormatName[100];
// 				GetClipboardFormatName(etc.cfFormat, szFormatName, 100-1);
// 				
// 					
// 						FORMATETC fmtetc = { etc.cfFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
// 						if(SUCCEEDED(pDataObject->GetData(&fmtetc, &stgmed)))
// 						{
// 							// 我们必须锁定HGLOBAL句柄,因为我们不能确信这是否是一个GEM_FIXED数据
// 							char *data = (char*)GlobalLock(stgmed.hGlobal);
// 							WCHAR *data1 = (WCHAR*)GlobalLock(stgmed.hGlobal);
// 							// cleanup
// 							GlobalUnlock(stgmed.hGlobal);
// 							ReleaseStgMedium(&stgmed);
// 						}
// 					
// 				
// 			hr=enumetc->Next(1,&etc,&p);
// 		}
// 		FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
// 		if(SUCCEEDED(pDataObject->GetData(&fmtetc, &stgmed)))
// 		{
// 			// 我们必须锁定HGLOBAL句柄,因为我们不能确信这是否是一个GEM_FIXED数据
// 			char *data = (char*)GlobalLock(stgmed.hGlobal);
// 			// cleanup
// 			GlobalUnlock(stgmed.hGlobal);
// 			ReleaseStgMedium(&stgmed);
// 		}

		HRESULT hr=m_pDrop->Drop(pDataObject,grfKeyState,pt,pdwEffect);
		return hr;
	}
public:

	static DISPID FindId(IDispatch *pObj, LPOLESTR pName);
	static HRESULT InvokeMethod(IDispatch *pObj, LPOLESTR pMehtod, VARIANT *pVarResult, VARIANT *ps, int cArgs);
	static HRESULT GetProperty(IDispatch *pObj, LPOLESTR pName, VARIANT *pValue);
	static HRESULT SetProperty(IDispatch *pObj, LPOLESTR pName, VARIANT *pValue);
	BOOL OpenCWebDialogwser();
	BOOL OpenURL(VARIANT* pVarUrl);
	inline IOleObject* _GetOleObject(){return _pOleObj;};
	inline IOleInPlaceObject* _GetInPlaceObject(){return _pInPlaceObj;};
	inline IWebBrowser2*   _GetWB2(){return _pWB2;};
	IWebBrowser2*      GetCWebDialogwser2();
	BOOL SetWebRect(LPRECT lprc);
	IDispatch*		   GetHtmlWindow();
	IHTMLDocument2*         GetDocument()
	{
		if(pHtmlDoc2)
		{
			pHtmlDoc2->Release();
		}
		IDispatch* pDp =  NULL;
		GetCWebDialogwser2()->get_Document(&pDp);
		pDp->QueryInterface(IID_IHTMLDocument2,(void**)&pHtmlDoc2);
		pDp->Release();	
		return pHtmlDoc2;
	}
	HWND GetSelfHwnd()
	{
		IOleWindow       *pOWin;       
		HWND       hBWnd;       
		HRESULT   hRes=GetCWebDialogwser2()-> QueryInterface(IID_IOleWindow,   (void**)&pOWin);       
		hRes=pOWin-> GetWindow(&hBWnd);   
		hBWnd=::FindWindowEx(hBWnd,0,_T("Shell DocObject View"),0);
		hBWnd=::FindWindowEx(hBWnd,0,_T("Internet Explorer_Server"),0);
		return hBWnd;         
	}
	virtual HWND GetHWND(){return NULL;}
	virtual void OnNavigateComplete(IDispatch* pDisp,VARIANT* url){return;}

	virtual void OnNewWindow(IDispatch **ppDisp,
		VARIANT_BOOL *Cancel,
		DWORD dwFlags,
		BSTR bstrUrlContext,
		BSTR bstrUrl
		)
	{
		return;
	}
	virtual void OnKeyDown(          IHTMLEventObj *pEvtObj
		)
	{
		return;
	}

	virtual void OnNewWindow2(IDispatch **ppDisp,
		VARIANT_BOOL *Cancel)
	{
		return;
	}

	virtual void OnProgressChange(long nProgress,long nProgressMax)
	{
		return;
	}
	virtual void OnDocumentComplete(          IDispatch *pDisp,
		VARIANT *URL
		)
	{
		return ;
	}
	virtual VARIANT_BOOL OnDocumentClick(IHTMLEventObj *pEvtObj)
	{
		return VARIANT_FALSE;
	}
	virtual void OnQuit()
	{
		return;
	}
	virtual void OnBeforeNavigate(IDispatch *pDisp,
		VARIANT *url,
		VARIANT *Flags,
		VARIANT *TargetFrameName,
		VARIANT *PostData,
		VARIANT *Headers,
		VARIANT_BOOL *Cancel)
	{
		return;
	}
	virtual VARIANT_BOOL OnContextMenu(IHTMLEventObj *pEvtObj)
	{
		CComQIPtr<IHTMLElement> ele;
		pEvtObj->get_srcElement(&ele);
		CComBSTR tagname;
		ele->get_tagName(&tagname);
		if(wcsicmp(tagname.m_str,L"input")!=0 && wcsicmp(tagname.m_str,L"textarea")!=0)
		{
			pEvtObj->put_cancelBubble(VARIANT_TRUE);
			pEvtObj->put_returnValue(CComVariant(VARIANT_FALSE));
		}
		return VARIANT_TRUE;
	}
	virtual VARIANT_BOOL OnSelectStart(IHTMLEventObj *pEvtObj)
	{
		CComQIPtr<IHTMLElement> ele;
		pEvtObj->get_srcElement(&ele);
		CComBSTR tagname;
		ele->get_tagName(&tagname);
		if(wcsicmp(tagname.m_str,L"input")!=0 && wcsicmp(tagname.m_str,L"textarea")!=0)
		{
			pEvtObj->put_cancelBubble(VARIANT_TRUE);
			pEvtObj->put_returnValue(CComVariant(VARIANT_FALSE));
		}
		return VARIANT_TRUE;
	}

private:
	IStorage *_pStorage;
	IOleObject *_pOleObj;
	IOleInPlaceObject *_pInPlaceObj;
	RECT  _rcWebWnd;
	bool  _bInPlaced;
	bool  _bExternalPlace;
	bool  _bCalledCanInPlace;
	bool  _bWebWndInited;
	IHTMLWindow2*               _pHtmlWnd2;
	IWebBrowser2*               _pWB2;
	long     _refNum;
	IHTMLDocument2 *pHtmlDoc2;
	IDropTarget *m_pDrop;
//dialog method
public:
	void InitWebUI();
	void SetBkColor(VARIANT);
	void SetFgColor(VARIANT);
	void GetCurPos(POINT *);
	virtual void OnNewEvent(BSTR,CWebPar*,BSTR);
	LRESULT WINAPI wndproc(MSG *);
	LRESULT Eval(BSTR,VARIANT *);
	bool LoadUIFromHtml(BSTR);
	vector<CWebPar*> m_Par;
	map<CComBSTR,CWebPar*> m_mFunc;
};
class CExternal:public IDispatch
{
private:
	long num;
public:
	typedef void (*pFunc)(LPVOID);
	CWebDialog *pDlg;
	CExternal(){num=1;}
	STDMETHODIMP QueryInterface(REFIID iid,void**ppvObject)
	{
		*ppvObject = NULL;
		if (iid == IID_IUnknown)	*ppvObject = this;
		else if (iid == IID_IDispatch)	*ppvObject = (IDispatch*)this;
		if(*ppvObject)
		{
			AddRef();
			return S_OK;
		}
		return E_NOINTERFACE;
	}
	STDMETHODIMP_(ULONG) AddRef()
	{
		return ::InterlockedIncrement( &num );
	}

	STDMETHODIMP_(ULONG) Release()
	{
		InterlockedDecrement( &num );
		long num1=num;
		if(num1==0)
		{
			delete this;
		}
		return num1;
	}
	HRESULT _stdcall GetTypeInfoCount(
		unsigned int * pctinfo) 
	{
		return E_NOTIMPL;
	}

	HRESULT _stdcall GetTypeInfo(
		unsigned int iTInfo,
		LCID lcid,
		ITypeInfo FAR* FAR* ppTInfo) 
	{
		return E_NOTIMPL;
	}

	HRESULT _stdcall GetIDsOfNames(
		REFIID riid, 
		OLECHAR FAR* FAR* rgszNames, 
		unsigned int cNames, 
		LCID lcid, 
		DISPID FAR* rgDispId 
		)
	{
		for(map<CComBSTR,CWebPar*>::iterator it=pDlg->m_mFunc.begin();it!=pDlg->m_mFunc.end();it++)
		{
			if(it->first==*rgszNames)
			{
				*rgDispId=(DISPID)&it->second;
				break;
			}
		}
		return S_OK;
	}
	HRESULT _stdcall Invoke(
		DISPID dispIdMember,
		REFIID riid,
		LCID lcid,
		WORD wFlags,
		DISPPARAMS* pDispParams,
		VARIANT* pVarResult,
		EXCEPINFO* pExcepInfo,
		unsigned int* puArgErr
		)
	{
		for(map<CComBSTR,CWebPar*>::iterator it=pDlg->m_mFunc.begin();it!=pDlg->m_mFunc.end();it++)
		{
			if(dispIdMember==(DISPID)&it->second)
			{
				((CWebPar*)it->second)->pfn(((CWebPar*)it->second)->dlg,pDispParams,pVarResult);
				break;
			}
		}
		return S_OK;
	}

};
class CWebControl
{
public:
	CWebControl(BSTR tag)
	{
		m_tagName=tag;
	}
	typedef void (*pFunc)(CWebDialog *);
	virtual void Create(CWebDialog*,BSTR,BSTR,int,int,int,int);
	virtual bool IsWindowVisible();
	virtual void ShowWindow(bool);
	virtual void MoveWindow(int,int,int,int);
	virtual void OnNewEvent(BSTR,CWebPar*,BSTR);
	virtual void SetBkColor(VARIANT);
	virtual void SetFgColor(VARIANT);
	virtual void GetWindowText(BSTR *);
	virtual void SetWindowText(BSTR);
	virtual void SetBkImg(BSTR);
	virtual void SetZIndex(int);
	virtual void GetWindowClient(RECT*);
	virtual void SetTransparent(int);
	virtual bool GetFromId(CWebDialog*,BSTR);
	virtual bool GetFromEval(CWebDialog*,BSTR);
protected:
	virtual void AppendChild();
	CComBSTR m_bsId;
	CWebDialog *m_pWeb;
	CComQIPtr<IHTMLElement> m_iEle;
	CComBSTR m_tagName;
	int m_iZIndex;
};
class CWebButton:public CWebControl
{
public:
	CWebButton():CWebControl(CComBSTR(L"button")){}
	void Create(CWebDialog*,BSTR,BSTR,int,int,int,int);
};
class CWebText:public CWebControl
{
public:
	CWebText():CWebControl(CComBSTR(L"input")),m_bPassword(false){}
	void Create(CWebDialog*,BSTR,BSTR,int,int,int,int);
	void SetPassWordType(bool);
	void GetWindowText(BSTR *);
	void SetWindowText(BSTR);
protected:
	bool m_bPassword;
};
class CWebStatic:public CWebControl
{
public:
	CWebStatic():CWebControl(CComBSTR(L"div")){}
	void Create(CWebDialog*,BSTR,BSTR,int,int,int,int);
};
class CWebImage:public CWebControl
{
public:
	CWebImage():CWebControl(CComBSTR(L"img")){}
	void Create(CWebDialog*,BSTR,BSTR,int,int,int,int);
	void SetImage(BSTR);
protected:
	CComBSTR m_bsImg;
};
class CWebMultipyText:public CWebControl
{
public:
	CWebMultipyText():CWebControl(CComBSTR(L"textarea")){}
	void Create(CWebDialog*,BSTR,BSTR,int,int,int,int);
};

webbro.cpp:

#include "StdAfx.h"
#include "WebBro.h"
CWebDialog::CWebDialog(void):_refNum(1),
	_bInPlaced(false),
	_bExternalPlace(false),
	_bCalledCanInPlace(false),
	_bWebWndInited(false),
	_pOleObj(NULL), 
	_pInPlaceObj(NULL), 
	_pStorage(NULL), 
	_pWB2(NULL), 
	_pHtmlWnd2(NULL),
	pHtmlDoc2(0)
{
	::memset((PVOID)&_rcWebWnd,0,sizeof(_rcWebWnd));
	OleInitialize(0);
	StgCreateDocfile(0,STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | STGM_CREATE,0,&_pStorage);

	OleCreate( CLSID_WebBrowser,IID_IOleObject,OLERENDER_DRAW, 0 , this, _pStorage, (void**)&_pOleObj );
	_pOleObj->QueryInterface(IID_IOleInPlaceObject,(LPVOID*)&_pInPlaceObj);

}


CWebDialog::~CWebDialog(void)
{
}
STDMETHODIMP CWebDialog::QueryInterface(REFIID iid,void**ppvObject)
{
	*ppvObject = NULL;

	if (iid == IID_IOleClientSite)	*ppvObject = (IOleClientSite*)this;
	else if (iid == IID_IUnknown)	*ppvObject = this;
	else if (iid == IID_IDispatch)	*ppvObject = (IDispatch*)this;
	else if (iid == IID_IDocHostUIHandler)		*ppvObject = (IDocHostUIHandler*)this;

	if ( _bExternalPlace == false)
	{
		if (iid == IID_IOleInPlaceSite)		*ppvObject = (IOleInPlaceSite*)this;		
		if (iid == IID_IOleInPlaceFrame)	*ppvObject = (IOleInPlaceFrame*)this;
		if (iid == IID_IOleInPlaceUIWindow)	*ppvObject = (IOleInPlaceUIWindow*)this;
	}

	if(*ppvObject)
	{
		AddRef();
		return S_OK;
	}
	return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CWebDialog::AddRef()
{
	return ::InterlockedIncrement( &_refNum );
}

STDMETHODIMP_(ULONG) CWebDialog::Release()
{
	return ::InterlockedDecrement( &_refNum );
}

// IDispatch Methods

HRESULT _stdcall CWebDialog::GetTypeInfoCount(
	unsigned int * pctinfo) 
{
	return E_NOTIMPL;
}

HRESULT _stdcall CWebDialog::GetTypeInfo(
	unsigned int iTInfo,
	LCID lcid,
	ITypeInfo FAR* FAR* ppTInfo) 
{
	return E_NOTIMPL;
}

HRESULT _stdcall CWebDialog::GetIDsOfNames(
	REFIID riid, 
	OLECHAR FAR* FAR* rgszNames, 
	unsigned int cNames, 
	LCID lcid, 
	DISPID FAR* rgDispId 
	)
{
	return E_NOTIMPL;
}
HRESULT _stdcall CWebDialog::Invoke(
	DISPID dispIdMember,
	REFIID riid,
	LCID lcid,
	WORD wFlags,
	DISPPARAMS* pDispParams,
	VARIANT* pVarResult,
	EXCEPINFO* pExcepInfo,
	unsigned int* puArgErr
	)
{
	if( dispIdMember == DISPID_BEFORENAVIGATE2)
	{
		OnBeforeNavigate(pDispParams->rgvarg[6].pdispVal,pDispParams->rgvarg[5].pvarVal,pDispParams->rgvarg[4].pvarVal,pDispParams->rgvarg[3].pvarVal,pDispParams->rgvarg[2].pvarVal,pDispParams->rgvarg[1].pvarVal,pDispParams->rgvarg[0].pboolVal);
		return S_OK;
	}
	if(dispIdMember== DISPID_NAVIGATECOMPLETE2)
	{
		OnNavigateComplete(pDispParams->rgvarg[1].pdispVal,pDispParams->rgvarg->pvarVal);
		return S_OK;
	}
	if(dispIdMember==DISPID_NEWWINDOW2)
	{
		OnNewWindow2(pDispParams->rgvarg[1].ppdispVal,pDispParams->rgvarg[0].pboolVal);
		return S_OK;
	}
	if(dispIdMember== DISPID_NEWWINDOW3)
	{
		OnNewWindow(pDispParams->rgvarg[4].ppdispVal,pDispParams->rgvarg[3].pboolVal,pDispParams->rgvarg[2].ulVal,pDispParams->rgvarg[1].bstrVal,pDispParams->rgvarg[0].bstrVal);
		return S_OK;
	}
	if(dispIdMember==DISPID_PROGRESSCHANGE)
	{
		OnProgressChange(pDispParams->rgvarg[1].lVal,pDispParams->rgvarg[0].lVal);
		return S_OK;
	}
	if(dispIdMember==DISPID_DOCUMENTCOMPLETE)
	{
		OnDocumentComplete(pDispParams->rgvarg[1].pdispVal,pDispParams->rgvarg->pvarVal);
		return S_OK;
	}
	if(dispIdMember==DISPID_QUIT)
	{
		OnQuit();
		return S_OK;
	}
	if(dispIdMember==DISPID_HTMLDOCUMENTEVENTS2_ONCLICK)
	{
		CComQIPtr<IHTMLEventObj> objEve=pDispParams->rgvarg[0].pdispVal;
		pVarResult->boolVal=OnDocumentClick(objEve);
		return S_OK;
	}
	if(dispIdMember==DISPID_HTMLDOCUMENTEVENTS2_ONCONTEXTMENU)
	{
		CComQIPtr<IHTMLEventObj> objEve=pDispParams->rgvarg[0].pdispVal;
		pVarResult->boolVal=OnContextMenu(objEve);
		return S_OK;
	}
	if(dispIdMember==DISPID_HTMLDOCUMENTEVENTS2_ONSELECTSTART)
	{
		CComQIPtr<IHTMLEventObj> objEve=pDispParams->rgvarg[0].pdispVal;
		pVarResult->boolVal=OnSelectStart(objEve);
		return S_OK;
	}
	if(dispIdMember==DISPID_HTMLDOCUMENTEVENTS2_ONKEYDOWN)
	{
		CComQIPtr<IHTMLEventObj> objEve=pDispParams->rgvarg[0].pdispVal;
		OnKeyDown(objEve);
		return S_OK;
	}
	return E_NOTIMPL;
}



//IOleClientSite methods
STDMETHODIMP CWebDialog::SaveObject()
{
	return S_OK;
}
STDMETHODIMP CWebDialog::GetMoniker(DWORD dwA,DWORD dwW,IMoniker**pm)
{
	*pm = 0;
	return E_NOTIMPL;
}
STDMETHODIMP CWebDialog::GetContainer(IOleContainer**pc)
{
	*pc = 0;
	return E_FAIL;
}
STDMETHODIMP CWebDialog::ShowObject()
{
	return S_OK;
}
STDMETHODIMP CWebDialog::OnShowWindow(BOOL f)
{
	return S_OK;
}
STDMETHODIMP CWebDialog::RequestNewObjectLayout()
{
	return S_OK;
}

//IOleInPlaceSite
STDMETHODIMP CWebDialog::GetWindow(HWND *p)
{
	*p = GetHWND();
	return S_OK;
}
STDMETHODIMP CWebDialog::ContextSensitiveHelp(BOOL)
{
	return E_NOTIMPL;
}
STDMETHODIMP CWebDialog::CanInPlaceActivate()//If this function return S_FALSE, AX cannot activate in place!
{
	if ( _bInPlaced )//Does CWebDialog Control already in placed?
	{
		_bCalledCanInPlace = true;
		return S_OK;
	}
	return S_FALSE;
}
STDMETHODIMP CWebDialog::OnInPlaceActivate()
{
	return S_OK;
}
STDMETHODIMP CWebDialog::OnUIActivate()
{
	return S_OK;
}
STDMETHODIMP CWebDialog::GetWindowContext(IOleInPlaceFrame** ppFrame,IOleInPlaceUIWindow **ppDoc,LPRECT r1,LPRECT r2,LPOLEINPLACEFRAMEINFO o)
{
	*ppFrame = (IOleInPlaceFrame*)this;
	AddRef();
	*ppDoc = NULL;
	::GetClientRect(  GetHWND() ,&_rcWebWnd );
	*r1 = _rcWebWnd;
	*r2 = _rcWebWnd;
	o->cb = sizeof(OLEINPLACEFRAMEINFO);
	o->fMDIApp = false;
	o->hwndFrame = GetParent( GetHWND() );
	o->haccel = 0;
	o->cAccelEntries = 0;

	return S_OK;
}
STDMETHODIMP CWebDialog::Scroll(SIZE s)
{
	return E_NOTIMPL;
}
STDMETHODIMP CWebDialog::OnUIDeactivate(int)
{
	return S_OK;
}
STDMETHODIMP CWebDialog::OnInPlaceDeactivate()
{
	return S_OK;
}
STDMETHODIMP CWebDialog::DiscardUndoState()
{
	return S_OK;
}
STDMETHODIMP CWebDialog::DeactivateAndUndo()
{
	return S_OK;
}
STDMETHODIMP CWebDialog::OnPosRectChange(LPCRECT)
{
	return S_OK;
}

//IOleInPlaceFrame
STDMETHODIMP CWebDialog::GetBorder(LPRECT l)
{
	::GetClientRect(  GetHWND() ,&_rcWebWnd );
	*l = _rcWebWnd;
	return S_OK;
}
STDMETHODIMP CWebDialog::RequestBorderSpace(LPCBORDERWIDTHS b)
{
	return S_OK;
}
STDMETHODIMP CWebDialog::SetBorderSpace(LPCBORDERWIDTHS b)
{
	return S_OK;
}
STDMETHODIMP CWebDialog::SetActiveObject(IOleInPlaceActiveObject*pV,LPCOLESTR s)
{
	return S_OK;
}
STDMETHODIMP CWebDialog::SetStatusText(LPCOLESTR t)
{
	return E_NOTIMPL;
}
STDMETHODIMP CWebDialog::EnableModeless(BOOL f)
{
	return E_NOTIMPL;
}
STDMETHODIMP CWebDialog::TranslateAccelerator(LPMSG,WORD)
{
	return E_NOTIMPL;
}
HRESULT _stdcall CWebDialog::RemoveMenus(HMENU h)
{
	return E_NOTIMPL;
}
HRESULT _stdcall CWebDialog::InsertMenus(HMENU h,LPOLEMENUGROUPWIDTHS x)
{
	return E_NOTIMPL;
}
HRESULT _stdcall CWebDialog::SetMenu(HMENU h,HOLEMENU hO,HWND hw)
{
	return E_NOTIMPL;
}

HRESULT CWebDialog:: ShowContextMenu(
	DWORD dwID,
	POINT *ppt,
	IUnknown *pcmdtReserved,
	IDispatch *pdispReserved
	)
{
	return E_NOTIMPL;

}
HRESULT CWebDialog::GetHostInfo(DOCHOSTUIINFO *pInfo)
{
	pInfo->dwFlags |= DOCHOSTUIFLAG_NO3DOUTERBORDER;
	pInfo->dwFlags |=DOCHOSTUIFLAG_THEME ;
	pInfo->dwFlags |=DOCHOSTUIFLAG_SCROLL_NO;
	pInfo->dwFlags |=DOCHOSTUIFLAG_DIALOG;
	return S_OK;
}
HRESULT CWebDialog:: ShowUI(
	DWORD dwID,
	IOleInPlaceActiveObject *pActiveObject,
	IOleCommandTarget *pCommandTarget,
	IOleInPlaceFrame *pFrame,
	IOleInPlaceUIWindow *pDoc
	)
{
	return E_NOTIMPL;
}
HRESULT CWebDialog::HideUI(void)
{
	return E_NOTIMPL;
}

HRESULT CWebDialog::UpdateUI(void)
{
	return E_NOTIMPL;
}

HRESULT CWebDialog::OnDocWindowActivate(BOOL fActivate)
{
	return E_NOTIMPL;
}
HRESULT CWebDialog::OnFrameWindowActivate(BOOL fActivate)
{
	return E_NOTIMPL;
}

HRESULT CWebDialog::ResizeBorder(
	LPCRECT prcBorder,
	IOleInPlaceUIWindow *pUIWindow,
	BOOL fRameWindow
	)
{
	return E_NOTIMPL;
}
HRESULT CWebDialog::TranslateAccelerator( 
	LPMSG lpMsg,
	const GUID *pguidCmdGroup,
	DWORD nCmdID
	)
{
	return E_NOTIMPL;
}
HRESULT CWebDialog::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
{
	return E_NOTIMPL;
}
HRESULT CWebDialog::GetDropTarget(IDropTarget *pDropTarget,IDropTarget **ppDropTarget)
{
	//S_OK:自定义拖拽
	//E_NOTIMPL:使用默认拖拽
	m_pDrop=pDropTarget;
	*ppDropTarget=this;
	return S_OK;

}

HRESULT CWebDialog::GetExternal( IDispatch **ppDispatch)
{
   CExternal* ext=new CExternal;
	ext->pDlg=this;
	*ppDispatch=ext;
	(*ppDispatch)->AddRef();
	return S_OK;
}

HRESULT CWebDialog::TranslateUrl(
	DWORD dwTranslate,
	OLECHAR *pchURLIn,
	OLECHAR **ppchURLOut
	)
{
	return E_NOTIMPL;
}
HRESULT CWebDialog:: FilterDataObject(IDataObject *pDO,IDataObject **ppDORet)
{
	return E_NOTIMPL;
}

//Other Methods
IWebBrowser2* CWebDialog::GetCWebDialogwser2()
{
	if(_pWB2 != NULL) return _pWB2;
	_pOleObj->QueryInterface(IID_IWebBrowser2,(void**)&_pWB2);
	return _pWB2;
RETURN:
	return NULL;
}

IDispatch* CWebDialog::GetHtmlWindow()
{
	if(_pHtmlWnd2 != NULL) return _pHtmlWnd2;

	IWebBrowser2* pWB2 = GetCWebDialogwser2();

	IHTMLDocument2 *pHtmlDoc2 = NULL;
	IDispatch* pDp =  NULL;
	pWB2->get_Document(&pDp);
	pDp->QueryInterface(IID_IHTMLDocument2,(void**)&pHtmlDoc2);

	pHtmlDoc2->get_parentWindow(&_pHtmlWnd2);

	IDispatch *pHtmlWindown = NULL;
	_pHtmlWnd2->QueryInterface(IID_IDispatch, (void**)&pHtmlWindown);

	pHtmlDoc2->Release();
	return pHtmlWindown;

RETURN:
	return NULL;
}

BOOL CWebDialog::SetWebRect(LPRECT lprc)
{
	BOOL bRet = FALSE;
	if( false == _bInPlaced )//尚未OpenCWebDialogwser操作,直接写入_rcWebWnd
	{
		_rcWebWnd = *lprc;
	}
	else//已经打开CWebDialog,通过 IOleInPlaceObject::SetObjectRects 调整大小
	{
		SIZEL size;
		size.cx = RECTWIDTH(*lprc);
		size.cy = RECTHEIGHT(*lprc);
		IOleObject* pOleObj;
		pOleObj= _GetOleObject();
		pOleObj->SetExtent(  1,&size );
		IOleInPlaceObject* pInPlace;
		pInPlace = _GetInPlaceObject();
		pInPlace->SetObjectRects(lprc,lprc);
		_rcWebWnd = *lprc;
	}
	bRet = TRUE;
RETURN:
	return bRet;
}

BOOL CWebDialog::OpenCWebDialogwser()
{
	BOOL bRet = FALSE;

	if((RECTWIDTH(_rcWebWnd) && RECTHEIGHT(_rcWebWnd)) == 0)
	{
		::GetClientRect( GetHWND() ,&_rcWebWnd);//设置CWebDialog的大小为窗口的客户区大小.
	}

	if( _bInPlaced == false )// Activate In Place
	{
		_bInPlaced = true;//_bInPlaced must be set as true, before INPLACEACTIVATE, otherwise, once DoVerb, it would return error;
		_bExternalPlace = 0;//lParam;

		_GetOleObject()->DoVerb(OLEIVERB_INPLACEACTIVATE,0,this,0, GetHWND()  ,&_rcWebWnd);
		_bInPlaced = true;

		//* 挂接DWebBrwoser2Event
		IConnectionPointContainer* pCPC = NULL;
		IConnectionPoint* pCP  = NULL;
		DWORD dwCookie = 0;
		GetCWebDialogwser2()->QueryInterface(IID_IConnectionPointContainer,(void**)&pCPC);
		pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2,&pCP);
		pCP->Advise( (IUnknown*)(void*)this,&dwCookie);
	}
//	GetCWebDialogwser2()->put_Silent(VARIANT_TRUE);
	bRet = TRUE;
RETURN:
	return bRet;
}
LRESULT WINAPI CWebDialog::wndproc(MSG *pMsg)
{
	if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)
	{
		HWND hwnd=::WindowFromPoint(pMsg->pt);
		TCHAR wszClsName[255]={0};
		GetClassName(hwnd,wszClsName,255);
		if(_tcscmp(wszClsName,_T("Internet Explorer_Server"))==0)
		{
			::PostMessage(hwnd,WM_CHAR,VK_RETURN,0);
			return TRUE;
		}
	}
	else if(pMsg->message==WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL)<0)
	{

		if(pMsg->hwnd==GetSelfHwnd())
		{
			if(pMsg->wParam==VkKeyScan(L'v'))
			{
				GetDocument()->execCommand(L"Paste",VARIANT_TRUE,CComVariant(0),0);
			}
			else if (pMsg->wParam==VkKeyScan(L'c'))
			{
				GetDocument()->execCommand(L"Copy",VARIANT_TRUE,CComVariant(0),0);
			}
			else if (pMsg->wParam==VkKeyScan(L'a'))
			{
				GetDocument()->execCommand(L"SelectAll",VARIANT_TRUE,CComVariant(0),0);
			}
			else if (pMsg->wParam==VkKeyScan(L'x'))
			{
				GetDocument()->execCommand(L"Cut",VARIANT_TRUE,CComVariant(0),0);
			}
			else if (pMsg->wParam==VkKeyScan(L'z'))
			{
				GetDocument()->execCommand(L"Undo",VARIANT_TRUE,CComVariant(0),0);
			}
			else if (pMsg->wParam==VkKeyScan(L'y'))
			{
				GetDocument()->execCommand(L"Redo",VARIANT_TRUE,CComVariant(0),0);
			}
			else if (pMsg->wParam==VkKeyScan(L'f'))
			{
				LPDISPATCH lpDispatch = NULL;
				LPOLECOMMANDTARGET lpOleCommandTarget = NULL;
				HRESULT hr = E_FAIL;

				// Get the IDispatch of the document.
				//
				lpDispatch = GetDocument();
				ASSERT(lpDispatch);

				if (lpDispatch)
				{
					// Get a pointer for the IOleCommandTarget interface.
					//
					hr = lpDispatch->QueryInterface(IID_IOleCommandTarget,
						(void**)&lpOleCommandTarget);
					lpDispatch->Release();

					if (SUCCEEDED(hr))
					{
						// Invoke the given command id 
						// for the WebBrowser control.
						hr = lpOleCommandTarget->Exec(&CGID_IWebBrowser,1, 0, NULL, NULL);
						lpOleCommandTarget->Release();
					}
				}
			}
			return TRUE;
		}
	}
	return FALSE;
}
BOOL CWebDialog::OpenURL(VARIANT* pVarUrl)
{
	BOOL bRet = FALSE;
	GetCWebDialogwser2()->Navigate2( pVarUrl,0,0,0,0);
	bRet = TRUE;
RETURN:
	return bRet;
}
DISPID CWebDialog::FindId(IDispatch *pObj, LPOLESTR pName)
{
	DISPID id = 0;
	HRESULT hr=pObj->GetIDsOfNames(IID_NULL,&pName,1,LOCALE_SYSTEM_DEFAULT,&id);
	if(FAILED(hr)) id = -1;
	return id;
}
HRESULT CWebDialog::InvokeMethod(IDispatch *pObj, LPOLESTR pName, VARIANT *pVarResult, VARIANT *p, int cArgs)
{
	DISPID dispid = FindId(pObj, pName);
	if(dispid == -1) return E_FAIL;

	DISPPARAMS ps;
	ps.cArgs = cArgs;
	ps.rgvarg = p;
	ps.cNamedArgs = 0;
	ps.rgdispidNamedArgs = NULL;

	return pObj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &ps, pVarResult, NULL, NULL);
}

HRESULT CWebDialog::GetProperty(IDispatch *pObj, LPOLESTR pName, VARIANT *pValue)
{
	DISPID dispid = FindId(pObj, pName);
	if(dispid == -1) return E_FAIL;

	DISPPARAMS ps;
	ps.cArgs = 0;
	ps.rgvarg = NULL;
	ps.cNamedArgs = 0;
	ps.rgdispidNamedArgs = NULL;

	return pObj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &ps, pValue, NULL, NULL);
}

HRESULT CWebDialog::SetProperty(IDispatch *pObj, LPOLESTR pName, VARIANT *pValue)
{
	DISPID dispid = FindId(pObj, pName);
	if(dispid == -1) return E_FAIL;

	DISPPARAMS ps;
	ps.cArgs = 1;
	ps.rgvarg = pValue;
	ps.cNamedArgs = 0;
	ps.rgdispidNamedArgs = NULL;

	return pObj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &ps, NULL, NULL, NULL);
}

void CWebDialog::InitWebUI()
{
	OpenCWebDialogwser();
	CRect rect;
	GetClientRect(GetHWND(),&rect);
	SetWebRect(&rect);
	_pWB2->Navigate2( &CComVariant(_T("about:blank")),NULL,NULL,NULL,NULL);
	VARIANT *param;
	SAFEARRAY *sfArray;
	CString strHtml;
	strHtml.Format(_T("<html><body scroll=\"no\"></body></html>"));
	BSTR bstr = strHtml.AllocSysString();

	// Creates a new one-dimensional array
	sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
	SafeArrayAccessData(sfArray,(LPVOID*) & param);
	param->vt = VT_BSTR;
	param->bstrVal = bstr;
	SafeArrayUnaccessData(sfArray);
	GetDocument()->write(sfArray);
	SysFreeString(bstr);
	SafeArrayDestroy(sfArray);
	IConnectionPointContainer* pCPC = NULL;
	IConnectionPoint* pCP  = NULL;
	DWORD dwCookie = 0;
	GetDocument()->QueryInterface(IID_IConnectionPointContainer,(void**)&pCPC);
	pCPC->FindConnectionPoint(DIID_HTMLDocumentEvents2,&pCP);
	pCP->Advise( (IUnknown*)(void*)this,&dwCookie);
}
void CWebDialog::SetBkColor(VARIANT v)
{
	GetDocument()->put_bgColor(v);
}
void CWebDialog::SetFgColor(VARIANT v)
{
	GetDocument()->put_fgColor(v);
}
void CWebDialog::GetCurPos(POINT *p)
{
	POINT pi;
	::GetCursorPos(&pi);
	ScreenToClient(GetHWND(),&pi);
	p->x=pi.x;
	p->y=pi.y;
}
void CWebDialog::OnNewEvent(BSTR bsEvent,CWebPar* pf,BSTR bsFunc)
{

	m_mFunc[bsFunc]=pf;
	CComBSTR bsJs;
	bsJs=L"document.body.";
	bsJs+=bsEvent;
	bsJs+=L"=function(){window.external.";
	bsJs+=bsFunc;
	bsJs+=L"();}";
	CComQIPtr<IHTMLWindow2> win;
	GetDocument()->get_parentWindow(&win);
	VARIANT ret;
	HRESULT hr=win->execScript(bsJs,CComBSTR(L"javascript"),&ret);
}
LRESULT CWebDialog::Eval(BSTR bstr,VARIANT *pResult)
{
	CComQIPtr<IHTMLWindow2> win;
	GetDocument()->get_parentWindow(&win);
	return InvokeMethod(win,L"eval",pResult,&CComVariant(bstr),1);
}
bool CWebDialog::LoadUIFromHtml(BSTR bstrPath)
{
	if(wcsstr(wcslwr(bstrPath),L".html")==0 && wcsstr(wcslwr(bstrPath),L".htm")==0 && wcsstr(wcslwr(bstrPath),L"http")==0)
	{
		return false;
	}
	_GetWB2()->Navigate2(&CComVariant(bstrPath),0,0,0,0);
	CComBSTR bstr;
	do 
	{
		GetDocument()->get_readyState(&bstr);
		MSG msg;
		if (PeekMessage(&msg, 0, 0 ,0, PM_REMOVE))
		{
			TranslateMessage (&msg) ;
			DispatchMessage (&msg) ;
		}
	} while (bstr!=L"complete");

	CComQIPtr<IHTMLElement> ele;
	GetDocument()->get_body(&ele);
	CComQIPtr<IHTMLBodyElement> body=ele;
	if(body)
	{	
		body->put_scroll(CComBSTR("no"));
		CComQIPtr<IHTMLStyle> style;
		ele->get_style(&style);
		style->put_overflow(CComBSTR("hidden"));
	}
	
	/*READYSTATE ready;
	_GetWB2()->get_ReadyState(&ready);
	while(ready!=READYSTATE_LOADING)
	{
		Sleep(1);
		_GetWB2()->get_ReadyState(&ready);
	}*/
	return true;
}
void CWebControl::Create(CWebDialog* pWeb,BSTR id,BSTR value,int x,int y,int w,int h)
{
	ASSERT(pWeb!=NULL);
	HRESULT hr;
	m_pWeb=pWeb;
	m_bsId=id;
	CComQIPtr<IHTMLDocument2> pDoc=m_pWeb->GetDocument();
	hr=pDoc->createElement(m_tagName,&m_iEle);
	hr=m_iEle->put_id(m_bsId);
	CComQIPtr<IHTMLStyle> eleStyle;
	hr=m_iEle->get_style(&eleStyle);
	hr=eleStyle->put_left(CComVariant(x));
	hr=eleStyle->put_top(CComVariant(y));
	hr=eleStyle->put_width(CComVariant(w));
	hr=eleStyle->put_height(CComVariant(h));
	CComQIPtr<IHTMLStyle2> eleStyle2=eleStyle;
	hr=eleStyle2->put_position(CComBSTR(L"absolute"));
}
void CWebControl::AppendChild()
{
	CComQIPtr<IHTMLElement> body;
	m_pWeb->GetDocument()->get_body(&body);
	CComVariant arg[]={m_iEle};
	CComVariant ret;
	m_pWeb->InvokeMethod(body,L"appendChild",&ret,arg,1);
}
bool CWebControl::IsWindowVisible()
{

	CComQIPtr<IHTMLStyle> eleStyle;
	m_iEle->get_style(&eleStyle);
	CComBSTR bsShow;
	eleStyle->get_display(&bsShow);
	if(bsShow==L"none")
	{
		return false;
	}
	else
	{
		return true;
	}
}
void CWebControl::ShowWindow(bool bShow)
{

	CComQIPtr<IHTMLStyle> eleStyle;
	m_iEle->get_style(&eleStyle);
	CComBSTR bsShow;
	if(bShow)
	{
		bsShow=L"inline";
	}
	else
	{
		bsShow=L"none";
	}
	eleStyle->put_display(bsShow);
}
void CWebControl::MoveWindow(int x,int y,int w,int h)
{

	CComQIPtr<IHTMLStyle> eleStyle;
	m_iEle->get_style(&eleStyle);
	eleStyle->put_left(CComVariant(x));
	eleStyle->put_top(CComVariant(y));
	eleStyle->put_width(CComVariant(w));
	eleStyle->put_height(CComVariant(h));
}
void CWebControl::OnNewEvent(BSTR bsEvent,CWebPar* pf,BSTR bsFunc)
{
	CComBSTR bstr;
	bstr+=m_bsId;
	bstr+=bsFunc;
	m_pWeb->m_mFunc[bstr]=pf;
	CComBSTR bsJs;
	bsJs=L"document.getElementById(\"";
	bsJs+=m_bsId;
	bsJs+=L"\").";
	bsJs+=bsEvent;
	bsJs+=L"=function(){window.external.";
	bsJs+=bstr;
	bsJs+=L"();}";
	CComQIPtr<IHTMLWindow2> win;
	m_pWeb->GetDocument()->get_parentWindow(&win);
	VARIANT ret;
	HRESULT hr=win->execScript(bsJs,CComBSTR(L"javascript"),&ret);
}
bool CWebControl::GetFromId(CWebDialog *dlg,BSTR bsId)
{
	m_pWeb=dlg;
	m_bsId=bsId;
	CComBSTR str;
	str+=L"document.getElementById(\"";
	str+=bsId;
	str+=L"\")";
	CComVariant v;
	HRESULT hr=m_pWeb->Eval(str,&v);
	if(SUCCEEDED(hr))
	{
		m_iEle=v.pdispVal;
		CComQIPtr<IHTMLStyle> style;
		m_iEle->get_style(&style);
		CComQIPtr<IHTMLStyle2> style2=style;
		style2->put_position(CComBSTR("absolute"));

	}
	else
	{
		return false;
	}
	return true;
}
bool CWebControl::GetFromEval(CWebDialog* dlg,BSTR bstr)
{
	m_pWeb=dlg;
	CComVariant v;
	HRESULT hr=m_pWeb->Eval(bstr,&v);
	if(SUCCEEDED(hr))
	{
		m_iEle=v.pdispVal;
		CComQIPtr<IHTMLStyle> style;
		m_iEle->get_style(&style);
		CComQIPtr<IHTMLStyle2> style2=style;
		style2->put_position(CComBSTR("absolute"));
	}
	else
	{
		return false;
	}
	return true;
}
void CWebControl::SetBkColor(VARIANT v)
{
	CComQIPtr<IHTMLStyle> style;
	m_iEle->get_style(&style);
	style->put_backgroundColor(v);
}
void CWebControl::SetFgColor(VARIANT v)
{
	CComQIPtr<IHTMLStyle> style;
	m_iEle->get_style(&style);
	style->put_color(v);
}
void CWebControl::GetWindowText(BSTR *bsText)
{
	m_iEle->get_innerText(bsText);

}
void CWebControl::SetWindowText(BSTR bsText)
{
	m_iEle->put_innerText(bsText);
}
void CWebControl::SetZIndex(int zIndex)
{
	m_iZIndex=zIndex;
	CComQIPtr<IHTMLStyle> style;
	m_iEle->get_style(&style);
	style->put_zIndex(CComVariant(zIndex));
}
void CWebControl::GetWindowClient(RECT* r)
{
	CComQIPtr<IHTMLStyle> style;	
	m_iEle->get_style(&style);
	style->get_pixelLeft(&(r->left));
	style->get_pixelTop(&(r->top));
	long w,h;
	style->get_pixelWidth(&w);
	style->get_pixelHeight(&h);
	r->right=r->left+w;
	r->bottom=r->top+h;
}
void CWebControl::SetTransparent(int nOpacity)
{
	CComQIPtr<IHTMLStyle> style;	
	m_iEle->get_style(&style);
	CComBSTR bsFilter;
	style->get_filter(&bsFilter);
	bsFilter+=_T("Alpha(opacity=%d);");
	wsprintfW(bsFilter.m_str,bsFilter.m_str,nOpacity);
	style->put_filter(bsFilter);
}
void CWebButton::Create(CWebDialog* pWeb,BSTR id,BSTR value,int x,int y,int w,int h)
{
	CWebControl::Create(pWeb,id,value,x,y,w,h);
	if(value)
	m_iEle->put_innerText(value);
	AppendChild();
}
void CWebControl::SetBkImg(BSTR bsImg)
{
	CComQIPtr<IHTMLStyle> style;
	m_iEle->get_style(&style);
	HRESULT hr=style->put_backgroundImage(bsImg);
}
void CWebText::Create(CWebDialog* pWeb,BSTR id,BSTR value,int x,int y,int w,int h)
{
	CWebControl::Create(pWeb,id,value,x,y,w,h);
	CComQIPtr<IHTMLInputElement> ele=m_iEle;
	if(value)
	ele->put_value(value);
	CComQIPtr<IHTMLInputElement> text=m_iEle;
	if(m_bPassword)
	{
		HRESULT hr;
		hr=text->put_type(CComBSTR("password"));

	}
	else
	{
		text->put_type(CComBSTR("text"));
	}
	AppendChild();
}
void CWebText::SetPassWordType(bool bPass)
{
	m_bPassword=bPass;
}
void CWebText::GetWindowText(BSTR *bsText)
{
	CComQIPtr<IHTMLInputElement> ele=m_iEle;
	ele->get_value(bsText);
}
void CWebText::SetWindowText(BSTR bsText)
{
	CComQIPtr<IHTMLInputElement> ele=m_iEle;
	ele->put_value(bsText);
}
void CWebStatic::Create(CWebDialog* pWeb,BSTR id,BSTR value,int x,int y,int w,int h)
{
	CWebControl::Create(pWeb,id,value,x,y,w,h);
	if(value)
	m_iEle->put_innerText(value);
	AppendChild();
}
void CWebImage::Create(CWebDialog* pWeb,BSTR id,BSTR value,int x,int y,int w,int h)
{
	CWebControl::Create(pWeb,id,value,x,y,w,h);
	AppendChild();
}
void CWebImage::SetImage(BSTR bsImg)
{
	if(!bsImg)
	{
		return;
	}
	m_bsImg=bsImg;
	CComQIPtr<IHTMLImgElement> img=m_iEle;
	img->put_src(bsImg);
	
}
void CWebMultipyText::Create(CWebDialog* pWeb,BSTR id,BSTR value,int x,int y,int w,int h)
{
	CWebControl::Create(pWeb,id,value,x,y,w,h);
	CComQIPtr<IHTMLStyle> style;
	m_iEle->get_style(&style);
	//style->put_whiteSpace(CComBSTR("nowrap"));
	m_pWeb->SetProperty(m_iEle,L"wrap",&CComVariant(L"irtual"));
	
	if(value)
		m_iEle->put_innerText(value);
	AppendChild();
}

       主要部分的代码就上面这些,cwebdialog这个类就是webbrowser,需要由mfc窗口继承,在gethwnd虚函数里返回mfc窗口的句柄,cexternal这个类就是重写webbrowser的external对象,让其指向宏ONFUNCEVEVT所创建的函数。CWebControl是webui控件的基类,webui所创建的控件都是从这个类上继承的。我们在c++客户端只需要调用initwebui即可完成webui的初始化操作,如果你当前有一个网页需要与客户端交互,LoadUIFromHtml这个方法是你的选择,下面给出一个实例:

main.h

#pragma once

#include "WebBro.h"
// CMain 对话框
class CvNotesDlg;
class CMain : public CDialogEx,public CWebDialog
{
	DECLARE_DYNAMIC(CMain)

public:
	CMain(CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CMain();
	HWND GetHWND(){return m_hWnd;}
	CString m_strPath;
	bool m_bInit;
	long m_flag; //0:new,1:view,2:edit
	CString m_strDate;
	CvNotesDlg *m_vNotesDlg;
	void InitExt();
	static DWORD m_ThredId;
	static DWORD WINAPI DownLoad(LPVOID);
// 对话框数据
	enum { IDD = IDD_VNOTES_MAIN };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	void OnOK(){}
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnClose();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	virtual BOOL OnInitDialog();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	void OnBeforeNavigate(IDispatch *pDisp,
		VARIANT *url,
		VARIANT *Flags,
		VARIANT *TargetFrameName,
		VARIANT *PostData,
		VARIANT *Headers,
		VARIANT_BOOL *Cancel)
	{
		char *szUrl=_com_util::ConvertBSTRToString(url->bstrVal);
		if(strstr(szUrl,"edit.html") || strstr(szUrl,"view.html") || strstr(szUrl,"manage.html") || strstr(szUrl,"about:blank"))
		{
			*Cancel=VARIANT_FALSE;
			if(strstr(szUrl,"edit.html"))
			{
				CRect r;
				GetWindowRect(&r);
				SetWindowPos(&wndTopMost,r.left,r.top,r.Width(),r.Height(),SWP_SHOWWINDOW);
			}
			else if(strstr(szUrl,"manage.html"))
			{
				CRect r;
				GetWindowRect(&r);
				SetWindowPos(&wndNoTopMost,r.left,r.top,r.Width(),r.Height(),SWP_SHOWWINDOW);

			}
		}
		else
		{
			*Cancel=VARIANT_TRUE;
		}
		delete[] szUrl;
		return;
	}
	afx_msg void OnDestroy();
	afx_msg void OnNcLButtonDblClk(UINT nHitTest, CPoint point);
};

main.cpp

// Main.cpp : 实现文件
//

#include "stdafx.h"
#include "vNotes.h"
#include "Main.h"
#include "afxdialogex.h"
#include "GetFlv.h"
#include "vNotesDlg.h"
// CMain 对话框
void GetFlag(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	result->vt=VT_I4;
	result->lVal=d->m_flag;
}
void GetDate(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	BSTR bstr=_com_util::ConvertStringToBSTR(d->m_strDate.GetBuffer(0));
	result->vt=VT_BSTR;
	result->bstrVal=bstr;
}
void GetColor(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	CColorDialog   dlgColor;
	dlgColor.m_cc.Flags|=CC_RGBINIT|CC_FULLOPEN;
	if(dlgColor.DoModal())
	{
			COLORREF col=dlgColor.m_cc.rgbResult;
			int r=GetRValue(col);
			int g=GetGValue(col);
			int b=GetBValue(col);
			CString strColor;
			strColor.Format("#%x%x%x",r,g,b);
			BSTR bstr=_com_util::ConvertStringToBSTR(strColor.GetBuffer(0));
			result->vt=VT_BSTR;
			result->bstrVal=bstr;
	
	}
}
void AddDowndLoad(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	char *url=_com_util::ConvertBSTRToString(par->rgvarg[1].bstrVal);
	char *file=_com_util::ConvertBSTRToString(CComBSTR(d->m_strPath+"\\html\\")+par->rgvarg[0].bstrVal);
	PostThreadMessage(d->m_ThredId,WM_MYDOWNLOAD,(WPARAM)url,(LPARAM)file);
}

void ViewNote(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	CMain *newDlg=new CMain;
	newDlg->m_flag=1;
	char *szDate=_com_util::ConvertBSTRToString(par->rgvarg[0].bstrVal);
	newDlg->m_strDate=szDate;
	delete[] szDate;
	newDlg->Create(IDD_VNOTES_MAIN);
	newDlg->CenterWindow();
	newDlg->ShowWindow(1);
}

void EditNote(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	CMain newDlg;
	newDlg.m_flag=2;
	char *szDate=_com_util::ConvertBSTRToString(par->rgvarg[0].bstrVal);
	newDlg.m_strDate=szDate;
	delete[] szDate;
	d->ShowWindow(0);
	newDlg.DoModal();
	d->ShowWindow(1);
}

void DelImg(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	char *file=_com_util::ConvertBSTRToString(CComBSTR(d->m_strPath+"\\html\\")+par->rgvarg[0].bstrVal);
	DeleteFile(file);
	delete[] file;
}

void GetFlv(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	CGetFlv flvDlg;
	CString strWeb;
	flvDlg.m_strWeb=&strWeb;
	d->ShowWindow(0);
	flvDlg.DoModal();
	d->ShowWindow(1);
	result->vt=VT_BSTR;
	result->bstrVal=_com_util::ConvertStringToBSTR(strWeb);
}

void EditPass(CWebDialog *dlg,DISPPARAMS* par,VARIANT* result)
{
	CMain* d=(CMain*)dlg;
	d->m_vNotesDlg->GetDlgItem(IDC_BUTTON2)->ShowWindow(0);
	d->m_vNotesDlg->EnableWindow(TRUE);
	d->m_vNotesDlg->ShowWindow(1);
}
IMPLEMENT_DYNAMIC(CMain, CDialogEx)
DWORD CMain::m_ThredId=0;
CMain::CMain(CWnd* pParent /*=NULL*/)
	: CDialogEx(CMain::IDD, pParent)
{
	m_bInit=0;
	m_flag=0;
}

CMain::~CMain()
{
}

void CMain::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CMain, CDialogEx)
	ON_WM_CLOSE()
	ON_WM_SYSCOMMAND()
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_WM_NCLBUTTONDBLCLK()
END_MESSAGE_MAP()


// CMain 消息处理程序


void CMain::OnClose()
{
	if(m_flag==0)
	{
		ShowWindow(0);
	}else if(m_flag==1)
	{
		DestroyWindow();
		delete this;
	}else if(m_flag==2)
	{
		EndDialog(IDOK);
	}
	

//	CDialogEx::OnClose();
}


void CMain::OnSysCommand(UINT nID, LPARAM lParam)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if(nID==SC_MINIMIZE)
	{
		if(m_flag==0)
		{
			ShowWindow(0);
		}else if(m_flag==1)
		{
			DestroyWindow();
			delete this;
		}else if(m_flag==2)
		{
			EndDialog(IDOK);
		}
		return;
	}
	CDialogEx::OnSysCommand(nID, lParam);
}


BOOL CMain::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	CRect rect (0,0,450,500);   
	AdjustWindowRect(&rect,GetStyle(),false);   
	CRect   cDest; 
	::SystemParametersInfo(SPI_GETWORKAREA,   0,   &cDest,   0); 
	if(m_flag==0)
	{
		SetWindowPos(&wndTopMost,cDest.Width()-rect.Width(),cDest.Height()-rect.Height(),rect.Width(),rect.Height(),SWP_SHOWWINDOW);
	}
	else
	{
		MoveWindow((cDest.Width()-rect.Width())/2,(cDest.Height()-rect.Height())/2,800,600);
		CenterWindow();
	}
	InitWebUI();
	_GetWB2()->put_Silent(VARIANT_TRUE);
	GetCurrentDirectory(255,m_strPath.GetBuffer(255));
	m_strPath.ReleaseBuffer();
	InitExt();
	if(m_flag==0)
	{
		LoadUIFromHtml(CComBSTR(m_strPath+"\\html\\edit.html"));
	}
	else if(m_flag==1)
	{
		LoadUIFromHtml(CComBSTR(m_strPath+"\\html\\view.html"));
	}else if(m_flag==2)
	{
		LoadUIFromHtml(CComBSTR(m_strPath+"\\html\\edit.html"));
	}
	m_bInit=1;
	if(m_ThredId==0)
	{
		CreateThread(0,0,DownLoad,0,0,&m_ThredId);
	}
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}


void CMain::OnSize(UINT nType, int cx, int cy)
{
	__super::OnSize(nType, cx, cy);
	if(m_bInit)
		SetWebRect(&CRect(0,0,cx,cy));
	// TODO: 在此处添加消息处理程序代码
}


BOOL CMain::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类

	return  wndproc(pMsg);
}
void CMain::InitExt()
{
	ONFUNCEVEVT(GetFlag);
	ONFUNCEVEVT(GetColor);
	ONFUNCEVEVT(AddDowndLoad);
	ONFUNCEVEVT(ViewNote);
	ONFUNCEVEVT(GetDate);
	ONFUNCEVEVT(EditNote);
	ONFUNCEVEVT(DelImg);
	ONFUNCEVEVT(GetFlv);
	ONFUNCEVEVT(EditPass);
}
DWORD WINAPI CMain::DownLoad(LPVOID l)
{
	while(1)
	{
		Sleep(1);
		MSG msg;
		if(PeekMessage(&msg,0,0,0,PM_REMOVE))
		{
			if(msg.message==WM_MYDOWNLOAD)
			{
				char* url=(char*)(msg.wParam);
				char* file=(char*)(msg.lParam);
				URLDownloadToFile(0,url,file,0,0);
				delete[] url;
				delete[] file;
			}
			else if(msg.message==WM_QUIT)
			{
				break;
			}
		}
	}
	return 0;
}

void CMain::OnDestroy()
{
	__super::OnDestroy();
	// TODO: 在此处添加消息处理程序代码
}


void CMain::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
		CRect   cDest,rect; 
		::SystemParametersInfo(SPI_GETWORKAREA,   0,   &cDest,   0); 
		GetWindowRect(&rect);
		if(rect==cDest)
		{
			MoveWindow((cDest.Width()-rect.Width())/2,(cDest.Height()-rect.Height())/2,800,600);
			CenterWindow();
		}
		else
		{
			SetWindowPos(&wndTop,0,0,cDest.Width(),cDest.Height(),SWP_SHOWWINDOW);
		}
	__super::OnNcLButtonDblClk(nHitTest, point);
}

      以上代码是我最近编写的一个微笔记程序里的代码,有时间我把完整的程序发上来。

    不得不说的是这个webui有一个bug,就是无法响应html里的onkeydown事件,自己摸索半天仍然不知所谓何因,有大侠知道还望赐教。

    本文有不足之处,还望大家多多指正。