IHTMLWindow2 *pWin~~~~
// 유효한 인터페이스가 존재하는 경우, 도큐먼트를 구할 시 다음과 같이 두 경우 고려 처리하면 된다.
if(S_OK == (hr=pWin->get_document(&pDocFrame))){
// 제대로 구해지면 여기서 프레임 도큐먼트를 가지고 작업
//~~~~~~~~
pDocFrame->Release();
} else if(hr == E_ACCESSDENIED){ // 옆의 에러 발생시 아래와 같은 처리
IServiceProvider *pSP=NULL;
IWebBrowser2 *pWBSub=NULL;
if(S_OK == pWin->QueryInterface(IID_IServiceProvider, (void**)&pSP)){
if(S_OK == pSP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&pWBSub)){
if(S_OK == pWBSub->get_Document(&pDisp)){
if(S_OK == pDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pDocFrame)){
// 여기서 프레임 도큐먼트를 가지고 작업
//~~~~~~~~~~~~~
pDocFrame->Release();
}
pDisp->Release();
}
pWBSub->Release();
}
pSP->Release();
}
}
pWin->Release();
================================ 관련 포스트 ====================================
When IHTMLWindow2::get_document returns E_ACCESSDENIED 뱉을 경우
When IHTMLWindow2::get_document returns E_ACCESSDENIED
Internet Explorer extensions usually needs to access HTML elements. When extensions are initialized they get a IWebBrowser2 pointer representing the browser. Starting with this pointer one can get any HTML element in the web page but to do that we need to browse a hierarchy of frames first. The simplest web pages only have one frame and one document. Web pages containing <frame> or <iframe> have a hierarchy of frames, each frame having its own document.
Here are the objects involved and the corresponding interfaces:
browser - IWebBrowser2
frame/iframe - IHTMLWindow2
document - IHTMLDocument2
element - IHTMLElement
The list bellow shows what method to call to get one object from another:
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
A normal call chain to get a HTML element is:
browser -> document -> frame -> child frame -> ... -> child frame -> document -> element
This will work almost all the time. The problems arise when different frames contain documents loaded from different internet domains. In this case IHTMLWindow2::get_document returns E_ACCESSDENIED when trying to get the document from the frame object. I think this happens to prevent cross frame scripting atacks.
Here is HtmlWindowToHtmlDocument function I wrote to be used instead IHTMLWindow2::get_document to bypass the restriction:
// 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;
}
'웹, HTML' 카테고리의 다른 글
Ftp 이어 받기, 이어 올리기 구현할 때 (2) | 2009.10.03 |
---|---|
IOleContainer 를 가지고 enum 객체 생성해 다수의 웹브라우저 컨트롤 구해보는 소스 (4) | 2009.09.28 |
IHTMLWindow2->get_document가 E_ACCESSDENIED를 뱉는 경우(아래와 다른 해결방법) (2) | 2009.09.28 |
ShellExecute,WinExec,CreateProcess (IE 실행방법) (0) | 2009.07.25 |
HTMLElement 객체/ Event - JavaScript - (0) | 2009.07.21 |
웹페이지 프레임 포함 전체 소스 추출 (0) | 2009.07.08 |
이벤트 싱크 소스 참조 (2) | 2009.07.05 |