Можливість додати власний пункт в контекстне меню IE дозволяє користувачеві налаштувати свій браузер "під себе", розширюючи його функціональність в потрібну йому сторону.
Наприклад, з сайту lingvo.yandex.ru ви можете завантажити модуль для IE, що дозволяє отримувати через мережу переклад з англійської або на англійську будь-якого виділеного вами в вікні браузера слова або словосполучення. Зручно? Безсумнівно! Виділяєте в броузері потрібне слово, пара кліків мишкою і перед вами сторінка з перекладом. Крім цього існує безліч модулів різних пошукових систем (yandex.ru, google.com, codeproject.com), що дозволяють швидко робити пошук за відповідними сайтам. Також, альтернативні менеджери завантаження файлів (GetRight, FlashGet і т.п.) вважають своїм обов'язком залишити слід в контекстному меню IE.
Після цього невеликого вступу, я думаю стало зрозуміло в яких додатках це може стати в нагоді. Давайте тепер розберемося - як це працює. Щоб не тренуватися на кішках, спробуємо написати компонент, який реалізує пошук по нашому улюбленому сайту (якщо хто не зрозумів - RSDN.ru)
Покопаємось в реєстрі
ПРИМІТКА
Додаючи розділи в гілку HКEY_CURRENT_USER, ви впливаєте на настройки Internet Explorer'а тільки для поточного користувача. Щоб додати необхідну функціональність для всіх користувачів, слід використовувати гілку HKEY_LOCAL_MACHINE.
Не хвилюйтеся, якщо розділ MenuExt на вашому комп'ютері відсутня. Це всього лише означає, що у вас поки немає додаткових пунктів. У загальному випадку, щоб додати власний елемент в контекстне меню, необхідно створити один розділ і пару параметрів (виділені жирним). Параметри Contexts і Flags необов'язкові. Їх значення буде пояснено нижче.
Таким чином, додавши за вказаною шляху новий ключ, ми створимо новий пункт контекстного меню. Як ім'я ключа слід вказати текст, який буде використаний при відображенні меню. Також можна використовувати символ "", що визначає гарячу клавішу. Значення за замовчуванням для цього ключа повинно містити URL сторінки, що містить скрипт, який і буде виконаний при виборі даного елемента.
скрипт обробки
Отже, меню додано, залишилося написати скрипт. У наступному прикладі, показано, як за вибором пункту меню відкрити нове вікно з результатами пошуку по сайту RSDN. Як рядки для пошуку передається текст виділення в активному вікні.
Через властивість menuArguments об'єкта external можна звернутися до об'єкта вікна (window), в якому було викликано контекстне меню. Ну, а через цей об'єкт легко отримати доступ до всієї об'єктної моделі Interner Explorer.
Використання COM-компонентів
Отримавши в методі Run покажчик на об'єкт вікна, можемо зробити що-небудь хороше. Наприклад, перейти на сайт RSDN.
Використовуючи подібну техніку, легко реалізувати практично будь-яку функціональність. Наприклад, FlashGet використовує схожий прийом для реалізації пунктів "Закачати за допомогою FlashGet" і "Закачати все"
ПРИМІТКА
Незважаючи на те, що ми створюємо і використовуємо COM-об'єкт всередині Internet Explorer'а, позначати його як "безпечний" (CATID_SafeForScripting, CATID_SafeForInitializing) необов'язково.
контекст відображення
У минулому прикладі ми додали власний пункт меню до IE. Однак, якщо замислитися, відображення нашого пункту не завжди розумно. Наприклад, безглуздо додавати команду "RSDN Search" у відповідь на шелчок правою клавішею на зображенні або елементі ActiveX. Отже, можна буде визначити контекст відображення нашого пункту меню, тобто повідомити IE, в яких випадках слід показувати наш пункт, а в яких ні. Це можна зробити додавши в розділ "RSDN Search" необов'язковий параметр Contexts.
Параметр Contexts містить ідентифікатор контекстного меню, що визначає у відповідь на яку дію відображати даний пункт. Можлива побітова комбінація наступних варіантів.
Наприклад, якщо ми хочемо, щоб наш пункт з'являвся тільки на засланні або при наявності виділеного фрагмента, необхідно в параметрі Contexts прописати значення 0x30 (0x10 | 0x20).
модальний режим
Задавши інший необов'язковий параметр - Flags = 0x1. можна змусити IE виконувати скрипт в модальному режимі. При цьому, створюваний діалог не буде прихованим, а скрипт буде запущено подібно викликом методу ShowModalDialog. До вихідного вікна можна звернутися також через external.menuArguments. Подбає про закриття діалогового вікна, в цьому випадку, доведеться самостійно.
Щоб продемонструвати цей спосіб у дії, усложним перший приклад. Давайте надамо користувачеві можливість редагувати текст пошукового запиту. Для цього необхідно створити простенький HTML-діалог такого змісту.
Інформація про подію
Захопившись створенням попередніх прикладів, мало не забув розповісти про ще одну корисну можливість.
При виборі пункту меню, об'єкт event вікна джерела (external.menuArguments.event) містить деяку корисну інформацію, яку можна використовувати з скрипта. Наприклад, об'єкт на якому клацнули мишею, можна отримати з властивості event.srcElement. А властивість event.type містить одну з наступних рядків, що визначають тип відображуваного меню:
- MenuExtDefault
- MenuExtImage
- MenuExtControl
- MenuExtTable
- MenuExtTextSelect
- MenuExtAnchor
- MenuExtUnknown
Використовуючи цю інформацію, можна реалізувати власне (відмінне від інших) поведінка для різних типів контекстного меню.
Приклади, приклади
Для демонстрації вищевикладеного наведу чотири приклади:
- RSDN Search Скрипт пошуку по виділеному фрагменту тексту
- RSDN Search2 HTML-діалог пошуку по сайту
- Goto RSDN! СОМ-об'єкт, який реалізує перехід на RSDN.ru
- 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-скрипт буде виглядати так:
Тут, "GORSDN.DLL.HTM" - строковий ідентифікатор ресурсу htm-скрипта в DLL.