Похоже, я сделал оригинальное сообщение как незарегистрированный пользователь, поэтому я не думаю, что смогу его редактировать. Мы смогли обойти исходную проблему, но она снова возникла в другом контексте (действительно начинает ненавидеть CDHTMLDialog).
Вот причина проблемы:
Вызовы Javascript вызывают событие Navigate, а CDHtmlDialog :: OnBeforeNavigate вызывается, отключается и удаляет IHTMLDocument2. К сожалению, это не настоящий Navigate, так как страница никогда не менялась. Это означает, что CDHtmlDialog :: OnNavigateComplete никогда не вызывается для возврата документа.
Что еще хуже, когда я перезаписываю CDHtmlDialog :: OnBeforeNavigate, я обнаруживаю, что строка URL не читается (ошибка)?
Самое простое (лучшее?) Решение:
Нам нужно перехватить событие Before Navigate и вызывать _OnBeforeNavigate2 CDHtmlDialog, только если URL не является действием javascript:
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);
}
}
}
Большинство из них довольно стандартны для настройки подкласса CDHtmlDialog, и на самом деле это довольно просто, но мне потребовалось немного времени, чтобы понять, как обрабатывать JavaScript. К сожалению, я не уверен, как это будет работать, если JavaScript вносит динамические изменения в саму страницу.
Пара замечаний:
- Если здесь необходимо полностью отменить навигацию, установите * Cancel = TRUE и не вызывайте _OnBeforeNavigate2. Будьте осторожны, потому что это также отменяет любые действия JavaScript.
- Не было ясно, пока я не увидел source , но CDHtmlDialog :: _ OnBeforeNavigate2 просто вызывает CDHtmlDialog :: OnBeforeNavigate.