double t;
long a;
VarI4FromR8(t, &a); // Никаких проблем с внешними ссылками
Использование Automation API позволит не только решить проблему преобразования, описанную выше, но и учесть при этом региональные настройки – например, получить локализованную строку даты. Кроме того, функция VarBstrCmpпоможет при сравнении строк unicode (но будьте осторожны с ней – в старых версиях Windows она отличается от новых реализаций, также нужно иметь установленный Service Pack 4 или выше для VC, иначе заголовочный файл будет содержать некорректное описание этой функции).
Для использования этих функций необходимо подключить библиотеку импорта oleaut32.lib.
До следующей встречи!
Алекс Jenter jenter@rsdn.ru Duisburg, 2001. Публикуемые в рассылке материалы принадлежат сайту RSDN.
Программирование на Visual C++
Выпуск №62 от 3 февраля 2002 г.
Здравствуйте, уважаемые подписчики!
СТАТЬЯ
Написание Plugin'ов для Internet Explorer
Автор: Борис Гулай aka BoresExpress
Источник: журнал "Программист" №1 за 2002
Исходные тексты примера – 11 KB
Всем памятны обвинения в адрес Microsoft в том, что включение браузера Microsoft Internet Explorer в состав операционной системы Windows недопустимо. Ответом корпорации было то, что браузер является неотъемлемой частью системы. Теперь мы можем сказать даже больше – Internet Explorer как единое приложение не существует. Это набор компонентов, которые собираются в единое целое только при запуске приложения. Сейчас мы попробуем включить в этот стройный ряд компонентов свой, чтобы он тоже стал неотъемлемой частью, ну если не операционной системы, то конкретной копии браузера точно.
Архитектура Internet Explorer
Что мы будем делать?
Что же представляет собой плагин для Internet Explorer? Это обычный внутрипроцессный (In Process) COM-сервер (т.е. DLL-файл), который содержит объект, реализующий как минимум 2 интерфейса: IOleCommandTarget и IObjectWithSite. Кроме того, наш dll-файл должен экспортировать не менее 2 функций: DllGetClassObject и DllCanUnloadNow. Думаю, их назначение всем известно.
Наш плагин будет очень простым. Он будет сохранять все ссылки страницы, которые указывают на файлы с заданными в .ini-файле расширениями в результирующий файл. Такой плагин может быть полезен, например, при создании списков закачиваемых файлов для download-менеджеров. Искать и сохранять ссылки он будет при нажатии на кнопку, которую мы добавим на панель инструментов браузера, или при выборе соответствующего пункта в меню 'Сервис'. А кнопку и пункт меню мы будем делать доступными (enabled) только в том случае, если в браузере открыт файл с расширением .htm или .html (это мы сделаем просто для демонстрации такой возможности).
Как это работает?
Теперь, когда мы определились, что будем писать, самое время узнать, как это будет работать. А работать это будет следующим образом.
Прежде всего, браузер загружает нашу библиотеку, это происходит вместе с загрузкой самого IE. Затем, после первого нажатия на кнопку (!), он вызывает экспортируемую функцию DllGetClassObject и запрашивает у неё указатель на интерфейс IClassFactory. Далее, из полученного интерфейса он вызвает метод CreateInstace и запрашивает у него интерфейс IUnknown. Это должен быть IUnknown компонента, который реализует и IOleCommandTarget и IObjectWithSite.
Два вышеназванных интерфейса должны быть реализованы именно в одном компоненте. Internet Explorer будет запрашивать один через QueryInterface другого. Поэтому реализовать их отдельно нет никакой возможности.
Такое поведение контейнера выглядит логичным, если принять во внимание то, зачем компоненту интерфейс IObjectWithSite. Через его метод SetSite браузер передаёт указатель на интерфейс, через который можно добраться до IWebBrowser – основного интерфейса WebBrowser Control. Это может потребоваться компоненту, при обработке нажатия на кнопку или выбора пункта меню, если он захочет узнать, в каком контексте произошло это событие. Поэтому совершенно логично, что IObjectWithSite должен реализовывать тот же компонент, который обрабатывает нажатие на кнопку.
После того, как произошло первое нажатие на кнопку, Internet Explorer вызывает метод SetSite интерфейса IObjectWithSite и передаёт в него IUnknown объекта, реализующего интерфейс IShellBrowser. Хочу обратить Ваше внимание, что вызов вышеназванного метода происходит только один раз.
Затем, в ответ на нажатие кнопки, вызывается метод IOleCommandTarget::Exec, в котором и происходит обработка события.
Читать дальше