Jenter Алекс
Шрифт:
Замечу, что 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:
А в .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.