. Как добавить свой пункт в контекстное меню IE
Как добавить свой пункт в контекстное меню IE

Как добавить свой пункт в контекстное меню IE

Возможность добавить собственный пункт в контекстное меню IE позволяет пользователю настроить свой броузер "под себя", расширяя его функциональность в нужную ему сторону.

К примеру, с сайта lingvo.yandex.ru вы можете загрузить модуль для IE, позволяющий получать через сеть перевод с английского или на английский любого выделенного вами в окне браузера слова или словосочетания. Удобно? Несомненно! Выделяете в броузере нужное слово, пара щелчков мышью и перед вами страница с переводом. Кроме этого существует множество модулей различных поисковиков (yandex.ru, google.com, codeproject.com), позволяющих быстро производить поиск по соответствующим сайтам. Также, альтернативные менеджеры загрузки файлов (GetRight, FlashGet и т.п.) считают своим долгом оставить след в контекстном меню IE.

После этого небольшого вступления, я думаю стало понятно в каких приложениях это может пригодиться. Давайте теперь разберемся - как это работает. Чтобы не тренироваться на кошках, попробуем написать компонент, реализующий поиск по нашему любимому сайту (если кто не понял - RSDN.ru)

Покопаемся в реестре

Internet Explorer хранит информацию о различных расширениях в реестре. В частности, "нестандартные" пункты контекстного меню можно найти по следующему адресу:

ПРИМЕЧАНИЕДобавляя разделы в ветвь HКEY_CURRENT_USER, вы влияете на настройки Internet Explorer'а только для текущего пользователя. Чтобы добавить требуемую функциональность для всех пользователей, следует использовать ветвь HKEY_LOCAL_MACHINE.

Не волнуйтесь, если раздел MenuExt на вашем компьютере отсутствует. Это всего лишь означает, что у вас пока нет дополнительных пунктов. В общем случае, чтобы добавить собственный элемент в контекстное меню, необходимо создать один раздел и пару параметров (выделены жирным). Параметры Contexts и Flags необязательны. Их значение будет пояснено ниже.

Таким образом, добавив по указанному пути новый ключ, мы создадим новый пункт контекстного меню. В качестве имени ключа следует указать текст, который будет использован при отображении меню. Также можно использовать символ "&", определяющий горячую клавишу. Значение по умолчанию для этого ключа должно содержать URL страницы, содержащей скрипт, который и будет выполнен при выборе данного элемента.

Броузер обращается к скрипту следующим образом. Содержимое страницы по соответствующему адресу загружается внутрь скрытого HTML-диалога, скрипт запускается на выполнение, по окончании которого, скрытый диалог автоматически уничтожается.

Скрипт обработки

Итак, меню добавлено, осталось написать скрипт. В следующем примере, показано, как по выбору пункта меню открыть новое окно с результатами поиска по сайту RSDN. В качестве строки для поиска передается текст выделения в активном окне.

Через свойство menuArguments объекта external можно обратиться к объекту окна (window), в котором было вызвано контекстное меню. Ну, а через этот объект легко получить доступ ко всей объектной модели Interner Explorer.

Использование COM-компонентов

Если по каким-либо причинам возможностей JavaScript/VBScript недостаточно, можно привлечь тяжелую артиллерию. Действительно, достаточно написать простой COM-объект и активизировать его из скрипта.

В следующем примере показан один из вариантов подобной реализации. В данном случае СОМ-объект содержит единственный метод Run, в который передается ссылка на объект окна.

Получив в методе Run указатель на объект окна, можем сделать что-нибудь хорошее. Например, перейти на сайт RSDN.

Используя подобную технику, легко реализовать практически любую функциональность. Например, FlashGet использует похожий прием для реализации пунктов "Закачать при помощи FlashGet" и "Закачать все"

ПРИМЕЧАНИЕНесмотря на то, что мы создаем и используем COM-объект внутри Internet Explorer'а, помечать его как "безопасный" (CATID_SafeForScripting, CATID_SafeForInitializing ) необязательно.

Контекст отображения

В прошлом примере мы добавили собственный пункт меню к IE. Однако, если задуматься, отображение нашего пункта не всегда разумно. Например, бессмысленно добавлять команду "RSDN Search" в ответ на шелчок правой клавишей на картинке или элементе ActiveX. Следовательно, имеет смысл определить контекст отображения нашего пункта меню, т.е. сообщить IE, в каких случаях следует показывать наш пункт, а в каких нет. Это можно сделать добавив в раздел "&RSDN Search" необязательный параметр Contexts .

Параметр Contexts содержит идентификатор контекстного меню, определяющий в ответ на какое действие отображать даный пункт. Возможна побитовая комбинация следующих вариантов.

ContextsЗначение По умолчанию0x1 Изображение0x2 Элемент управления0x4 Таблица0x8 Выделенный текст0x10 Ссылка0x20

К примеру, если мы хотим, чтобы наш пункт появлялся только на ссылке или при наличии выделенного фрагмента, необходимо в параметре Contexts прописать значение 0x30 (0x10 | 0x20).

Модальный режим

Задав другой необязательный параметр - Flags = 0x1 , можно заставить IE выполнять скрипт в модальном режиме. При этом, создаваемый диалог не будет скрытым, а скрипт будет запущен подобно вызову метода ShowModalDialog . К исходному окну можно обратиться также через external.menuArguments. Позаботится о закрытии диалогового окна, в этом случае, придется самостоятельно.

Чтобы продемонстрировать данный способ в действии, усложним первый пример. Давайте предоставим пользователю возможность редактировать текст поискового запроса. Для этого необходимо создать простенький HTML-диалог следующего содержания.

Как видите ничего сложного. Обычный HTML. Обычный JavaScript. При этом внешний вид HTML-диалога практически не отличается от "стандартного" диалога. В функции BodyLoad передаем выделенный фрагмент текста в строку редактирования. По нажатию кнопки "Найти", запускаем скрипт поиска на RSDN. Да, и не забываем закрыть окно.

Информация о событии

При выборе пункта меню, объект event окна источника (external.menuArguments.event) содержит некоторую полезную информацию, которую можно использовать из скрипта. Например, объект на котором щелкнули мышью, можно получить из свойства event.srcElement . А свойство event.type содержит одну из следующих строк, определяющих тип отображаемого меню:

  • MenuExtDefault
  • MenuExtImage
  • MenuExtControl
  • MenuExtTable
  • MenuExtTextSelect
  • MenuExtAnchor
  • MenuExtUnknown

Используя эту информацию, можно реализовать собственное (отличное от других) поведение для разных типов контекстного меню.

Примеры, примеры

Для демонстрации вышеизложенного приведу четыре примера:

  1. RSDN Search Скрипт поиска по выделенному фрагменту текста
  2. RSDN Search2 HTML-диалог поиска по сайту
  3. Goto RSDN! СОМ-объект, реализующий переход на RSDN.ru
  4. RSDN Search СОМ-объект, реализующий поиск по выделенному фрагменту

1 и 2-ой примеры содержат скрипты WSH (Windows Script Host) избавляющие от ручного копания в реестре. Чтобы добавить новый пункт достаточно запустить файл install.vbs . Убедитесь, что каталоги файлов со скриптами указаны верно:

В третьем примере добавление соответствующего пункта меню происходит одновременно с регистрацией COM-объекта, поэтому запускать дополнительные скрипты не требуется. Убедитесь только, что скрипт GoRSDN.dll.htm лежит в том же каталоге, что и GoRSDN.dll.

ПРИМЕЧАНИЕВы, наверное, обратили внимание на странное имя скрипта - GoRSDN.dll.htm. К сожалению, это обусловлено производственной необходимостью. Язык скриптов реестра в ATL (RGS - ReGistry Script) поддерживает простой и элегантный способ общения с реестром. Чтобы задать местоположение файла c COM-объектом, в нем используется предопределенная метка-заполнитель - %MODULE%. При вызове функции регистрации, эта метка заменяется на результат вызова функции GetModuleFileName. Существует возможность определять собственные метки-заполнители. Однако в данном случае, можно поступить проще, написав в RGS-файле следующее: '%MODULE%.htm'. При этом, в качестве URL скрипта будет прописан путь к файлу GoRSDN.dll.htm. Что, собственно, и требовалось.

Элегантное решение проблемы предложил Алексей Кирюшкин. Его способ продемонстрирован в четвертом примере. Воспользуемся тем обстоятельством, что Internet Explorer умеет загружать HTM-страницы из ресурсов. При этом можно импортировать скрипт в ресурсы DLL содержащей COM-объект. В этом случае соответствующий RGS-скрипт будет выглядеть так:

📎📎📎📎📎📎📎📎📎📎