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方法如图
技术分享
技术分享
技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。