How to get CDHtmlDialog document after Asp.Net AJAX UpdatePanel
It looks like I made the original post as an unregistered user, so I don't think I can edit it. We were able to work around the original problem, but it reappeared in a different context (really starting to hate CDHTMLDialog).
Here's the cause of the problem:
Javascript calls raise the Navigate event, and CDHtmlDialog :: OnBeforeNavigate calls and disables and disposes of IHTMLDocument2. Unfortunately, this is not a real Navigation as the page has never changed. This means that CDHtmlDialog :: OnNavigateComplete is never called to return the document.
Worse still, when I override CDHtmlDialog :: OnBeforeNavigate I found the URL string is unreadable (error)?
Simplest (best?) Solution:
We need to intercept the Before Navigate event and call CDHtmlDialog _OnBeforeNavigate2 if the url is not a javascript action:
BEGIN_EVENTSINK_MAP(CMyHTMLDlg, CDHtmlDialog)
ON_EVENT(CMyHTMLDlg, AFX_IDC_BROWSER, DISPID_BEFORENAVIGATE2, OnBeforeNavigate2, VTS_DISPATCH VTS_VARIANT VTS_VARIANT VTS_VARIANT VTS_VARIANT VTS_VARIANT VTS_PBOOL)
END_EVENTSINK_MAP()
void CMyHTMLDlg::OnBeforeNavigate2(LPDISPATCH pDisp, VARIANT* URL,VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData,VARIANT* Headers, BOOL* Cancel)
{
...
if (URL != NULL)
{
// Check if navigation is to a folder..
CString url = CString(*URL);
if(url.Left(11) != _T("javascript:"))
{
_OnBeforeNavigate2(pDisp, URL, Flags, TargetFrameName, PostData, Headers, (BOOL*)Cancel);
// If dynamic linking MFC then the above handler doesn't exist. Need to call OnBeforeNavigate direct.
// This is from a code site, and it compiles, but I've never tested it to see if it works.
//CDHtmlDialog::OnBeforeNavigate(pDisp,(LPCSTR)URL);
}
}
}
Much of this is pretty standard for subclassing CDHtmlDialog, and it's pretty straightforward, but it took me a bit to figure out how to handle JavaScript. Unfortunately I'm not sure how this would work if JavaScript is making dynamic changes on the page itself.
A couple of notes:
- If navigation needs to be completely canceled here, set * Cancel = TRUE and don't call _OnBeforeNavigate2. Be careful because this will override any JavaScript actions as well.
- It's unclear until I see the source , but CDHtmlDialog :: _ OnBeforeNavigate2 just calls CDHtmlDialog :: OnBeforeNavigate.
source to share