c++编写webui内核 .

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);
};
原文地址:https://www.cnblogs.com/carl2380/p/3547711.html