在 mfc 中控制 web browser

    在很多 application 中,我使用了 browser + html. 好处很多,比如完成复杂的图文显示,预览,打印等等功能。在 VB6 或 C# 中通过 html Document 来控制browser 很简单,但在 mfc 中稍微有些复杂,于是我封装了 IHtmelDocument2 接口,用 exception 来捕获错误,这样,在 mfc 中使用IHtmelDocument2 变得相当简单了。
 
例如,我的网上赚钱程序中一段自动 login 的代码:
 
void CAutoSearchView::OnFileLogin()
{
            try {
                        m_Doc.Navigate(m_strLogin[0]);
                        IHTMLElementCollection* pAll = m_Doc.GetAll();
                        IHTMLElementCollection* pInputs = m_Doc.GetCollectionTags(pAll, "input");
                        m_Doc.SetInputText(pInputs, m_strLogin[1], m_strLogin[2]);
                        m_Doc.SetInputText(pInputs, m_strLogin[3], m_strLogin[4]);
                        IHTMLElement* pSubmit = m_Doc.GetCollectionItem(pInputs, m_strLogin[5]);
                        if (pSubmit != NULL) {
                                    pSubmit->click();
                        }
            }
            catch(...)
            {
                        ShowInformation("Login error");                     
            }
}
 
 
 
Source code of HtmlDocument.H
 
#pragma once
 
#include "mshtml.h"
#include "comdef.h"
#include <afxdisp.h>
 
namespace HtmlFunctions
{
            typedef HRESULT (__stdcall IHTMLDocument2::*PFUNC_DOC_COLLECTION)(IHTMLElementCollection**);
            typedef HRESULT (__stdcall IHTMLDocument2::*PFUNC_DOC_ELEMENT)(IHTMLElement**);
            typedef HRESULT (__stdcall IHTMLDocument2::*PFUNC_DOC_GETTEXT)(BSTR*);
            typedef HRESULT (__stdcall IHTMLDocument2::*PFUNC_DOC_PUTTEXT)(BSTR);
 
            typedef HRESULT (__stdcall IHTMLElement::*PFUNC_ELEMENT_COLLECTION)(IHTMLElementCollection**);
            typedef HRESULT (__stdcall IHTMLElement::*PFUNC_ELEMENT_ELEMENT)(IHTMLElement**);
            typedef HRESULT (__stdcall IHTMLElement::*PFUNC_ELEMENT_GETTEXT)(BSTR*);
            typedef HRESULT (__stdcall IHTMLElement::*PFUNC_ELEMENT_PUTTEXT)(BSTR);
};
 
using namespace HtmlFunctions;
 
class CHtmlDocument
{
            CHtmlView*                                                  m_pHtmlView;
            IHTMLDocument2*                                         m_pHtmlDoc;
            IHTMLElement*                                              m_pHtmlElement;
            IHTMLElementCollection*                  m_pHtmlElementCollection;
            IHTMLElementCollection*                  m_pAllElements;
 
            CString                                                             m_strText;
 
            static void DoEvents();
 
public:
            bool                                                                 m_bOnNavigateCompleted;
            bool                                                                 m_bEnableException;
 
public:
            CHtmlDocument();
            ~CHtmlDocument(void);
 
private:
            IHTMLElementCollection*                  GetCollection(PFUNC_DOC_COLLECTION pDocFunction);
            IHTMLElement*                                              GetElement(PFUNC_DOC_ELEMENT pDocFunction);
 
            CString&                                                         GetString(IHTMLElement* pHtmlElement,
                                                                                                PFUNC_ELEMENT_GETTEXT pDocFunction);
            void                                                                  PutString(IHTMLElement* pHtmlElement,
                                                                                                PFUNC_ELEMENT_PUTTEXT pDocFunction, LPCTSTR strText);
 
public:
            IHTMLElementCollection*                  GetCollectionTags(IHTMLElementCollection* pElementCollection,
                                                                                                LPCTSTR strKey);
            IHTMLElement*                                              GetCollectionItem(IHTMLElementCollection* pElementCollection,
                                                                                                LPCTSTR strKey, int index=0);
            IHTMLElement*                                              GetCollectionItem(IHTMLElementCollection* pElementCollection,
                                                                                                int index);
            int                                                                                 GetCollectionLength(IHTMLElementCollection* pElementCollection);                                                               
 
 
public:
            IHTMLDocument2* CHtmlDocument::GetHtmlDocument();
            void SetHtmlView(CHtmlView* pHtmlView);
            bool Navigate(LPCTSTR strUrl);
 
            bool SetInputText(IHTMLElementCollection* pCollection, LPCTSTR strKey, LPCTSTR text);
            bool SubmitForm(LPCTSTR strForm);
 
            IHTMLElementCollection*                  GetAll(void) { return GetCollection(IHTMLDocument2::get_all); }
            IHTMLElement*                                              GetBody(void) { return GetElement(IHTMLDocument2::get_body); }
 
};
 
 
 
CPP File:
 
#include "StdAfx.h"
#include "./htmldocument.h"
 
#define THROWEXCEPTION if (m_bEnableException) ::AfxThrowUserException()
#define CHECK(s) if ((s) != S_OK) THROWEXCEPTION
#define NotNULL(p) if (p == NULL) THROWEXCEPTION
#define CHECK_RET(s) if ((s) != S_OK) return false
#define NULL_RET(p) if (p == NULL) return false
 
 
CHtmlDocument::CHtmlDocument()
{
            m_pHtmlView = NULL;
            m_bEnableException = true;
}
 
CHtmlDocument::~CHtmlDocument(void)
{
}
 
void CHtmlDocument::SetHtmlView(CHtmlView* pHtmlView)
{
            ASSERT(pHtmlView);
            m_pHtmlView = pHtmlView;
}
 
IHTMLDocument2* CHtmlDocument::GetHtmlDocument()
{
            ASSERT(m_pHtmlView);
            try {
                        IDispatch* pDisp = m_pHtmlView->GetHtmlDocument();
                        if (pDisp != NULL ) {
                                    CHECK(pDisp->QueryInterface(IID_IHTMLDocument2, (void**) &m_pHtmlDoc));
                        }
                        NotNULL(m_pHtmlDoc);
            }
            catch (...) {
                        return NULL;
            }
 
            return m_pHtmlDoc;
}
 
/**************************************************************************************************
            IHTMLDocument2 Functions
**************************************************************************************************/
IHTMLElementCollection*             CHtmlDocument::GetCollection(PFUNC_DOC_COLLECTION pDocFunction)
{
            NotNULL(m_pHtmlDoc);
            CHECK((m_pHtmlDoc->*pDocFunction)(&m_pHtmlElementCollection));
            NotNULL(m_pHtmlElementCollection);
            return m_pHtmlElementCollection;
}
 
IHTMLElement* CHtmlDocument::GetElement(PFUNC_DOC_ELEMENT pDocFunction)
{
            NotNULL(m_pHtmlDoc);
            CHECK((m_pHtmlDoc->*pDocFunction)(&m_pHtmlElement));
            NotNULL(m_pHtmlElement);
            return m_pHtmlElement;
}
 
/**************************************************************************************************
            IHTMLElementCollection Functions
**************************************************************************************************/
IHTMLElementCollection* CHtmlDocument::GetCollectionTags
(
            IHTMLElementCollection* pElementCollection, LPCTSTR strKey
)
{
            NotNULL(pElementCollection);
            IDispatch* pDisp;
            CHECK(pElementCollection->tags(COleVariant(strKey), &pDisp));
            if (pDisp == NULL) return NULL;
            CHECK(pDisp->QueryInterface(IID_IHTMLElementCollection, (void**) &m_pHtmlElementCollection));
            return m_pHtmlElementCollection;
}
 
IHTMLElement* CHtmlDocument::GetCollectionItem
(
            IHTMLElementCollection* pElementCollection, LPCTSTR strKey, int index
)
{
            NotNULL(pElementCollection);
            IDispatch* pDisp;
            CHECK(pElementCollection->item(COleVariant(strKey), COleVariant((long) index), &pDisp));
            if (pDisp == NULL) return NULL;
            CHECK(pDisp->QueryInterface(IID_IHTMLElement, (void**) &m_pHtmlElement));
            return m_pHtmlElement;
}
 
IHTMLElement* CHtmlDocument::GetCollectionItem(IHTMLElementCollection* pElementCollection, int index)
{
            NotNULL(pElementCollection);
            IDispatch* pDisp;
            CHECK(pElementCollection->item(COleVariant((long) index), COleVariant((long) 0), &pDisp));
            if (pDisp == NULL) return NULL;
            CHECK(pDisp->QueryInterface(IID_IHTMLElement, (void**) &m_pHtmlElement));
            return m_pHtmlElement;
}
 
int CHtmlDocument::GetCollectionLength(IHTMLElementCollection* pElementCollection)
{
            NotNULL(pElementCollection);
            long length;
            CHECK(pElementCollection->get_length(&length));
            return length;
}
 
 
/**************************************************************************************************
            IHTMLElement Functions
**************************************************************************************************/
CString& CHtmlDocument::GetString(IHTMLElement* pHtmlElement, PFUNC_ELEMENT_GETTEXT pDocFunction)
{
            BSTR str;
            CHECK((pHtmlElement->*pDocFunction)(&str));
            m_strText = str;
            return m_strText;
}
 
void CHtmlDocument::PutString(IHTMLElement* pHtmlElement, PFUNC_ELEMENT_PUTTEXT pDocFunction, LPCTSTR strText)
{
            CHECK((pHtmlElement->*pDocFunction)(_bstr_t(strText)));
}
 
/**************************************************************************************************
**************************************************************************************************/
 
bool CHtmlDocument::SetInputText(IHTMLElementCollection* pCollection, LPCTSTR strKey, LPCTSTR text)
{
            NULL_RET(pCollection);
            IDispatch* pDisp;
            IHTMLInputTextElement* pElement;
            CHECK_RET(pCollection->item(COleVariant(strKey), COleVariant((long) 0), &pDisp));
            if (pDisp == NULL) return false;
            CHECK_RET(pDisp->QueryInterface(IID_IHTMLInputTextElement, (void**) &pElement));
            NULL_RET(pElement);
 
            CHECK_RET(pElement->put_value(_bstr_t(text)));
            return true;
}
 
 
bool CHtmlDocument::Navigate(LPCTSTR strUrl)
{
            m_bOnNavigateCompleted = false;
            m_pHtmlDoc = NULL;
            m_pHtmlElementCollection = NULL;
            m_pHtmlElement = NULL;
            m_pHtmlView->Navigate2(strUrl);
           
            DWORD timetick = ::GetTickCount();
            while (! m_bOnNavigateCompleted) {
                        DoEvents();
                        ::Sleep(10);
                        if (::GetTickCount() > timetick + 20000) {
                                    THROWEXCEPTION;
                                    return false;
                        }
            }
            GetHtmlDocument();
            return true;
}
 
 
void CHtmlDocument::DoEvents()
{
            MSG            msg;
            if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
                        if (msg.message == WM_QUIT) {
                                    ::PostMessage( NULL, WM_QUIT, 0, 0);
                        }
                        if (msg.message != WM_COMMAND) {
                                    ::TranslateMessage(&msg);
                                    ::DispatchMessage(&msg);
                        }
            }         
}
 
 
bool CHtmlDocument::SubmitForm(LPCTSTR strForm)
{
            return false;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值