问========================================
在您的网站拜读了关于TWebBrowser的使用方法,但是一直有一个问题困扰我,就是如何取得frame嵌套frame的HTML的原码,我只是知道单个frame如何取得源码,但是多个frame嵌套就没有办法,请教一下!
2004-09-29 23:41:28
答========================================
要得到源代码,必须先得到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; }