Почему событие DocumentComplete элемента управления Webbrowser сначала запускается для фрейма верхнего уровня?

На основе этой статьи в MSDN: Как определить завершение загрузки страницы в элементе управления WebBrowser и из прошлых обсуждений StackOverflow я бы предположил, что в случае документа с несколькими фреймами событие DocumentComplete будет срабатывать несколько раз, и последний раз будет для фрейма верхнего уровня.

Однако, используя точный образец кода из вышеупомянутой ссылки MSDN, я обнаружил, что если при выполнении перехода к URL-адресу возникает несколько событий DocumentComplete, условие выполняется в следующем коде в первый раз, а не в последний раз, поскольку статья как бы указывает. Последующие вызовы DocumentComplete кажутся для кадров более низкого уровня, поскольку условие не выполняется.

IUnknown*  pUnk;
LPDISPATCH lpWBDisp;
HRESULT    hr;
pUnk = m_webBrowser.GetControlUnknown();
ASSERT(pUnk);
hr = pUnk->QueryInterface(IID_IDispatch, (void**)&lpWBDisp);
ASSERT(SUCCEEDED(hr));
if (lpDisp == lpWBDisp )
{
   // Top-level Window object, so document has been loaded
   TRACE("Web document is finished downloading\n");
}
lpWBDisp->Release();

Я не уверен, почему поведение, которое я наблюдаю, прямо противоположно тому, что должно быть в соответствии с документацией. Любые указатели на это будут оценены.

Фон: я использую этот код в диалоговом приложении VC++/MFC, и в событии DocumentComplete я хочу получить определенную статистику, когда документ полностью загружен. Итак, я пытался использовать приведенный выше код, чтобы определить, что конкретный экземпляр срабатывания DocumentComplete происходит, когда страница полностью загружена.


person Sonali Gupta    schedule 29.09.2013    source источник
comment
Примечание. Я отлаживаю первоначальную загрузку веб-страницы, соответствующей URL-адресу, такому как microsoft.com, не используя учитывать дальнейшие действия пользователя, такие как переход по ссылкам на странице. Несколько событий DocumentComplete соответствуют начальной загрузке страницы (по одному для каждого фрейма страницы, как мне кажется)   -  person Sonali Gupta    schedule 29.09.2013


Ответы (2)


ИМО, самый надежный способ получить уведомление о полной загрузке страницы — это прикрепить ее к window.onload DOM-событие для верхнего объекта window (IWebBrowser2::get_Document, IHTMLDocument2::get_parentWindow), когда DocumentComplete запускается в первый раз для определенной навигации. Затем событие onload для верхней веб-страницы будет запущено, когда все внутренние фреймы будут загружены. Этот ответ иллюстрирует, как это можно сделать на C# и этот ответ может помочь сделать это на C++.

person noseratio    schedule 30.09.2013

Документ MSDN кажется мне правильным: последний DISPID_DOCUMENTCOMPLETE запускается для основного фрейма.

Я не могу воспроизвести вашу проблему для http://www.microsoft.com/, так как эта ссылка дает мне окончательный http://www.microsoft.com/fr-fr/default.aspx который представляет собой один кадр.

Мне не нравится, как пример кода тестируется для основного браузера (равенство двух указателей IDispatch). Я делаю следующее:

  1. QueryInterface IDispatch вместо IWebBrowser2
  2. Сделайте настоящий тест на равенство COM, то есть «сравнение IUnknown» с 2 IWebBrower2 (я делаю это с помощью метода IsEqualObject из шаблона CComPtr.
person manuell    schedule 04.01.2014