对Dialog添加视图CHtmlView,并获取滚动条的滚动范围

来源:互联网 发布:免费虚拟局域网软件 编辑:程序博客网 时间:2024/05/16 04:50

View头文件WebView.h:

#ifndef __WEBVIEW_H__#define __WEBVIEW_H__#pragma onceclass CWebView : public CHtmlView{public: // 仅从序列化创建CWebView();virtual ~CWebView();DECLARE_DYNCREATE(CWebView)// 操作public:int GetScrollHeight();// 返回滚动条的高度// 对于有多个iframe的网页,所有页面加载完成,调用该方法,只调用一次static void OnLoad(VARIANT *pVarResult, LONG_PTR lpUserData);// 重写public:virtual BOOL PreCreateWindow(CREATESTRUCT& cs);virtual void OnInitialUpdate(); // 构造后第一次调用// 页面加载完成调用,对于有多个iframe的网页,可能会调用多次virtual void OnDocumentComplete(LPCTSTR lpszURL);#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endif// 生成的消息映射函数protected:DECLARE_MESSAGE_MAP()};#endif // __WEBVIEW_H__

实现WebView.c:

// WebView.cpp : implementation file//#include "stdafx.h"#include "WebView.h"#include "DOMEventHandler.h"#include <afxctl.h>#ifdef _DEBUG#define new DEBUG_NEW#endif// CWebViewIMPLEMENT_DYNCREATE(CWebView, CHtmlView)BEGIN_MESSAGE_MAP(CWebView, CHtmlView)// 标准打印命令ON_COMMAND(ID_FILE_PRINT, &CHtmlView::OnFilePrint)END_MESSAGE_MAP()// CBENBEN_IEView 构造/析构CWebView::CWebView(){}CWebView::~CWebView(){}BOOL CWebView::PreCreateWindow(CREATESTRUCT& cs){return CHtmlView::PreCreateWindow(cs);}// 构造后第一次调用void CWebView::OnInitialUpdate(){CHtmlView::OnInitialUpdate();}// 获取滚动条的高度int CWebView::GetScrollHeight(){CWebView *pView = (CWebView *)this;HRESULT hr;CComPtr<IDispatch> spDisp;// 获取COM组件的IDispatch的接口spDisp = pView->GetHtmlDocument();if (!spDisp)return 0;// 查询IID为IID_IHTMLDocument2的接口IHTMLDocument2 *pHtmlDoc = NULL;hr = spDisp->QueryInterface(IID_IHTMLDocument2, (void **)&pHtmlDoc);ASSERT(SUCCEEDED(hr));if (!pHtmlDoc)return 0;// 取得IHTMLElement类型的body接口IHTMLElement *pHtmlElement = NULL;hr = pHtmlDoc->get_body(&pHtmlElement);ASSERT(SUCCEEDED(hr));if (!pHtmlElement)return 0;// 查询IID为IID_IHTMLElement2的接口IHTMLElement2 *pHtmlElement2 = NULL;hr = pHtmlElement->QueryInterface(IID_IHTMLElement2, (void **)&pHtmlElement2);ASSERT(SUCCEEDED(hr));if (!pHtmlElement2)return 0;// 取得网页中滚动条的滚动范围long lScrollHeight;pHtmlElement2->get_scrollHeight(&lScrollHeight);return lScrollHeight;}// 页面加载完成调用,对于有多个iframe的网页,可能会调用多次void CWebView::OnDocumentComplete( LPCTSTR lpszURL ){IHTMLDocument *pHtmlDoc = (IHTMLDocument *)GetHtmlDocument();CComQIPtr<IHTMLDocument2> pHtmlDoc2(pHtmlDoc);if(pHtmlDoc2){CComPtr<IHTMLWindow2> pHtmlWnd2;pHtmlDoc2->get_parentWindow(&pHtmlWnd2);if(pHtmlWnd2){VARIANT vEvent = CDOMEventHandler::CreateEventHandlerVariant(&CWebView::OnLoad, (LONG_PTR)this);pHtmlWnd2->put_onload(vEvent);}}CHtmlView::OnDocumentComplete(lpszURL);}// 对于有多个iframe的网页,所有页面加载完成,调用该方法,只调用一次void CWebView::OnLoad( VARIANT *pVarResult, LONG_PTR lpUserData ){CWebView *pWebView = reinterpret_cast<CWebView *>(lpUserData);}

DOMEventHandler.h 为判断网页是否加载完成而添加的类

#ifndef __DOMEVENTHANDLER_H__#define __DOMEVENTHANDLER_H__#pragma oncetypedef void (*PFN_DOM_EVENT_CALLBACK)(VARIANT* pVarResult, LONG_PTR lpUserData);class CDOMEventHandler : public IDispatch{public:CDOMEventHandler(PFN_DOM_EVENT_CALLBACK pfnCallback, LONG_PTR lpUserData);~CDOMEventHandler(void);HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject);DWORD __stdcall AddRef();DWORD __stdcall Release();STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo){ return E_NOTIMPL; }STDMETHOD(GetTypeInfo)(unsigned int iTInfo, LCID  lcid, ITypeInfo FAR* FAR*  ppTInfo){ return E_NOTIMPL; }STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId) { return S_OK; }STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr);  static LPDISPATCH CreateEventHandler(PFN_DOM_EVENT_CALLBACK pfnCallback, LONG_PTR lpUserData);static VARIANT CreateEventHandlerVariant(PFN_DOM_EVENT_CALLBACK pfnCallback, LONG_PTR lpUserData);private:PFN_DOM_EVENT_CALLBACK  m_pfCallback;long                    m_lRefCount;LONG_PTR                m_lpUserData;};#endif // __DOMEVENTHANDLER_H__


DOMEventHandler.cpp 为判断网页是否加载完成而添加的类
// DOMEventHandler.cpp : implementation file//#include "StdAfx.h"#include "DOMEventHandler.h"CDOMEventHandler::CDOMEventHandler(PFN_DOM_EVENT_CALLBACK pfnCallback, LONG_PTR lpUserData): m_lRefCount(0), m_pfCallback(pfnCallback), m_lpUserData(lpUserData){}CDOMEventHandler::~CDOMEventHandler(void){}HRESULT __stdcall CDOMEventHandler::QueryInterface(REFIID riid, void** ppvObject){*ppvObject = NULL;if (IsEqualGUID(riid, IID_IUnknown))*ppvObject = reinterpret_cast<void**>(this);if (IsEqualGUID(riid, IID_IDispatch))*ppvObject = reinterpret_cast<void**>(this);if (*ppvObject){((IUnknown*)*ppvObject)->AddRef();return S_OK;}else{return E_NOINTERFACE;}}DWORD __stdcall CDOMEventHandler::AddRef(){return InterlockedIncrement(&m_lRefCount);}DWORD __stdcall CDOMEventHandler::Release(){if (InterlockedDecrement(&m_lRefCount) == 0){delete this;return 0;}return m_lRefCount;}HRESULT CDOMEventHandler::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr){if (dispIdMember == DISPID_VALUE){if( m_pfCallback )(*m_pfCallback)(pVarResult, m_lpUserData);}return S_OK;}LPDISPATCH CDOMEventHandler::CreateEventHandler(PFN_DOM_EVENT_CALLBACK pfnCallback, LONG_PTR lpUserData){CDOMEventHandler * pHandler = new CDOMEventHandler( pfnCallback, lpUserData);return reinterpret_cast<LPDISPATCH>(pHandler);}VARIANT CDOMEventHandler::CreateEventHandlerVariant(PFN_DOM_EVENT_CALLBACK pfnCallback, LONG_PTR lpUserData){VARIANT variant;variant.vt = VT_DISPATCH;variant.pdispVal = CDOMEventHandler::CreateEventHandler( pfnCallback, lpUserData);return variant;}

最后在CMyDialog::OnInitDialog()中添加:

// 创建并加载网页视图m_pWebView = new CWebView;m_pWebView->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, rcWebView, this, 2009);m_pWebView->ShowWindow(SW_HIDE);Navigate2("www.baidu.com",NULL,NULL);


原创粉丝点击