Чтение онлайн

на главную - закладки

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

 m_pBrowserApp->Navigate(bstrURL, NULL, NULL, NULL, NULL);

}

Замечу, что CLSID_WebBrowser — идентификатор объекта webbrowser, описанный в файле comdef.h. Этот файл имеет ключевое значение, поскольку в нем отражены идентификаторы основных интерфейсов объектной модели Windows, в частности WebBrowser и объектной модели HTML. Для большинства элементов объявлены smart-pointers, что особенно актуально для работы с DHTML из приложения, где просто море различных интерфейсов. Помимо стандартных для ActiveX элементов интерфейса, webbrowser компонент экспортирует также два

собственных интерфейса:

• IWebBrowser2. Этот интерфейс реализует управление элементом: внешним видом, параметрами, а также позволяет производить навигацию.

• DWebBrowserEvents2. Объект webbrowser использует события для уведомления приложения о состоянии компонента. Например, перед навигацией на новый URL, вызывается событие BeforeNavigate2.

Описание этих интерфейсов exdisp.h/exdispid.h. Оглядываясь на практический опыт, замечу, что ссылки на все описанные файлы лучше прописывать в stdafx.h.

Подключение событий

Механизм подключения событий через точки соединения стандартный, поэтому не имеет смысла его здесь описывать. Тем более, что MFC предоставляет более удобный способ для отлова событий webbrowser через DECLARE_EVENTSINK_MAP макрос.

Запишем в заголовочном файле класса, содержащего webbrowser control:

// Web browser event sink

DECLARE_EVENTSINK_MAP

virtual void OnDownloadComplete;

virtual void DocumentComplete(LPDISPATCH pDisp, VARIANT* URL);

А в .cpp файле добавим строки:

BEGIN_EVENTSINK_MAP(CChatChannelDialog, CDialog)

 ON_EVENT(CChatChannelDialog, AFX_IDW_PANE_FIRST, DISPID_NAVIGATECOMPLETE, OnDownloadComplete, VTS_NONE)

 ON_EVENT(CChatChannelDialog, AFX_IDW_PANE_FIRST, DISPID_DOCUMENTCOMPLETE, DocumentComplete, VTS_DISPATCH, VTS_PVARIANT)

END_EVENTSINK_MAP

Для полной реализации механизма отлова событий этим путем, лучше всего обратиться к исходным текстам CHTMLView.

Модель объектов DHTML

Интерфейс DWebBrowserEvents2 при помощи события DISPID_NAVIGATECOMPLETE позволяет определить тот момент, когда HTML документ полностью сгенерирован внутри webbrowser control. После того, как это происходит, весь HTML документ доступен через функцию IWebBrowser2::get_Document. Также, как и webbrowser control, HTML документ поддерживает события, такие как click, mouseover. Для того, чтобы использовать объектную модель DHTML, нужно подключить заголовок mshtml.h.

CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> pADocument;

IDispatch* pdispTmpVal;

m_pBrowserApp->get_Document(&pdispTmpVal);

pADocument = pdispTmpVal;

pdispTmpVal->Release;

Интерфейс IHTMLDocument2 предоставляет возможность получать и модифицировать содержимое документа. Вы можете использовать множество методов, таких как get_body, get_all, get_activeElement чтобы извлекать элементы или коллекции элементов внутри документа. Базовой основой для любого тэга внутри HTML-документа является интерфейс IHTMLElement. Меняя содержимое тэга при помощи свойств innerHTML

и outerHTML мы реализуем принцип динамического содержания, который нами и преследовался. К любому элементу можно адресоваться при помощи идентификатора id через вызов IHTMLElementCollection::Item. Итак, c визуализацией ясно, а как же теперь обеспечить интерактивность? Как избавиться от ненужных клавишных комбинаций и меню? Как получить доступ из скриптов к внутренней модели объектов нашей программы?

Расширение объектной модели DHTML

Компания Microsoft предоставила возможность расширения объектной модели через механизм window.external. Приложение, использующее web-browser control может реализовывать собственную логику через переопределение объекта external. Естественно, чтобы иметь возможноть работать со своим приложением из скрипта, программа должна реализовывать dispatch-интерфейсы. При помощи ClassWizard, добавить поддержку автоматизации к своим объектам не составляет труда. Единственным замечанием здесь может служить лишь то, что объекты должны наследоваться от CCmdTarget. Чтобы передать указатель на свой объект самому объекту webbrowser, а заодно установить целую кучу дополнительных параметров, необходимо реализовать cлужебный интерфейс IDocHostUIHandler, который описан в mshtmhst.h. Этот интерфейс представляет собой некий call-back, или интерфейс обратной связи, к которому обращается webbrowser в следующих случаях:

• Необходимо показать контекстное меню. Как раз здесь можно заменить стандартное меню Internet-explorer на свое собственное. Либо вообще сделать так, чтобы меню не показывалось.

• Есть возможность подменить элементы пользовательского интерфейса браузера.

• Нужно обработать нажатие горячей клавиши.

• Нужно обработать URL, по которому совершается переход.

• Нужно обработать события drag-and-drop.

• Необходимо получить указатель на объект window.external.

После реализации этого call-back объекта, его можно "инсталлировать", используя метод интерфейса ICustomDoc SetUIHandler. Интерфейс IСustomDoc экспортируется обычно реализуется тем же объектом, что реализует IHTMLDocument2.

// код из OnNavigateComplete

CComQIPtr<ICustomDoc, &IID_ICustomDoc> m_pBrowserCustomDoc;

CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> pADocument;

CDocHostUIHandler m_DocHostImpl;

m_DocHostImpl.AddRef;

m_DocHostImpl.m_pAppDisp = m_pApp->GetIDispatch(FALSE);

m_pBrowserCustomDoc = pADocument;

m_pBrowserCustomDoc->SetUIHandler((IDocHostUIHandler*)&m_DocHostImpl);

В данном коде фигурирует класс CDocHostUIHandler, который реализует все методы интерфейса IDocHostUIHandler (и конечно же AddRef, QueryInterface и Release от IUnknown). В базовом варианте, реализация этого объекта сводится лишь к созданию процедур-заглушек для каждого метода IDocHostUIHandler, возвращающих E_NOTIMPL. А если хочется, чтобы Internet Explorer не показывал своего конекстного меню, нужно возвращать из метода ShowContextMenu S_OK.

Если наш объект CDocHostUIHandler возвращает указатель в методе get_External, то этот указатель и используется как объект расширения и тогда где-нибудь внутри самой html странички можно будет написать такие строки:

Поделиться:
Популярные книги

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

На границе империй. Том 9. Часть 4

INDIGO
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4

Наследник

Кулаков Алексей Иванович
1. Рюрикова кровь
Фантастика:
научная фантастика
попаданцы
альтернативная история
8.69
рейтинг книги
Наследник

Совершенно несекретно

Иванов Дмитрий
15. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Совершенно несекретно

Ваше Сиятельство 2

Моури Эрли
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Ваше Сиятельство 2

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Единственная для темного эльфа 3

Мазарин Ан
3. Мир Верея. Драконья невеста
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Единственная для темного эльфа 3

Жандарм

Семин Никита
1. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
4.11
рейтинг книги
Жандарм

Долгий путь домой

Русич Антон
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
6.20
рейтинг книги
Долгий путь домой

Прогрессор поневоле

Распопов Дмитрий Викторович
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прогрессор поневоле

Наследие Маозари 6

Панежин Евгений
6. Наследие Маозари
Фантастика:
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 6

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита