Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема: WebBrowser - изменения на странице, До её отображения в браузере 
:(
    Опции темы
GraySE
  Дата 18.7.2008, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 18.7.2008

Репутация: нет
Всего: нет



Привет! Такой вопрос...
Я обрабатываю страницу (IHTMLDocument2.body.innerHTML), получаемую браузером на событие DownloadComplete. На момент изменения innerHTML, пользователю уже выводится в браузер оригинальная страница. И он видит изменения на ней чуть позже, чем отображается сама страница.
Как можно заблокировать вывод страницы пользователю, до тех пор, пока я не сделаю на ней нужные изменения?

Спасибо.
PM MAIL   Вверх
Ulysses4j
Дата 18.7.2008, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

Репутация: нет
Всего: 10



Можно попробовать сделать body.style.visible=false, а потом true. Но это  smile 


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
GraySE
Дата 18.7.2008, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 18.7.2008

Репутация: нет
Всего: нет



Хм... А на какое событие это делать то? На BeforeNavigate, вроде бы элемента body ещё не существует?
PM MAIL   Вверх
Ulysses4j
Дата 18.7.2008, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

Репутация: нет
Всего: 10



Возможно, поместить всю обработку в body.onLoad.

А, если не существует, тогда не знаю.

Это сообщение отредактировал(а) Ulysses4j - 18.7.2008, 20:49


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
GoldFinch
Дата 3.4.2010, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



АП.
та же проблема.
есть свое окно с компонентом WebBrowser, хочу при загрузке страницы внести в нее изменения.
т.к. изменений много, хочу внедрить туда js код который произведет всю работу.
вариант 1:
Код

    void DocumentComplete(IDispatch *pDisp, VARIANT *URL)    
    {
        IWebBrowser2* webBrowser;
        HRESULT r = pDisp->QueryInterface(IID_IWebBrowser2, (void**)&webBrowser);
        IDispatch* documentDisp;
        r = webBrowser->get_Document(&documentDisp);
        IHTMLDocument2* htmlDocument;
        r = documentDisp->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDocument);
        IHTMLElement* body;
        r = htmlDocument->get_body(&body);

        BSTR html = 
            L"<span style=\"color:#f00\">test</span>"
            L"<script type=\"text/javascript\">alert(1+1)</script>";

        r = body->insertAdjacentHTML(L"afterBegin", html);
    }

вариант 1а:
Код

    void DocumentComplete(IDispatch *pDisp, VARIANT *URL)    
    {
        IWebBrowser2* webBrowser;
        HRESULT r = pDisp->QueryInterface(IID_IWebBrowser2, (void**)&webBrowser);
        IDispatch* documentDisp;
        r = webBrowser->get_Document(&documentDisp);
        IHTMLDocument2* htmlDocument;
        r = documentDisp->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDocument);
        IHTMLElement* body;
        r = htmlDocument->get_body(&body);

        BSTR html = 
            L"<span style=\"color:#f00\">test</span>"
            L"<script type=\"text/javascript\">alert(1+1)</script>";

        IHTMLElement* el;
        r = htmlDocument->createElement(L"DIV", &el);
        r = el->put_innerHTML(html);
        IHTMLDOMNode* elNode;
        r = el->QueryInterface(IID_IHTMLDOMNode, (void**)&elNode);

        IHTMLDOMNode* bodyNode;
        r = body->QueryInterface(IID_IHTMLDOMNode, (void**)&bodyNode);
        IHTMLDOMNode* newNode;
        r = bodyNode->appendChild(elNode, &newNode);
    }


вариант 2
Код

    void DocumentComplete(IDispatch *pDisp, VARIANT *URL)    
    {
        IWebBrowser2* webBrowser;
        HRESULT r = pDisp->QueryInterface(IID_IWebBrowser2, (void**)&webBrowser);

        BSTR jcode = L"javascript:"
            L"var el = document.createElement('DIV');"
            L"el.innerHTML='"
                L"<span style=\"color:#f00\">test</span>"
                L"<script type=\"text/javascript\">alert(1+1)</script>"
            L"';"
            L"document.body.appendChild(el)"
            ;

        webBrowser->Navigate(jcode, 0, 0, 0, 0);
    }


при использовании вариантов 1 и 1а, span появляется, а скрипт не срабатывает (alert'а нет)
при использовании варианта 2 span появляется, браузер виснет не успев показать остальное содержимое страницы

что делать чтобы выполнить большой скрипт в загружаемой странице?
PM MAIL ICQ   Вверх
GoldFinch
Дата 3.4.2010, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



во втором способе было неправильное использование "javascript:", поправил - заработало как и 1й способ %)
PM MAIL ICQ   Вверх
GoldFinch
Дата 3.4.2010, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



таки не до конца поправил %)
после "javascript:" должна быть только одна операция, 
значит чтобы записать несколько, надо применить идиому
(function(){ ...код; код; .... })()

возможно это надо завернуть в void(), и возможно надо заменить пробелы на %20, хотя у меня и так работает (ie7)
PM MAIL ICQ   Вверх
GoldFinch
Дата 4.4.2010, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



для метода с insertAdjacentHTML помогло добавление атрибута defer:
Код

        BSTR html =    L"<div>&nbsp;</div><script defer=\"defer\" type=\"text/javascript\">alert(1+1)</script>";
        r = body->insertAdjacentHTML(L"afterBegin", html);

также тег script не должен быть первым потомком body, перед ним должен быть какой-то другой (непустой?) тег
PM MAIL ICQ   Вверх
GoldFinch
Дата 4.4.2010, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



остается непонятным такой вопрос:
если создавать элемент script, то как получить его интерфейс IHTMLScriptElement, чтобы вызвать put_text?

вот такой код не работает, QueryInterface возвращает E_NOINTERFACE
Код

        IHTMLElement* scriptEl;
        htmlDocument->createElement(L"SCRIPT", &scriptEl);
        IHTMLScriptElement* script;        
        HRESULT r = scriptEl->QueryInterface(IID_IHTMLScriptElement, (void**)&script);


PM MAIL ICQ   Вверх
GoldFinch
Дата 4.4.2010, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



но в любом случае,
на момент события DownloadComplete
на экране еще нет содержимого body, зато нарисован его фон (background-image, background-color).

по этому надо ловить NavigateComplete2.
однако, при наступлении события NavigateComplete2 тег body получить еще нельзя,
зато можно получить стили, и добавить новые правила
Код

    void NavigateComplete2(IDispatch *pDisp, VARIANT *URL)
    {
            HRESULT r;
            ATL::CComQIPtr<IWebBrowser2> webBrowser(pDisp);
            ATL::CComPtr<IDispatch> documentDisp;
            r = webBrowser->get_Document(&documentDisp);
            ATL::CComQIPtr<IHTMLDocument2> htmlDocument(documentDisp);
            ATL::CComPtr<IHTMLStyleSheetsCollection > cssCollection;
            r = htmlDocument->get_styleSheets(&cssCollection);
            ATL::CComVariant idx(0);
            ATL::CComVariant cssVar;
            r = cssCollection->item(&idx, &cssVar);
            ATL::CComQIPtr<IHTMLStyleSheet> css(cssVar.pdispVal);
            long newRuleIdx;
            static BSTR ruleSelector = SysAllocString(L"body");
            static BSTR ruleBody = SysAllocString(L"background:none !important;");
            r = css->addRule(ruleSelector, ruleBody, -1, &newRuleIdx);

при вызове addRule надо обратить внимание на то, что строки должны быть получены вызовом SysAllocString, иначе будет ошибка E_INVALIDARG

Это сообщение отредактировал(а) GoldFinch - 4.4.2010, 12:41
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.0782 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.