兩種方法訪問多層嵌套的frame

來源:互聯網
上載者:User
訪問

========================================

在您的網站拜讀了關於TWebBrowser的使用方法,但是一直有一個問題困擾我,就是如何取得frame嵌套frame的HTML的原碼,我只是知道單個frame如何取得源碼,但是多個frame嵌套就沒有辦法,請教一下!

答========================================

要得到原始碼,必須先得到frame。訪問frame一般說來有兩種方法:

  1、通過WebBrowser的文檔介面得到frame的集合,再逐一訪問。

HRESULT IHTMLDocument2::get_frames(IHTMLFramesCollection2 **p);

  由IHTMLFramesCollection2介面的item方法,可以以frame的索引號(從0開始)或frame的名稱來訪問相應的frame,pvarResult則返回一個IDispatch介面(或一個IDispatch介面的數組,多層嵌套的情況).

HRESULT item(         
    VARIANT *pvarIndex,
    VARIANT *pvarResult
);

  例子如下,假設pWin是一個指向主視窗的有效IHTMLWindow介面指標。

......
VARIANT frameRequested;
VARIANT frameOut;
IHTMLFramesCollection2* pFramesCol;
IHTMLWindow2* pRightFrameWindow;
IHTMLDocument2* pRightDoc;

frameRequested.vt = VT_BSTR;//若為VT_I4則以索引號來訪問
frameRequested.bstrVal = L"rightframe";//以名稱來訪問
//frameRequested.vt = VT_I4;
//frameRequested.bstrVal = (BSTR)0;

hr = pWin->get_frames(&pFramesCol);
hr = pFramesCol->item(&frameRequested, &frameOut);
  
hr = frameOut.pdispVal->QueryInterface(IID_IHTMLWindow2, (void**)&pRightFrameWindow);
hr = pRightFrameWindow->get_document(&pRightDoc);
......

  2、通過IOleContainer枚舉內嵌物件的方式來訪問WebBrowser對象。

void CMyHtmlView::RefreshFrames()
{
  // 取得文檔的IDispatch指標
  LPDISPATCH lpDisp = NULL;
  lpDisp = GetHtmlDocument();

  if (lpDisp)
  {
    IOleContainer* pContainer;
    HRESULT hr = lpDisp->QueryInterface(IID_IOleContainer, (void**)&pContainer);
    lpDisp->Release();
    if (FAILED(hr))
      return hr;

    IEnumUnknown* pEnumerator;
    // 獲得列舉程式
    hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);
    pContainer->Release();
    if (FAILED(hr))
      return hr;

    IUnknown* pUnk;
    ULONG uFetched;
    // 枚舉並重新整理所有frame
    for (UINT i = 0; S_OK == pEnumerator->Next(1, &pUnk, &uFetched); i++)
    {
      IWebBrowser2* pBrowser;

      hr = pUnk->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser);
      pUnk->Release();
      if (SUCCEEDED(hr))
      {
         pBrowser->Refresh();
         pBrowser->Release();
      }
    }
    pEnumerator->Release();
}

  3、訪問的多層嵌套frame

  注意每個frame又可以包含自己的frame,而上面所說的方法則是針對一個WebBrowser的視窗實現的,並不會涉及到深層的frame。要實現多層嵌套frame的訪問,只需要加入一點遞迴的操作就行了。如對1中的pRightFrameWindow和2中的pBrowser,將函數稍加修改,在得到兩個指標後作遞迴調用即可。

  4、訪問原始碼

  下面的方法來自CHtmlView,是比較正規的方法(能夠保持網頁的原始格式)。

BOOL CHtmlView::GetSource(CString& refString)
{
  BOOL bRetVal = FALSE;
  CComPtr<IDispatch> spDisp = GetHtmlDocument();

  if (spDisp != NULL)
  {
    HGLOBAL hMemory;
    hMemory = GlobalAlloc(GMEM_MOVEABLE, 0);
    if (hMemory != NULL)
    {
      CComQIPtr<IPersistStreamInit> spPersistStream = spDisp;
      if (spPersistStream != NULL)
      {
        CComPtr<IStream> spStream;
        if (SUCCEEDED(CreateStreamOnHGlobal(hMemory, TRUE, &spStream)))
        {
          spPersistStream->Save(spStream, FALSE);

          LPCTSTR pstr = (LPCTSTR) GlobalLock(hMemory);
          if (pstr != NULL)
          {
            // Stream is always ANSI, but CString
            // assignment operator will convert implicitly.

            bRetVal = TRUE;
            TRY
            {
              refString = pstr;
            }
            CATCH_ALL(e)
            {
              bRetVal = FALSE;
              DELETE_EXCEPTION(e);
            }
            END_CATCH_ALL

            if(bRetVal == FALSE)
              GlobalFree(hMemory);
            else
              GlobalUnlock(hMemory);
          }
        }
      }
    }
  }
 
  return bRetVal;
}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.