获取IE (控件)的所有链接(包括Frameset, iframe)zz
IE 頂層 body 節(jié)點通過IHTMLElement->get_all 方法無法獲取iframe 里面的節(jié)點列表
CComPtr<IHTMLElement> body;
?
CComPtr<IDispatch> spDispCollection;
body->get_all(&spDispCollection);
所以要獲取iframe/frame(frameset) 里面的節(jié)點列表的話, 則需要根據(jù)body/doc 找到frames, 然后從frames -> IHTMLWindow2 -> IHTMLDocument2 . 主要有2個方法, 下面是代碼片段
方法一:
IHTMLDocument2 *pDoc = 瀏覽器的Document(IWebBrowser2->IDispatch->IHTMLDocument2);
IHTMLWindow2 *pHTMLWnd = NULL;
IHTMLDocument2 *pFrameDoc=NULL;
IHTMLFramesCollection2 *pFramesCollection=NULL;
LPDISPATCH lpDispatch;
long p;
VARIANT varindex,varresult;
varresult.vt=VT_DISPATCH;
varindex.vt = VT_I4;
if(pDoc!=NULL)
{
???? HRESULT hr=pDoc->get_frames(&pFramesCollection);
??? if(SUCCEEDED(hr)&&pFramesCollection!=NULL)
???? {
???????? hr=pFramesCollection->get_length(&p);
??????? if(SUCCEEDED(hr))
??????????? for(int i=0; i<p; i++)
???????????? {
???????????????? varindex.lVal = i;
??????????????? if(pFramesCollection->item(&varindex, &varresult) ==S_OK)
???????????????? {
???????????????????? lpDispatch=(LPDISPATCH)varresult.ppdispVal;
??????????????????? if (SUCCEEDED(lpDispatch->QueryInterface(IID_IHTMLWindow2, (LPVOID *)&pHTMLWnd)))
???????????????????? {
??????????????????????? if(SUCCEEDED(pHTMLWnd->get_document( &pFrameDoc)))
???????????????????????? {
??????????????????????????? //work with the pFrameDoc
???????????????????????? }
???????????????????????? pHTMLWnd->Release();
???????????????????????? pHTMLWnd=NULL;
???????????????????? }
???????????????? }
???????????? }
???????????? pFramesCollection->Release();
???? }
???? pDoc->Release();
}
方法二:
CComQIPtr<IHTMLElement> pElem = ; // 可以遞歸上面的 CComPtr<IDispatch> spDispCollection 來得到
CComBSTR bstrTagName;
pElem->get_tagName(&bstrTagName);
if ( lstrcmpiW(L"IFRAME", bstrTagName)==0 ||
???????? lstrcmpiW(L"FRAME", bstrTagName)==0 )
{
???? CComQIPtr<IHTMLFrameBase2>???? _framebase2;
???? CComPtr<IHTMLWindow2>???????? _framewindow;
???? CComPtr<IHTMLDocument2>???????? _framedoc;
???
??? if( (_framebase2 = spItem)
??????? && SUCCEEDED( _framebase2->get_contentWindow(&_framewindow) ) && _framewindow!=NULL
??????? && SUCCEEDED( _framewindow->get_document(&_framedoc) ) && _framedoc!=NULL )
???? {
??????? // 對 _framedoc 節(jié)點進行處理
???? }
}
iframe 跨域訪問(cross frame)?? zz from : http://www.wzszf.com/
由于安全性限制, 為防止跨域腳本攻擊, 當frames 跨域的時候, IHTMLWindow2::get_document 調(diào)用將返回 E_ACCESSDENIED .
下面函數(shù) HtmlWindowToHtmlDocument 對于跨域的frame 通過 IHTMLWindow2 -> IID_IWebBrowserApp -> IHTMLWindow2 繞過了限制.
// Converts a IHTMLWindow2 object to a IHTMLDocument2. Returns NULL in case of failure.
// It takes into account accessing the DOM across frames loaded from different domains.
CComQIPtr<IHTMLDocument2> HtmlWindowToHtmlDocument(CComQIPtr<IHTMLWindow2> spWindow)
{
????? ATLASSERT(spWindow != NULL);
????? CComQIPtr<IHTMLDocument2> spDocument;
????? HRESULT hRes = spWindow->get_document(&spDocument);
???
???? if ((S_OK == hRes) && (spDocument != NULL))
????? {
????????? // The html document was properly retrieved.
????????? return spDocument;
????? }
???? // hRes could be E_ACCESSDENIED that means a security restriction that
???? // prevents scripting across frames that loads documents from different internet domains.
????? CComQIPtr<IWebBrowser2>?? spBrws = HtmlWindowToHtmlWebBrowser(spWindow);
???? if (spBrws == NULL)
????? {
????????? return CComQIPtr<IHTMLDocument2>();
????? }
???? // Get the document object from the IWebBrowser2 object.
????? CComQIPtr<IDispatch> spDisp;
????? hRes = spBrws->get_Document(&spDisp);
????? spDocument = spDisp;
???? return spDocument;
}
// Converts a IHTMLWindow2 object to a IWebBrowser2. Returns NULL in case of failure.
CComQIPtr<IWebBrowser2> HtmlWindowToHtmlWebBrowser(CComQIPtr<IHTMLWindow2> spWindow)
{
????? ATLASSERT(spWindow != NULL);
????? CComQIPtr<IServiceProvider>?? spServiceProvider = spWindow;
???? if (spServiceProvider == NULL)
????? {
????????? return CComQIPtr<IWebBrowser2>();
????? }
????? CComQIPtr<IWebBrowser2> spWebBrws;
????? HRESULT hRes = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrws);
???? if (hRes != S_OK)
????? {
????????? return CComQIPtr<IWebBrowser2>();
????? }
???? return spWebBrws;
}
附:
IE(控件/接口)中主要有4個部分, Browser, Document, Frame/IFrame, Element , 其對應接口分別是
Browser????????? -???? IWebBrowser2
Document?????? -???? IHTMLDocument2
Frame/IFrame-???? IHTMLWindow2
Element????????? -???? IHTMLElement
可以通過下面方法互相獲取
browser????? -> document??????? IWebBrowser2::get_Document
document???? -> frame?????????? IHTMLDocument2::get_parentWindow
frame??????? -> document??????? IHTMLWindow2::get_document
frame??????? -> parent frame??? IHTMLWindow2::get_parent
frame??????? -> children frames IHTMLWindow2::get_frames
element???? -> Frame????????????? IHTMLElement->QI(IHTMLFrameBase2) -> IHTMLFrameBase2->get_contentWindow -> IHTMLWindow2
總結
以上是生活随笔為你收集整理的获取IE (控件)的所有链接(包括Frameset, iframe)zz的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信号分解:双正交、完备性、对偶向量
- 下一篇: 信号分解:标架、对偶标架、紧标架