Click to See Complete Forum and Search --> : IHTMLWindow2 get_document fails with Access is Denied on IFrame


hobnob
October 28th, 2001, 01:59 PM
get_document fails with Access is denied with IFrame's

whats the problem ?, i took most of this code from microsoft's site.

thanks,
lee.

I wait for if (dispidMember == DISPID_DOCUMENTCOMPLETE)
parse the html page ok, look for frames and process those, which usually works but i've found IFrames makes it fall over with Access is Denied.

VARIANT frameRequested;
VARIANT frameOut;
IHTMLFramesCollection2* pFramesCol = NULL;
IHTMLWindow2* pRightFrameWindow = NULL;
IHTMLDocument2* pRightDoc = NULL;

frameRequested.vt = VT_UINT;

HRESULT hr = spHTML->get_frames(&pFramesCol);
if (FAILED(hr))
{
MessageBox(NULL,_T("no frames"),NULL,NULL);
return FALSE;
}

long len = 0;
pFramesCol->get_length(&len);
if(len==0) return FALSE;

for(int f=0;f<len;f++)
{
MessageBox(NULL,CComBSTR(frames[f]),NULL,NULL);

frameRequested.lVal = f;

hr = pFramesCol->item(&frameRequested, &frameOut);
if (SUCCEEDED(hr)) // frame present
{

hr = frameOut.pdispVal->QueryInterface(IID_IHTMLWindow2, (LPVOID *)&pRightFrameWindow);
if (SUCCEEDED(hr)) // QueryInterface OK
{


hr = pRightFrameWindow->get_document(&pRightDoc);
if (!SUCCEEDED(hr))
{
_com_error e( hr );
MessageBox(NULL, CComBSTR(e.ErrorMessage()),NULL,NULL );
}

AWarlock
November 6th, 2001, 05:44 AM
Hi,
You can't get from a "normal" Frame acess to the Document of a IFRAME, also if you try you will see that when you receive the DocumentComplete from a IFRAME you also can't get the Document from the Parent window, or Top Window.
This behaviour is if I'm not mistaken if the Domain differs and it's not a bug.

hobnob
November 6th, 2001, 01:30 PM
thanks for that, I have partially got around that problem by using IHTMLFrameBase instead which works fine with IFrames in the html document root.

but I don't know how to implement it within a Frame.. i'm really stuck!
any ideas anybody ? some code would be a god send.

thanks,
lee.

AWarlock
November 7th, 2001, 05:46 AM
Hi,
The IHTMLFrameBase doesn't give acess to the Document, how did you managed to get it from there ???

If you want to get the document from a frame, the
get_document of the IHTMLWindow2 seems to work fine.

So you only need to query each Frame Item for a IHTMLWindow2 and then use the get_document if
the returned IHTMLDocument2 isn't null then you are probably dealing with a frame.
Once you have the frame you can Query it for a
IOleWindow and then get the window Handle.

If you managed to get the document of a IFRAME from another Frame, please let me know.

thanks,

hobnob
November 7th, 2001, 03:17 PM
ok will look into that... thanks.

heres the IID_IHTMLFrameBase code which works with javascript IFrames in the document root, it took a while to work it out. shame there isn't more examples on microsofts IE site!, you know of any other sites ???

have fun.


BOOL CViewSource::RetrieveIFrames()
{
HRESULT hr;

IHTMLFramesCollection2* pFramesCol = NULL;

hr = spHTML->get_frames(&pFramesCol);

IHTMLElementCollection* pColl = NULL;
if(SUCCEEDED(hr = spHTML->get_all( &pColl )))
{
long length = 0;
if(SUCCEEDED(hr = pColl->get_length(&length)) && (length))
{
for (int x = 0; x < length; x++ )
{
VARIANT Index;
IDispatch* pDisp2 = NULL;
Index.vt = VT_UINT;
Index.lVal = x;
VARIANT var2;
VariantInit( &var2 );
if(SUCCEEDED(hr = pColl->item (Index, var2, &pDisp2)))
{

IHTMLFrameBase* pBase = NULL;

if(SUCCEEDED(hr = pDisp2->QueryInterface(IID_IHTMLFrameBase,(void**)&pBase)) && (pBase))
{
BSTR src = NULL;
if(SUCCEEDED(pBase->get_src(&src)))
{
// do whatever you want

}

}

}

}
}

}

return S_OK;
}

AWarlock
November 7th, 2001, 04:13 PM
The code you posted doesn't give acess to the "document", what I needed was a way to get the IHTMLDocument of a "IFRAME" in a IHTMLFramesCollection. But thanks anyway, if you need the code to get the IHTMLDocument of a "FRAME" let me know...

Unfortunately code examples for the HTML Interfaces are rare... so the best way to get info are the Newsgroups.

Thanks,

hobnob
November 7th, 2001, 04:18 PM
yes please.

any code is usefull.

thanks,
lee.

AWarlock
November 8th, 2001, 04:33 PM
hr = pHTMLDoc->get_frames(&pFrameCol);
if(SUCCEEDED(hr) && pFrameCol)
{
long lNumberOfFrames = 0;
pFrameCol->get_length(&lNumberOfFrames);
VARIANT varObject;
VARIANT varTmp;
varTmp.vt = VT_INT;
for(long i=0; i<lNumberOfFrames; i++)
{
varTmp.intVal = i;
pFrameCol->item(&varTmp, &varObject);
if(varObject.pdispVal)
{
// Get this Window
hr = varObject.pdispVal->QueryInterface(IID_IHTMLWindow2, (void**) &pHTMLWindow2Aux);

if(SUCCEEDED(hr) && pHTMLWindow2Aux)
{
hr = pHTMLWindow2Aux->get_document(&pHTMLDocAux);
if(SUCCEEDED(hr))
{
if(pHTMLDocAux) // Possible Frame
{
// At this point you have a valid IHTMLDocument
// To get the HANDLE of the Frame Window
hr = pHTMLDocAux->QueryInterface(IID_IOleWindow,(void**)&pOleWindowAux);
if(SUCCEEDED(hr) && pOleWindowAux)
{
HWND hwndTmp = NULL;
hr = pOleWindowAux->GetWindow(&hwndTmp);
}




**********
By the way if you haven't notices if a page has a META TAG of Refresh but doesn't give a diferent URL you don't receive the DocumentComplete Notification, do you know a way to identify if the page was refreshed ?

AWarlock
November 8th, 2001, 04:37 PM
I forgot to ask if you know how to detect if a page was readed or not from the cache...

bigbencat
February 28th, 2010, 09:03 PM
The code you posted doesn't give acess to the "document", what I needed was a way to get the IHTMLDocument of a "IFRAME" in a IHTMLFramesCollection. But thanks anyway, if you need the code to get the IHTMLDocument of a "FRAME" let me know...

Unfortunately code examples for the HTML Interfaces are rare... so the best way to get info are the Newsgroups.

Thanks,

now ok:

CComPtr < IHTMLDocument2 > spDoc2;
hr = spWin2->get_document( &spDoc2 ); //error in here!!!!
if (!SUCCEEDED(hr))
{
_com_error e( hr ); Display("get document error:"+CString(e.ErrorMessage()));
spDoc2=HtmlWindowToHtmlDocument(spWin2);//ok now!!!!
}




// 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;
}


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;
}