Программирование на Visual C++. Архив рассылки
Шрифт:
• IWebBrowser2. Этот интерфейс реализует управление элементом: внешним видом, параметрами, а также позволяет производить навигацию.
• DWebBrowserEvents2. Объект webbrowser использует события для уведомления приложения о состоянии компонента. Например, перед навигацией на новый URL, вызывается событие BeforeNavigate2.
Описание этих интерфейсов exdisp.h/exdispid.h. Оглядываясь на практический опыт, замечу, что ссылки на все описанные файлы лучше прописывать в stdafx.h.
Механизм подключения событий через точки соединения стандартный, поэтому не имеет смысла его здесь описывать.
Запишем в заголовочном файле класса, содержащего webbrowser control:
А в .cpp файле добавим строки:
Для полной реализации механизма отлова событий этим путем, лучше всего обратиться к исходным текстам CHTMLView.
Интерфейс DWebBrowserEvents2 при помощи события DISPID_NAVIGATECOMPLETE позволяет определить тот момент, когда HTML документ полностью сгенерирован внутри webbrowser control. После того, как это происходит, весь HTML документ доступен через функцию IWebBrowser2::get_Document. Также, как и webbrowser control, HTML документ поддерживает события, такие как click, mouseover. Для того, чтобы использовать объектную модель DHTML, нужно подключить заголовок mshtml.h.
Интерфейс IHTMLDocument2 предоставляет возможность получать и модифицировать содержимое документа. Вы можете использовать множество методов, таких как get_body, get_all, get_activeElement чтобы извлекать элементы или коллекции элементов внутри документа. Базовой основой для любого тэга внутри HTML-документа является интерфейс IHTMLElement. Меняя содержимое тэга при помощи свойств innerHTML и outerHTML мы реализуем принцип динамического содержания, который нами и преследовался. К любому элементу можно адресоваться при помощи идентификатора id через вызов IHTMLElementCollection::Item. Итак, c визуализацией ясно, а как же теперь обеспечить интерактивность? Как избавиться от ненужных клавишных комбинаций и меню? Как получить доступ из скриптов к внутренней модели объектов нашей программы?
Компания 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.
В данном коде фигурирует класс CDocHostUIHandler, который реализует все методы интерфейса IDocHostUIHandler (и конечно же AddRef, QueryInterface и Release от IUnknown). В базовом варианте, реализация этого объекта сводится лишь к созданию процедур-заглушек для каждого метода IDocHostUIHandler, возвращающих E_NOTIMPL. А если хочется, чтобы Internet Explorer не показывал своего конекстного меню, нужно возвращать из метода ShowContextMenu S_OK.
Если наш объект CDocHostUIHandler возвращает указатель в методе get_External, то этот указатель и используется как объект расширения и тогда где-нибудь внутри самой html странички можно будет написать такие строки:
В приведенном примере, функция ShowSettings и свойство BackColor запрашиваются из недр нашего собственного приложения.
Где хранить свои HTML
В ресурсах! К счастью, Internet explorer умеет грузить из ресурсов, нужно только в качестве префикса URL написать res://<путь к модулю>/<название ресурса>. Я привожу реализацию этого метода, выдранную из исходного текста CHTMLView.