Программирование на Visual C++. Архив рассылки
Шрифт:
В начале я проверяю, не хочет ли IE сказать мне этим вызовом, что происходит завершение его работы и я должен освободить его интерфейсы. Дальше – интересней. Я запрашиваю интерфейс IWebBrowser2, но не как обычно, через вызов QueryInterface, а посредством вызова метода QueryService, предварительно полученного интерфейса IServiceProvider.
Очередное
Предположим, существует некое приложение-контейнер, которое использует несколько COM-серверов. У каждого из них, естественно, есть доступ к интерфейсам контейнера (посредством IObjectWithSite::SetSite, например). Но вот кому-то из COM-серверов потребовалось получить доступ к интерфейсам другого COM-сервера, также содержащегося в контейнере.
Как же ему решить эту задачу? Ведь стандартными средствами он до другого сервера никак не доберётся, поскольку контейнер, в соответствии с идеологией COM, не предоставляет доступ к интерфейсам содержащихся в нём объектов непосредственно через вызовы QueryInterface своих интерфейсов.
Для решения таких задач как раз и предназначен интерфейс IServiceProvider. Его единственный метод – QueryService – отличается от QueryInterface одним параметром – идентификатором сервиса. Фактически – это идентификатор одного из COM-компонентов, используемых приложением-контейнером. И когда COM-сервер хочет получить интерфейс другого сервера, используемого тем же клиентом, он просто вызывает вышеназванный метод с соответствующим идентификатором сервиса.
Клиент же, в свою очередь, просто определяет, какой из содержащихся в нём компонентов соответствует переданному идентификатору и вызывает его QueryInterface.
Возвращаясь к нашей задаче, легко заметить, что здесь аналогичная ситуация. Internet Explorer представляет собой зоопарк компонентов, где наш COM-сервер (т.е. плагин) – один из питомцев. Поэтому нам и приходится использовать вышеописанную технику для получения доступа к интерфейсам другого компонента (которым, в нашем примере, является WebBrowser Control).
Следующим в очереди на реализацию у нас стоит метод QueryStatus интерфейса IOleCommandTarget. Его текст выглядит следующим образом:
В начале необходимо удостовериться в корректности переданных данных. Затем мы просто запрашиваем текущий URL и, если его последние символы .htm или .html, делаем кнопку и пункт меню доступными, или недоступными в противном случае. Следует заметить, что в этот метод всегда должен передаваться только один элемент в массиве prgCmds, т.к. мы отвечаем только за одну кнопку и пункт меню.
Теперь мы вплотную подошли к реализации основной функции нашего плагина. В ней мы будем искать содержащиеся на
Теперь остался последний штрих – регистрация нашего компонента в реестре. В первую очередь, необходимо корректно зарегистрировать наш плагин как COM-сервер. Я не буду описывать эту процедуру здесь, поскольку это лежит за рамками моей статьи, да и информации на эту тему немало. Остановимся подробнее на регистрации нашей DLL в качестве плагина для Internet Explorer.
Для этого необходимо создать следующий ключ в реестре:
В качестве <key root> может выступать либо HKEY_CURRENT_USER (в этом случае плагин будет доступен только текущему пользователю), либо HKEY_LOCAL_MACHINE (плагин будет доступен всем пользователям).
Теперь в нём необходимо создать следующие параметры:
ButtonText | Текст всплывающей подсказки для кнопки. Значение может быть как текстом, так и строкой следующего формата @dll_path,-ID, где dll_path путь к DLL плагина, ID – идентификатор строки в string table. |
CLSID | Всегда {1FBA04EE-3024-11d2-8F1F-0000F87ABD16} |
Default Visible | Будет ли кнопка, сразу после регистрации плагина, находиться на панели ('yes') или пользователь должен будет добавить её на панель самостоятельно ('no' или если параметр отсутствует). |
ClsidExtension | GUID плагина, как COM-сервера (из раздела HKCR\CLSID). |
HotIcon | Путь к иконке, соответствующей активному состоянию кнопки (когда на неё наведена мышь). Если путь указывает на .dll или .exe файл, то после него, через запятую, указывается идентификатор ресурса. |
Icon | Путь к иконке, соответствующей обычному состоянию кнопки. |
MenuText | Текст пункта в меню сервис. |
MenuStatusBar | Текст подсказки, появляющейся в строке состояния, когда пункт меню активен (формат аналогичен параметру ButtonText). |
Файл, на который указывает параметр HotIcon, должен содержать следующие цветные значки:
• 16×16 16 цветов
• 20×20 16 цветов (не обязательно)
• 20×20 256 цветов
Второй файл (соответствующий параметру Icon) должен содержать значки в оттенках серого. Параметры этих значков следующие:
• 16×16 16 оттенков серого
• 20×20 16 оттенков серого (не обязательно)
• 20×20 256 оттенков серого
Вообще-то и эти значки могут быть цветными, но в таком случае они не будут соответствовать общему стилю оформления панелей инструментов Internet Explorer. Подробнее о стиле, в котором должны быть решены эти кнопки можно прочитать здесь).
Выполнение операций по добавлению информации в реестр логично возложить на функцию DllRegisterServer, экспортируемую нашей DLL. Именно так сделано в примере к этой статье. Также в демонстрационном приложении реализована функция DllUnregidterServer, удаляющая всю информацию о плагине из реестра.
Теперь, если вы следовали приведённым выше действиям, на панели инструментов Internet Explorer должна появиться кнопка, а в меню 'Сервис' строка меню, запускающая наш плагин.