C++之WebBrowser容器,SDK实现

这几天一直在研究程序窗口显示网页的方法,刚一开始不得其法,后来咨询一大神,介绍说是用WebBrowser来做成dll或者是lib,然后用程序窗口调用这个lib或者dll,这样正是符合我的要求.因为我要做成和QQ游戏大厅一样的结果.废话不多说,代码如果.代码是从http://blog.csdn.net/sidyhe/article/details/9073485拷贝过来的,不过运行的时候有问题,就修改了一下,是Initialize的声音,前面加了一个virtual

XWebBrowser.h

// XWebBrowser.h: interface for the CXWebBrowser class.
// http://blog.csdn.net/Sidyhe
//////////////////////////////////////////////////////////////////////

#ifndef _INCLUDE_WEBBROWSEREX_FILE_H_
#define _INCLUDE_WEBBROWSEREX_FILE_H_
#pragma once
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#if _DEBUG
#include <crtdbg.h>//_ASSERT
#endif
//有冲突,居然被宏定义了,取消掉(WinUser.h中)
#ifdef TranslateAccelerator
#undef TranslateAccelerator
#endif

#include <oleidl.h>
#include <MsHTML.h>
#include <MSHTMHST.H>
#include <EXDISP.H>
/*
使用此类前务必调用OleInitialize,否则出错!
*/
enum _PAGE_ACT
{
    PAGE_GOBACK,    //后退
    PAGE_GOFORWARD, //前进
    PAGE_GOHOME,    //主页
    PAGE_SEARCH,    //搜索
    PAGE_REFRESH,   //刷新
    PAGE_STOP       //停止
};

class CXWebBrowser://IE控件要继承这几个基类
public IDispatch,
public IOleClientSite,
public IOleInPlaceSite,
public IOleInPlaceFrame,
public IDocHostUIHandler
{
public:
    CXWebBrowser();
    ~CXWebBrowser();
//////////////////////////////////////////////////////////////////////////
// 考虑到以后可能被继承/重载,所以写成虚的,但是本身也实现了
protected:
//IUnKnown
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
    virtual ULONG STDMETHODCALLTYPE AddRef(void);
    virtual ULONG STDMETHODCALLTYPE Release(void);
//IDispatch
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
    virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
                                            DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
//IOleWindow
    virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
    virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
//IOleInPlaceUIWindow
    virtual HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder);
    virtual HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths);
    virtual HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS pborderwidths);
    virtual HRESULT STDMETHODCALLTYPE SetActiveObject(IOleInPlaceActiveObject *pActiveObject,LPCOLESTR pszObjName);
//IOleInPlaceFrame
    virtual HRESULT STDMETHODCALLTYPE InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
    virtual HRESULT STDMETHODCALLTYPE SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject);
    virtual HRESULT STDMETHODCALLTYPE RemoveMenus(HMENU hmenuShared);
    virtual HRESULT STDMETHODCALLTYPE SetStatusText(LPCOLESTR pszStatusText);
    virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable);
    //返回0,则不相应回车消息,其他功能未知
    virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD wID);
//IOleClientSite
    virtual HRESULT STDMETHODCALLTYPE SaveObject(void);
    virtual HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
    virtual HRESULT STDMETHODCALLTYPE GetContainer(IOleContainer **ppContainer);
    virtual HRESULT STDMETHODCALLTYPE ShowObject(void);
    virtual HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL fShow);
    virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(void);
//IDocHostUIHandler
    //返回0,则不弹出鼠标右键菜单,其他功能未知
    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);
//  HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable);//重复了
    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);
//IOleInPlaceSite
    virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void);
    virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void);
    virtual HRESULT STDMETHODCALLTYPE OnUIActivate(void);
    virtual HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc,
                                                        LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo);
    virtual HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtant);
    virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable);
    virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void);
    virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(void);
    virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void);
    virtual HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect);
private://内部私有变量
    IStorage *m_pStorage;               //存储根对象
    IOleObject *m_pObject;              //OLE对象
    IOleInPlaceObject   *m_pInPlaceObj; //InPlace对象
    IWebBrowser2 *m_pIWebBrowser2;      //IWebBrowser2对象
    HWND m_hDlg;                        //窗口容器
    BOOL m_bInPlaced;                   //是否替代???
    DWORD m_RefCount;                   //引用计数
    IOleInPlaceActiveObject *m_pInPlaceActiveObj;
public://公开外部可调用函数
    virtual BOOL Initialize(IN HWND hDlg/*窗体句柄,IE控件的容器*/);
    HWND GetHwnd(void);
    IOleObject* GetIOleObject(void);
    IWebBrowser2* GetIWebBrowser2(void);
    IOleInPlaceObject* GetIOleInPlaceObject(void);
    IOleInPlaceActiveObject* GetIOleInPlaceActiveObject(void);
    virtual BOOL OpenUrl(IN PWCHAR pszUrl/*Unicode*/);
    virtual VOID DoPageAction(IN _PAGE_ACT eAct);
    /*
    以HTML代码形式显示网页(新网页)
    例如:<P>这是一个图片<P><IMG src="mypic.jpg">
    注:不需要<BODY></BODY>标签
    */
    virtual BOOL PutHtmlCode(IN PWCHAR pszCode);
    virtual BOOL GetHtmlCode(OUT PWCHAR pszCode, IN OUT int *iszCount/*字符数*/);
    virtual BOOL ClickElementByID(PWCHAR pID);
    //根据控件ID设置值,用于自动填表
    virtual BOOL SetElementValueByID(IN PWCHAR pID, IN PWCHAR pszValue);
    //根据控件ID获取值
    virtual BOOL GetElementValueByID(IN PWCHAR pID, IN PWCHAR pszValue, IN OUT int *iszCount/*字符数*/);
};

#endif

/*
目前无法实现快捷键的复制/粘贴等操作
解决方法之一是用CreateWindowEx创建窗体
在后面的GetMessage中做按键判断
再向WebBrowser发送命令

粘贴命令:(参见OLECMDID枚举结构)
m_pIWebBrowser2->ExecWB(OLECMDID_PASTE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
*/

XWebBrowser.cpp

// XWebBrowser.cpp: implementation of the CXWebBrowser class.
// http://blog.csdn.net/Sidyhe
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XWebBrowser.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CXWebBrowser::CXWebBrowser()
{
    //初始化
    m_bInPlaced = FALSE;
    m_hDlg = NULL;
    m_RefCount = 0;
    m_pObject = NULL;
    m_pStorage = NULL;
#if _DEBUG
    //创建一个存储根对象
    _ASSERT(StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_DIRECT|STGM_CREATE, 0, &m_pStorage) == ERROR_SUCCESS);
    //创建OLE对象
    _ASSERT(OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, NULL, this/*万恶的继承*/, m_pStorage, (void**)&m_pObject) == ERROR_SUCCESS);
    _ASSERT(m_pObject->QueryInterface(IID_IOleInPlaceObject, (void**)&m_pInPlaceObj) == ERROR_SUCCESS);
    _ASSERT(m_pObject->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&m_pInPlaceActiveObj) == ERROR_SUCCESS);
    _ASSERT(m_pObject->QueryInterface(IID_IWebBrowser2, (void**)&m_pIWebBrowser2) == ERROR_SUCCESS);
#else
    StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_DIRECT|STGM_CREATE, 0, &m_pStorage);
    OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, NULL, this, m_pStorage, (void**)&m_pObject);
    m_pObject->QueryInterface(IID_IOleInPlaceObject, (void**)&m_pInPlaceObj);
    m_pObject->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&m_pInPlaceActiveObj);
    m_pObject->QueryInterface(IID_IWebBrowser2, (void**)&m_pIWebBrowser2);
#endif
}

CXWebBrowser::~CXWebBrowser()
{
    m_pInPlaceActiveObj->Release();//IOleInPlaceActiveObject
    m_pInPlaceObj->Release();//IOleInPlaceObject
    m_pIWebBrowser2->Release();//IWebBrowser2
    m_pObject->Close(OLECLOSE_NOSAVE);
    m_pObject->Release();
    //有必要么
    //  OleClose(m_pObject);
}

//IUnKnown

HRESULT CXWebBrowser::QueryInterface(REFIID riid, void **ppvObject)
{
    //!!!
    *ppvObject = NULL;
    if (riid == IID_IOleClientSite) *ppvObject = (IOleClientSite*)this;
    if (riid == IID_IUnknown) *ppvObject = this;
    if (riid == IID_IDispatch) *ppvObject = (IDispatch*)this;
    if (!m_bInPlaced)
    {
        if (riid == IID_IOleInPlaceSite) *ppvObject = (IOleInPlaceSite*)this;
        if (riid == IID_IOleInPlaceFrame) *ppvObject = (IOleInPlaceFrame*)this;
        if (riid == IID_IOleInPlaceUIWindow) *ppvObject = (IOleInPlaceUIWindow*)this;
    }
    if (riid == DIID_DWebBrowserEvents2) *ppvObject = (DWebBrowserEvents2*)this;
    if (riid == IID_IDocHostUIHandler) *ppvObject = (IDocHostUIHandler*)this;
    if (*ppvObject)
    {
        AddRef();
        return ERROR_SUCCESS;
    }
    else
    {
        return E_NOINTERFACE;
    }
}

ULONG CXWebBrowser::AddRef(void)
{
    InterlockedExchangeAdd((PLONG)&m_RefCount, 1);
    return ERROR_SUCCESS;
}

ULONG CXWebBrowser::Release(void)
{
#if _DEBUG
    if (InterlockedExchangeAdd((PLONG)&m_RefCount, -1) == 0) _ASSERT(0);
#else
    InterlockedExchangeAdd((PLONG)&m_RefCount, -1);
#endif
    return ERROR_SUCCESS;
}

//IDispatch

HRESULT CXWebBrowser::GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;//貌似是不支持的意思
}

HRESULT CXWebBrowser::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    return E_NOTIMPL;
}

//IOleWindow

HRESULT CXWebBrowser::GetWindow(HWND *phwnd)
{
    *phwnd = m_hDlg;
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::ContextSensitiveHelp(BOOL fEnterMode)
{
    return E_NOTIMPL;
}

//IOleInPlaceUIWindow

HRESULT CXWebBrowser::GetBorder(LPRECT lprectBorder)
{
    GetClientRect(m_hDlg, lprectBorder);
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::SetActiveObject(IOleInPlaceActiveObject *pActiveObject,LPCOLESTR pszObjName)
{
    return ERROR_SUCCESS;
}

//IOleInPlaceFrame

HRESULT CXWebBrowser::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::RemoveMenus(HMENU hmenuShared)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::SetStatusText(LPCOLESTR pszStatusText)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::EnableModeless(BOOL fEnable)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::TranslateAccelerator(LPMSG lpmsg, WORD wID)
{
    return TRUE;
}

//IOleClientSite

HRESULT CXWebBrowser::SaveObject( void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
    *ppmk = NULL;
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::GetContainer(IOleContainer **ppContainer)
{
    *ppContainer = NULL;
    return E_FAIL;
}

HRESULT CXWebBrowser::ShowObject(void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::OnShowWindow(BOOL fShow)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::RequestNewObjectLayout(void)
{
    return ERROR_SUCCESS;
}

//IDocHostUIHandler

HRESULT CXWebBrowser::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved)
{
    return TRUE;
}

HRESULT CXWebBrowser::GetHostInfo(DOCHOSTUIINFO *pInfo)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::ShowUI(DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget, IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::HideUI(void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::UpdateUI(void)
{
    return ERROR_SUCCESS;
}

//EnableModeless重复了

HRESULT CXWebBrowser::OnDocWindowActivate(BOOL fActivate)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::OnFrameWindowActivate(BOOL fActivate)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::TranslateAccelerator(LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::GetOptionKeyPath(LPOLESTR *pchKey, DWORD dw)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::GetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::GetExternal(IDispatch **ppDispatch)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::TranslateUrl(DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
{
    return ERROR_SUCCESS;
}

//IOleInPlaceSite

HRESULT CXWebBrowser::CanInPlaceActivate(void)
{
    if (m_bInPlaced)
    {
        return S_FALSE;
    }
    else
    {
        m_bInPlaced = TRUE;
        return ERROR_SUCCESS;
    }
}

HRESULT CXWebBrowser::OnInPlaceActivate(void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::OnUIActivate(void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::GetWindowContext(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
    RECT rect;

    *ppFrame = (IOleInPlaceFrame*)this;
    AddRef();
    *ppDoc = NULL;
    GetClientRect(m_hDlg, &rect);
    *lprcPosRect = rect;
    *lprcClipRect = rect;
    lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
    lpFrameInfo->hwndFrame = GetParent(m_hDlg);
    lpFrameInfo->cAccelEntries = 0;
    lpFrameInfo->fMDIApp = FALSE;
    lpFrameInfo->haccel = NULL;
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::Scroll(SIZE scrollExtant)
{
    return E_NOTIMPL;
}

HRESULT CXWebBrowser::OnUIDeactivate(BOOL fUndoable)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::OnInPlaceDeactivate(void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::DiscardUndoState(void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::DeactivateAndUndo(void)
{
    return ERROR_SUCCESS;
}

HRESULT CXWebBrowser::OnPosRectChange(LPCRECT lprcPosRect)
{
    return ERROR_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
BOOL CXWebBrowser::Initialize(HWND hDlg)
{
    RECT rect;
    IConnectionPointContainer* pCPC = NULL;
    IConnectionPoint* pCP  = NULL;
    DWORD dwCookie = 0;

    if (!m_bInPlaced)
    {
#if _DEBUG
        _ASSERT(IsWindow(hDlg));
#endif
        m_hDlg = hDlg;
        GetClientRect(m_hDlg, &rect);
        m_pObject->DoVerb(OLEIVERB_INPLACEACTIVATE, 0, (IOleClientSite *)this, 0, m_hDlg, &rect);
        m_pIWebBrowser2->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
        pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &pCP);
        pCP->Advise((IUnknown*)(void*)this, &dwCookie);
        m_bInPlaced = TRUE;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

HWND CXWebBrowser::GetHwnd()
{
    return m_hDlg;
}

IOleObject* CXWebBrowser::GetIOleObject()
{
    return m_pObject;
}

IWebBrowser2* CXWebBrowser::GetIWebBrowser2()
{
    return m_pIWebBrowser2;
}

IOleInPlaceObject* CXWebBrowser::GetIOleInPlaceObject()
{
    return m_pInPlaceObj;
}

IOleInPlaceActiveObject* CXWebBrowser::GetIOleInPlaceActiveObject()
{
    return m_pInPlaceActiveObj;
}

BOOL CXWebBrowser::OpenUrl(PWCHAR pszUrl)
{
    BOOL bRet = FALSE;
    VARIANT vUrl;

    if (pszUrl == NULL) return bRet;
    VariantInit(&vUrl);
    vUrl.vt = VT_BSTR;
    vUrl.bstrVal = SysAllocString(pszUrl);
    if (vUrl.bstrVal)
    {
        m_pIWebBrowser2->Navigate2(&vUrl, NULL, NULL, NULL, NULL);
        VariantClear(&vUrl);
        bRet = TRUE;
    }
    return bRet;
}

VOID CXWebBrowser::DoPageAction(_PAGE_ACT eAct)
{
    switch (eAct)
    {
    case PAGE_GOBACK:
        m_pIWebBrowser2->GoBack();
        break;
    case PAGE_GOFORWARD:
        m_pIWebBrowser2->GoForward();
        break;
    case PAGE_GOHOME:
        m_pIWebBrowser2->GoHome();
        break;
    case PAGE_SEARCH:
        m_pIWebBrowser2->GoSearch();
        break;
    case PAGE_REFRESH:
        m_pIWebBrowser2->Refresh();
        break;
    case PAGE_STOP:
        m_pIWebBrowser2->Stop();
        break;
    }
    return;
}

BOOL CXWebBrowser::PutHtmlCode(PWCHAR pszCode)
{
    BOOL bRet = FALSE;
    VARIANT vUrl;
    IDispatch *pDispatch = NULL;
    IHTMLDocument2 *htmlDoc2 = NULL;
    SAFEARRAY *sfArray = NULL;
    SAFEARRAYBOUND ArrayBound = {1, 0};
    VARIANT *pVar = NULL;

    if (pszCode == NULL) return bRet;
    __try
    {
        VariantInit(&vUrl);
        vUrl.vt = VT_BSTR;
        vUrl.bstrVal = SysAllocString(L"about:blank");
        if (!vUrl.bstrVal) __leave;
        m_pIWebBrowser2->Navigate2(&vUrl, NULL, NULL, NULL, NULL);
        VariantClear(&vUrl);
        if (m_pIWebBrowser2->get_Document(&pDispatch) != ERROR_SUCCESS) __leave;
        if (pDispatch == NULL) __leave;
        if (pDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDoc2) != ERROR_SUCCESS) __leave;
        if (htmlDoc2 == NULL) __leave;
        sfArray = SafeArrayCreate(VT_VARIANT, 1, (SAFEARRAYBOUND *)&ArrayBound);
        if (sfArray == NULL) __leave;
        if (SafeArrayAccessData(sfArray, (void**)&pVar) != ERROR_SUCCESS) __leave;
        pVar->vt = VT_BSTR;
        pVar->bstrVal = SysAllocString(pszCode);
        htmlDoc2->write(sfArray);
        htmlDoc2->close();
        SafeArrayDestroy(sfArray);
        bRet = TRUE;
    }
    __finally
    {
        if (htmlDoc2) htmlDoc2->Release();
        if (pDispatch) pDispatch->Release();
    }
    return bRet;
}

BOOL CXWebBrowser::GetHtmlCode(PWCHAR pszCode, int *iszCount)
{
    BOOL bRet = FALSE;
    IDispatch *pDispatch = NULL;
    IHTMLDocument2 *htmlDoc2 = NULL;
    IHTMLElement *pBodyElement = NULL;
    PWCHAR pHtmlCode = NULL;
    int iLen = 0;

    if (pszCode == NULL || iszCount == NULL) return bRet;
    __try
    {
        if (m_pIWebBrowser2->get_Document(&pDispatch) != ERROR_SUCCESS) __leave;
        if (pDispatch == NULL) __leave;
        if (pDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDoc2) != ERROR_SUCCESS) __leave;
        if (htmlDoc2 == NULL) __leave;
        htmlDoc2->get_body(&pBodyElement);
        if (pBodyElement == NULL) __leave;
        pBodyElement->get_innerHTML(&pHtmlCode);
        if (pHtmlCode == NULL) __leave;
        iLen = lstrlenW(pHtmlCode) + 1;//还有个‘\0‘
        if (pszCode)
        {
            if (*iszCount >= iLen)
            {
                ZeroMemory(pszCode, *iszCount * sizeof(WCHAR));
                CopyMemory(pszCode, pHtmlCode, iLen * sizeof(WCHAR));
            }
        }
        else
        {
            *iszCount = iLen;
            __leave;
        }
        bRet = TRUE;
    }
    __finally
    {
        if (pBodyElement) pBodyElement->Release();
        if (htmlDoc2) htmlDoc2->Release();
        if (pDispatch) pDispatch->Release();
    }
    return bRet;
}

BOOL CXWebBrowser::ClickElementByID(PWCHAR pID)
{
    BOOL bRet = FALSE;
    IDispatch *pDispatch = NULL;
    IHTMLDocument3 *htmlDoc3 = NULL;
    IHTMLElement *pElement = NULL;

    if (pID == NULL) return bRet;
    __try
    {
        if (m_pIWebBrowser2->get_Document(&pDispatch) != ERROR_SUCCESS) __leave;
        if (pDispatch == NULL) __leave;
        if (pDispatch->QueryInterface(IID_IHTMLDocument3, (void**)&htmlDoc3) != ERROR_SUCCESS) __leave;
        if (htmlDoc3 == NULL) __leave;
        htmlDoc3->getElementById(pID, &pElement);
        if (pElement == NULL) __leave;
        pElement->click();
        bRet = TRUE;
    }
    __finally
    {
        if (pElement) pElement->Release();
        if (htmlDoc3) htmlDoc3->Release();
        if (pDispatch) pDispatch->Release();
    }
    return bRet;
}

BOOL CXWebBrowser::SetElementValueByID(PWCHAR pID, PWCHAR pszValue)
{
    BOOL bRet = FALSE;
    IDispatch *pDispatch = NULL;
    IHTMLDocument3 *htmlDoc3 = NULL;
    IHTMLElement *pElement = NULL;
    VARIANT variant;

    if (pID == NULL || pszValue == NULL) return bRet;
    __try
    {
        if (m_pIWebBrowser2->get_Document(&pDispatch) != ERROR_SUCCESS) __leave;
        if (pDispatch == NULL) __leave;
        if (pDispatch->QueryInterface(IID_IHTMLDocument3, (void**)&htmlDoc3) != ERROR_SUCCESS) __leave;
        if (htmlDoc3 == NULL) __leave;
        htmlDoc3->getElementById(pID, &pElement);
        if (pElement == NULL) __leave;
        VariantInit(&variant);
        variant.vt = VT_BSTR;
        variant.bstrVal = SysAllocString(pszValue);
        if (variant.bstrVal == NULL) __leave;
        pElement->setAttribute(L"value", variant);
        VariantClear(&variant);
        bRet = TRUE;
    }
    __finally
    {
        if (pElement) pElement->Release();
        if (htmlDoc3) htmlDoc3->Release();
        if (pDispatch) pDispatch->Release();
    }
    return bRet;
}

BOOL CXWebBrowser::GetElementValueByID(PWCHAR pID, PWCHAR pszValue, int *iszCount/*字符数*/)
{
    BOOL bRet = FALSE;
    IDispatch *pDispatch = NULL;
    IHTMLDocument3 *htmlDoc3 = NULL;
    IHTMLElement *pElement = NULL;
    VARIANT variant;
    int iLen;

    if (iszCount == NULL) return bRet;
    __try
    {
        if (m_pIWebBrowser2->get_Document(&pDispatch) != ERROR_SUCCESS) __leave;
        if (pDispatch == NULL) __leave;
        if (pDispatch->QueryInterface(IID_IHTMLDocument3, (void**)&htmlDoc3) != ERROR_SUCCESS) __leave;
        if (htmlDoc3 == NULL) __leave;
        htmlDoc3->getElementById(pID, &pElement);
        if (pElement == NULL) __leave;
        VariantInit(&variant);
        pElement->getAttribute(L"value", 0, &variant);
        iLen = lstrlenW(variant.bstrVal) + 1;
        if (*iszCount >= iLen && pszValue)
        {
            ZeroMemory(pszValue, *iszCount * sizeof(WCHAR));
            CopyMemory(pszValue, variant.bstrVal, iLen * sizeof(WCHAR));
        }
        else
        {
            *iszCount = iLen;
            VariantClear(&variant);
            __leave;
        }
        VariantClear(&variant);
        bRet = TRUE;
    }
    __finally
    {
        if (pElement) pElement->Release();
        if (htmlDoc3) htmlDoc3->Release();
        if (pDispatch) pDispatch->Release();
    }
    return bRet;
}

然后创建一个窗口程序,调用上面的lib文件代码如下.

//////////////////////////////////////////////////////////////////////////
// 

#include "XWebBrowser.h"

static const char  ClassName[] = "Browser Example";
CXWebBrowser *cWeb = NULL;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    //WCHAR szC[100];
    int szi = 1;

    if (uMsg == WM_CLOSE)
    {
        PostQuitMessage(0);
        return 0;
    }
    if (uMsg == WM_HOTKEY)
    {
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstNULL, LPSTR lpszCmdLine, int nCmdShow)
{
    MSG msg;  

    if (OleInitialize(NULL) == S_OK)
    {
        WNDCLASSEX wc;

        ZeroMemory(&wc, sizeof(WNDCLASSEX));
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.hInstance = hInstance;
        wc.lpfnWndProc = WindowProc;
        wc.lpszClassName = &ClassName[0];
        RegisterClassEx(&wc);
        if ((msg.hwnd = CreateWindowEx(0, &ClassName[0], "百度", WS_OVERLAPPEDWINDOW, 0, 0, 1024, 768, HWND_DESKTOP, NULL, hInstance, NULL)))
        {
            cWeb = new CXWebBrowser();

            cWeb->Initialize(msg.hwnd);
            cWeb->OpenUrl(L"http://www.baidu.com");
            RegisterHotKey(msg.hwnd, 0x512, 0, VK_F1);
            ShowWindow(msg.hwnd, nCmdShow);
            UpdateWindow(msg.hwnd);
        }
        while (GetMessage(&msg, 0, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        OleUninitialize();
        return(0);
    }
    MessageBox(0, "Can‘t open OLE!", "ERROR", MB_OK);

    return 0;
}

调用lib方法如图

时间: 2024-07-31 14:06:05

C++之WebBrowser容器,SDK实现的相关文章

使用C++实现SDK之WebBrowser容器

转自http://blog.csdn.net/norsd/article/details/2921389 一.由来 我还记还得当自认为学习完了C++语法后, 兴致勃勃的打开MFC向导,开始所谓"MFC高级自动化编程"时, 我不由喊道: 这他妈的都是些什么乱七八糟的东西啊.诚然,MFC为了方便愚蠢的程序员,的确是让人瞬间高级编程, 可是愚蠢的我们还是会用CString strTest;写出(PWSTR)strTest.GetBuffer() 这种自作聪明的用法,结果就是整个程序好像发了疯

[转帖]Hyperledger Fabric 学习一:简介

Hyperledger Fabric 学习一:简介 https://www.jianshu.com/p/f971858b70f3?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation 1.Hyperledger简介 Hyperledger:超级账本,是首个面向企业应用场景的分布式账本平台,包括了:IBM.Intel.Cisco.DAH.摩根大通.R3等在内的众多科

《ArcGIS Runtime SDK for Android开发笔记》——(9)、空间数据的容器-地图MapView

1.前言 在上一篇内容里介绍了 关于ArcGIS Android开发的未来(“Quartz”版Beta)相关内容,期间也提到了关于API接口的重构,开发思路的调整,根据2015UC资料也可以知道新版预计将在明年的时候推出.届时在开发思路上将会往新版迁移. 总的来说,虽然“Quartz”版的开发思路有所变化,但总体变化不大,这里我将继续以现有正式发布版本为主梳理ArcGIS Runtime SDK for Android 开发内容. 参考API版本号:version 10.2.7.后续内容若不做特

HyperLedger/Fabric SDK使用Docker容器镜像快速部署上线

HyperLedger/Fabric SDK Docker Image 该项目在github上的地址是:https://github.com/aberic/fabric-sdk-container (感谢Star). 这是一个基于fabric-sdk-java的项目,该项目的主要目的是简化HyperLedger/Fabric开发人员在SDK应用层上的工作流程,使得开发和部署更加简单. 该项目使用方便,只需要你的服务器上部署有Docker及docker compose环境即可,通过docker-c

c#winform使用WebBrowser 大全

C# WinForm WebBrowser (一) MSDN资料 1.主要用途:使用户可以在窗体中导航网页. 2.注意:WebBrowser 控件会占用大量资源.使用完该控件后一定要调用 Dispose 方法,以便确保及时释放所有资源.必须在附加事件的同一线程上调用 Dispose 方法,该线程应始终是消息或用户界面 (UI) 线程. 3.WebBrowser 使用下面的成员可以将控件导航到特定 URL.在导航历史记录列表中向后和向前移动,还可以加载当前用户的主页和搜索页: 1.URL属性:可读

如何控制WebBrowser控件不下载图片

Sidyhe在http://blog.csdn.net/sidyhe/article/details/9073485 一文中,利用C++以及Windows SDK实现了WebBrowser控件的容器. 我们可以在Sidyhe的基础上,简单修改CXWebBrowser类,即可控制其在访问页面时,不下载图片(对其他下载资源的控制可参照图片的). 具体实现只要修改Invoke函数即可,原来的Invoke函数如下: HRESULT CXWebBrowser::Invoke(DISPID dispIdMe

运维之我的docker-python sdk

安装docker的python sdk [[email protected] ~]# pip install docker 这里从最简单的运行一个容器开始,在容器里面运行一段命令"echo "hello" "world"" In [1]: import docker   In [2]: client = docker.from_env()   In [3]: print client.containers.run("redis"

【重要更新】Senparc.Weixin SDK v4.3.3升级说明

为了更好地适应微信越来越快的API更新速度和越来越多的API数量,本次Senparc.Weixin.dll v4.3.3对一些通用功能进行了深度的重构. 本次更新同时影响以下所有Senparc.Weixin相关版本的dll: Senparc.Weixin.dll 升级到 v4.3.3 Senparc.Weixin.MP.dll 升级到 v13.3.0(重要) Senparc.Weixin.MP.MvcExtension.dll 升级到 v1.4.1 Senparc.Weixin.Open 升级到

WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下?

原文:WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下? 一.问题的提出 偶然发现,Winform里的WebBrowser和IE实际安装的版本似乎并不同步,很有趣! 下面有张图,里面一个窗口是用IE9打开某网站,另一个窗口是用Winform+WebBrowser打开同样的网站,有意思的事情出现了. 在IE9窗口中,这个网站左边菜单树无法显示,原因是IE9使用的技术较新,而网站使用的技术较旧,未能及时同步更新到支持IE9所致.该如何办呢? 微软在IE9中提供一个兼容