这篇文章我一直想写,但是一直没有动笔,因为这里面牵扯的内容太多,而且有一部分并非我原创,拿出来有班门弄斧之嫌,所以一拖再拖,现在感觉可以把自己的一些经验心得和大家分享一下了。
现在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事件,自己摸索半天仍然不知所谓何因,有大侠知道还望赐教。
本文有不足之处,还望大家多多指正。