【问题标题】:problem with IHTMLDocument2::write()IHTMLDocument2::write() 的问题
【发布时间】:2010-10-18 00:10:12
【问题描述】:

我正在尝试从 html 缓冲区创建一个 mshtml 文档对象。但是当执行以下代码时,它正在调用 Internet Explorer 窗口。如何防止它调用 IE。

#include <atlbase.h>
#include <mshtml.h>


CoInitialize(NULL);

CString strHTMLCode = _T("<html><head><script language=\"JavaScript\">{top.location.href=\"index.php\"}</script></head><body></body></html>");

CComPtr<IHTMLDocument2> pDoc;
HRESULT hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IHTMLDocument2, (void**)&pDoc);

SAFEARRAY* psa = SafeArrayCreateVector(VT_VARIANT, 0, 1);
VARIANT *param;

hr = SafeArrayAccessData(psa, (LPVOID*)¶m);
param->vt = VT_BSTR;
param->bstrVal = strHTMLCode.AllocSysString();

hr = pDoc->write(psa); //This line invoks internet explorer window.
hr = pDoc->close();

【问题讨论】:

  • 你想要完成什么?你有没有注意到,如果你删除了 javascript,IE 就不会启动?
  • 我正在编写一个应用程序来使用 IHTMLDocument2 接口解析网页。我观察到,当我解析某些包含 java 脚本的网页时,它会从我的应用程序中调用 IE 窗口。基本上我想使用 IHTMLDocument2 静默解析网页。

标签: c++ com mfc visual-c++-6 mshtml


【解决方案1】:
OLECHAR szHTML[] = OLESTR("<HTML><BODY>Hello World!</BODY></HTML>");

IHTMLDocument2 *pDoc = NULL;
CoInitialize(NULL);
CoCreateInstance(CLSID_HTMLDocument,
               NULL,
               CLSCTX_INPROC_SERVER,
               IID_IHTMLDocument2,
               (LPVOID *)&pDoc);
if(pDoc)
{
    IPersistStreamInit *pPersist = NULL;
    pDoc->QueryInterface(IID_IPersistStreamInit, (LPVOID *) &pPersist);
    if(pPersist)
    {
        IMarkupServices *pMarkSvr = NULL;
        pPersist->InitNew();
        pPersist->Release();
        pDoc->QueryInterface(IID_IMarkupServices, (LPVOID *)&pMarkSvr);
        if(pMarkSvr)
        {
            IMarkupContainer *pMkContainer = NULL;
            IMarkupPointer *pMkStart = NULL;
            IMarkupPointer *pMkFinish = NULL;
            pMarkSvr->CreateMarkupPointer(&pMkStart);
            pMarkSvr->CreateMarkupPointer(&pMkFinish);
            pMarkSvr->ParseString(szHTML, 0, &pMkContainer, pMkStart, pMkFinish);
            if(pMkContainer)
            {
                IHTMLDocument2 *pNewDoc = NULL;
                pMkContainer->QueryInterface(IID_IHTMLDocument, (LPVOID *)&pNewDoc);
                if(pNewDoc)
                {
                    // do anything with pNewDoc, in this case
                    // get the body innerText.
                    IHTMLElement *pBody;
                    pNewDoc->get_body(&pBody);
                    if(pBody)
                    {
                        BSTR strText;
                        pBody->get_innerText(&strText);
                        ShowMessage(strText);
                        pBody->Release();
                        SysFreeString(strText);
                    }
                    pNewDoc->Release();
                }
                pMkContainer->Release();
            }
            if(pMkStart)
                pMkStart->Release();
            if(pMkFinish)
                pMkFinish->Release();
            pMarkSvr->Release();
        }
    }
    pDoc->Release();
}
CoUninitialize();

参考:http://www.codeguru.com/cpp/i-n/ieprogram/article.php/c4385/Lightweight-HTML-Parsing-Using-MSHTML.htm#more

【讨论】:

    【解决方案2】:

    请尝试以下代码。

    CoInitialize(NULL);
    
    CString strHTMLCode = "...";
    CComPtr<IHTMLDocument2> pDoc;
    HRESULT hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IHTMLDocument2, (void**)&pDoc);
    
    // get persist stream init
    ComQIPtr<IPersistStreamInit> psi = doc;
    
    // allocate memory
    HGLOBAL hMem = ::GlobalAlloc(GPTR, strHTMLCode.GetLength() * sizeof(TCHAR));
    ::GlobalLock(hMem);
    ::CopyMemory(hMem, (LPCTSTR)strHTMLCode, strHTMLCode.GetLength() *  * sizeof(TCHAR));
    
    // create stream
    IStream* stream = NULL;
    HRESULT hr = ::CreateStreamOnHGlobal(hMem, FALSE, &stream);
    if (SUCCEEDED(hr))
    {
        // load html string
        psi->Load(stream);
        stream->Release();
    }
    
    // free memory
    ::GlobalUnlock(hMem);
    ::GlobalFree(hMem);
    

    【讨论】:

    • 使用IpersistStreamInit.Load等,DOM马上不可用,需要等待readystate == complete(或相应的事件),如果没有调用线程处理,这似乎不会发生窗口消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多