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()-]),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()-]);\
}
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,,_T("Shell DocObject View"),);
hBWnd=::FindWindowEx(hBWnd,,_T("Internet Explorer_Server"),);
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")!= && wcsicmp(tagname.m_str,L"textarea")!=)
{
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")!= && wcsicmp(tagname.m_str,L"textarea")!=)
{
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=;}
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==)
{
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);
};