我试过很多种方法,但是都不太行(IHTMLDocument2 *pDoc已经存在):
IPersistFile *pFile;
         HRESULT hr;
BSTR bstrFileName = CString("e:\\1.html").AllocSysString();
hr = pDoc->QueryInterface(IID_IPersistFile,(void **)&pFile);
hr = pFile->Load(bstrFileName,STGM_READ); IHTMLElementCollection *pAll; hr = pDoc->get_all(&pAll);
long nLen;
pAll->get_length(&nLen);
         这里 nLen 还是为 0;
这个我也试过:
    IPersistStreamInit     *pPSI = NULL;
    IStream *pStm;
    HRESULT hr = URLOpenBlockingStreamA(0, "e:\\1.html", &pStm, 0,0);        hr = pDoc->QueryInterface(IID_IPersistStreamInit, (void **)&pPSI);
    hr = pPSI->Load(pStm);
    hr = pDoc->get_all(&pAll);
    long nLen;
    pAll->get_length(&nLen);
         这里 nLen 还是为 0;所有函数的执行都返回成功。

解决方案 »

  1.   

    你的意思是加载吗?
    如果是的话就这样: 一般就用UrlMoniker, 如果是文件就用IPersistFile;
    用UrlMoniker和IPersistFile的时候你要写个IPropertyNotifySink来接收加载完毕的消息,只有消息完成时才成功
      

  2.   

    给你个具体的例子:// HtmlDoc.h : Declaration of the CHtmlDoc
    // written by [email protected], 2000
    // modified by bugn, 2001
    // originated from www.ddj.com#ifndef __HTMLDOC_H_
    #define __HTMLDOC_H_#include "resource.h"    // main symbols/////////////////////////////////////////////////////////////////////////////
    // CHtmlDoc
    class ATL_NO_VTABLE CHtmlDoc : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public IDispatch,
    public IOleClientSite,
    public IPropertyNotifySink
    {
    public:
    CHtmlDoc();
    ~CHtmlDoc();DECLARE_REGISTRY_RESOURCEID(IDR_HTMLDOC)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CHtmlDoc)
    COM_INTERFACE_ENTRY(IPropertyNotifySink)
    COM_INTERFACE_ENTRY(IDispatch)
    END_COM_MAP()// IHtmlDoc
    public: // IPropertyNotifySink methods
    STDMETHOD(OnChanged)(DISPID dispID);
    STDMETHOD(OnRequestEdit)(DISPID dispID) { return NOERROR; } // IOleClientSite
    STDMETHOD(SaveObject)(void) { return E_NOTIMPL; }
    STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk) { return E_NOTIMPL; }
    STDMETHOD(GetContainer)(IOleContainer** ppContainer) { return E_NOTIMPL; }
    STDMETHOD(ShowObject)(void) { return E_NOTIMPL; }
    STDMETHOD(OnShowWindow)(BOOL fShow) { return E_NOTIMPL; }
    STDMETHOD(RequestNewObjectLayout)(void) { return E_NOTIMPL; } // IDispatch methods
    STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) { return E_NOTIMPL; }
    STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { return E_NOTIMPL; }
    STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { return E_NOTIMPL; }
    STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr); // 
    static CHtmlDoc* Instance();
    STDMETHOD(LoadHTMLFile)(BSTR FileName);
    IHTMLDocument2* GetDoc();protected:
    DWORD mCookie;
    IHTMLDocument2* mMSHTML;
    LPCONNECTIONPOINT mCP;
    BOOL mIsConnected;
    };inline IHTMLDocument2* CHtmlDoc::GetDoc() {return mMSHTML;}#endif //__HTMLDOC_H_
    // HtmlDoc.cpp : Implementation of CHtmlDoc
    // written by [email protected], 2000
    // modified by bugn, 2001
    // originated from www.ddj.com#include "stdafx.h"
    #include "HtmlDoc.h"/////////////////////////////////////////////////////////////////////////////
    // CHtmlDoc#define WM_USER_LOAD_COMPLETE   WM_USER+1CHtmlDoc::CHtmlDoc()
    {
    mCookie = 0;
    mMSHTML = NULL;
    mCP = NULL;
    mIsConnected = FALSE;}CHtmlDoc::~CHtmlDoc()
    {
    if (mMSHTML)
    mMSHTML->Release();
    if (mCP)
    mCP->Release();
    }CHtmlDoc* CHtmlDoc::Instance()
    {
    CComObject<CHtmlDoc>* phd;
    HRESULT hr;
    LPCONNECTIONPOINTCONTAINER pCPC = NULL;
    LPOLEOBJECT pOleObject = NULL;
    LPOLECONTROL pOleControl = NULL;

    phd = new CComObject<CHtmlDoc>;
    if (phd == NULL)
    return NULL; // Create an instance of an dynamic HTML document
    if (SUCCEEDED(hr = CoCreateInstance( CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IHTMLDocument2, (LPVOID*)&phd->mMSHTML )))
    {
    if (SUCCEEDED(hr = phd->mMSHTML->QueryInterface(IID_IOleObject,(LPVOID*)&pOleObject)))
    {
    hr = pOleObject->SetClientSite((IOleClientSite*)phd);
    pOleObject->Release();
    if (SUCCEEDED(hr = phd->mMSHTML->QueryInterface(IID_IOleControl, (LPVOID*)&pOleControl)))
    {
    hr = pOleControl->OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL);
    pOleControl->Release();

    // Hook up sink to catch ready state property change
    if (SUCCEEDED(hr = phd->mMSHTML->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pCPC)))
    {
    if (SUCCEEDED(hr = pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &phd->mCP)))
    {
    hr = phd->mCP->Advise((LPUNKNOWN)(IPropertyNotifySink*)phd, &phd->mCookie);
    if (SUCCEEDED(hr))
    phd->mIsConnected = TRUE;
    }
    pCPC->Release();
    }
    }
    }
    } if (SUCCEEDED(hr))
    {
    return phd;
    }
    else
    {
    delete phd;
    return NULL;
    }
    }STDMETHODIMP CHtmlDoc::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
    WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult,
    EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr
    )
    {
    if (!pVarResult)
    return E_POINTER;
    switch(dispIdMember)
    {
    case DISPID_AMBIENT_DLCONTROL:
    // This tells IE4 that you want to download the page, but you don't 
    // want to run scripts, Java applets, or ActiveX controls
    V_VT(pVarResult) = VT_I4;
    V_I4(pVarResult) =  DLCTL_DOWNLOADONLY | 
    DLCTL_NO_SCRIPTS | 
    DLCTL_NO_JAVA |
    DLCTL_NO_DLACTIVEXCTLS |
    DLCTL_NO_RUNACTIVEXCTLS;
    break;
    default:
    return DISP_E_MEMBERNOTFOUND;
    }
    return NOERROR;
    }STDMETHODIMP CHtmlDoc::OnChanged(DISPID dispID)
    {
    HRESULT hr; if (DISPID_READYSTATE == dispID)
    {
    VARIANT vResult = {0};
    EXCEPINFO excepInfo;
    UINT uArgErr;
    long lReadyState;
    DISPPARAMS dp = {NULL, NULL, 0, 0}; if (SUCCEEDED(hr = mMSHTML->Invoke(DISPID_READYSTATE, IID_NULL, 
    LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &vResult, &excepInfo, &uArgErr)))
    {
    lReadyState = (READYSTATE)V_I4(&vResult);
    switch (lReadyState)
    {
    case READYSTATE_UNINITIALIZED:
    case READYSTATE_LOADING:
    case READYSTATE_LOADED:
    case READYSTATE_INTERACTIVE:
    break;
    case READYSTATE_COMPLETE:
    // IE4 is finished parsing the file
    BOOL fRet = PostThreadMessage(GetCurrentThreadId(), WM_USER_LOAD_COMPLETE, (WPARAM)0, (LPARAM)0);
    break;
    }
    VariantClear(&vResult);
    }
    } return NOERROR;
    }STDMETHODIMP CHtmlDoc::LoadHTMLFile(BSTR FileName)
    {
    HRESULT hr;
    LPPERSISTFILE pPF;
    MSG msg; if (!mIsConnected)
    return S_FALSE;
    // avoid IE error msg box if the file does not exist
    HANDLE h;
    if ((h=CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
    return S_FALSE;
    CloseHandle(h); // use IPersistFile to load the HTML
    if ( SUCCEEDED(hr = mMSHTML->QueryInterface(IID_IPersistFile, (LPVOID*) &pPF)))
    {
    hr = pPF->Load(FileName, 0);
    pPF->Release();
    } hr = S_FALSE;
    if (SUCCEEDED(hr))
    {
    while (GetMessage(&msg, NULL, 0, 0))
    {
    // notification from OnChanged
    if (WM_USER_LOAD_COMPLETE == msg.message && NULL == msg.hwnd)
    {
    hr = S_OK;
    break;
    }
    else
    {
    DispatchMessage(&msg);
    }
    }
    }
    return hr;
    }
      

  3.   

    调用例子:// NOTE: BUG!! u should check the returned values after every method call in ur own programHRESULT hr;
    CHtmlDoc* phd;phd = CHtmlDoc::Instance();
    hr = phd->LoadHTMLFile(L"d:\\debug\\h.htm");
    if (hr == S_OK)
    {
     IHTMLElement* body;
     BSTR title;
     BSTR text; phd->GetDoc()->get_title(&title);
     phd->GetDoc()->get_body(&body);
     body->get_innerHTML(&text); MessageBoxW(m_hWnd, text, title, MB_OK);
     
     body->Release();
     SysFreeString(title);
     SysFreeString(text);
    }
    phd->Release();
      

  4.   

    其实我就是想要一个简单的向 IHTMLDocument 中等待的写入数据的方法,而不是接到
    一个完成的事件。你的第一个回答已经告诉我,没有这样的方法。总是必须响应一个事件,
    这样的话,我直接用 IWebBrowser2::Navigate 就行了。反正是必须等待一个事件。
    你的第二个回答很有专业精神。看出来你是一个比较深入COM的人,反正是比我深入的多。
    当然,你的源码有点问题,就是接口不干净。我拿你的东西编译,他会要我声明一个
    _Moudule 实例。
    我的问题已经解决了。谢谢你。
    下一次有问题再请教你。谢谢。
      

  5.   

    不好意思,因为懒得写IUnknown,所以才用ATL,而ATL就非要_Module。把IUnknown完成就独立了。