tags:

views:

356

answers:

1

When the page displayed in our CDHtmlDialog does an Asp.Net AJAX UpdatePanel we get a navigate event, but everything after that seems to be lost. We don't have a document anymore or get any mouse events on the page.

A: 

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 issue, but it came up again in a different context (really starting to hate CDHTMLDialog).

Here is the cause of the problem:
Javascript calls are causing a Navigate event, and CDHtmlDialog::OnBeforeNavigate gets called and disconnects and deletes the IHTMLDocument2. Unfortunately it's not a true Navigate since the page never changed. This means CDHtmlDialog::OnNavigateComplete is never called to get the document back.

To make matters worse, when I override CDHtmlDialog::OnBeforeNavigate I find the URL string is unreadable (bug)?

The simplest (best?) solution:
We need to intercept the Before Navigate event, and only call the CDHtmlDialog's _OnBeforeNavigate2 if the URL isn't 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);
        }
    }
}

Most of this is pretty standard for setting up a CDHtmlDialog subclass, and it's pretty simple actually, but it took me a bit to figure out how to handle JavaScript. Unfortunately, I'm not sure how this will work if the JavaScript is making dynamic changes to the page itself.

A couple notes:

  • If the navigation needs to be completely canceled here, then set *Cancel = TRUE and don't call _OnBeforeNavigate2. Be careful here because this also cancels any JavaScript actions.
  • It wasn't clear until I saw the source, but CDHtmlDialog::_OnBeforeNavigate2 just calls CDHtmlDialog::OnBeforeNavigate.
Tony