http://blog.csdn.net/sx1989827/article/details/8068779
#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); };