    ГЛАВА       21 

    Создание элементов управления ActiveX 

    Тодд Миллер 

    Большинству пользователей, услышавших термин ActiveX, на ум сразу приходят 
элементы управления ОСХ, по-новому названные в очередном маркетинговом, трюке 
компании Microsoft В некотором смысле это так: Microsoft действительно 
использует термин ActiveX для обозначения технологий, базирующихся на модели 
СОМ. Но аббревиатура OLE уже не охватывает всех этих технологий. Microsoft 
настолько расширила определение OLE, что разработчики уже давно считают 
сопутствующие технологии чем-то отдельным от OLE. Поэтому в профессиональную 
лексику был введен термин ActiveX, используемый для обозначения всех 
базирующихся на СОМ технологий, которые существуют на данный момент и будут 
созданы в будущем. На сегодняшний день ActiveX включает следующие технологии. 

    Я Библиотеки ActiveX (внутренние серверы). 
    • Серверы автоматизации (внутренние и внешние серверы). 
    В Элементы управления ActiveX. 
    Я Формы ActiveForm (комбинированные элементы управления ActiveX). 
    И Страницы свойств. 

    -- Среда разработки ОАХ 
    Описывается среда разработки DAX, которая облегчает создание элементов 
управления ActiveX и форм ActiveForm, a также поддерживает работу со 
средствами автоматизации OLE в Delphi 3. 
    -- Элементы библиотеки типа 
    Рассматриваются элементы interface, Diaplnterface, Enum И codass библиотек 
типов, которые можно редактировать с помощью редактора библиотек типов (Type 
Library Editor). 
    --- Создание элементов управления ActiveX 
    Демонстрируется создание комбинированной формы ActiveForm с помощью 
мастера Delphi ActiveForm. 
    -- Использование элементов управления ActiveX и форм ActiveForm в Web 
    Описываются методы использования элементов управления ActiveX и форм 
ActiveForm в документах Web. Здесь также рассматриваются возможности Delphi по 
распространению этих элементов. 

    Среда разработки Delphi ActiveX (DAX) 

    Чтобы упростить разработку базирующихся на стандарте ActiveX технологий, 
необходима продуманная и спланированная среда, которая инкапсулирует в себе 

490

    сложность множества интерфейсов и функций ActiveX и OLE. Разработчики 
Delphi создали механизм, с помощью которого любой элемент управления Windows, 
порожденный классом TWinControl, можно превратить в элемент управления 
АйТуёХТ^ВьГможётё^йспользовать существующие компон^нть1,УС1- и превратить их в 
элементы ActiveX, которые будутТюлёзны в других средах разработки, например в 
Visual Basic. 
    Для облегчения преобразования разработчики Delphi создали среду Delphi 
ActiveX (DAX). Она упрощает разработку серверов СОМ, типизированных объектов 
СОМ, серверов автоматизации, элементов управления ActiveX, форм ActiveForm и 
страниц свойств. Давайте ближе познакомимся со средой DAX. 

    Объекты ActiveX в среде DAX 

    Ниже показана иерархия классов среды DAX, которые поддерживают объекты 
СОМ, типизированные объекты СОМ, серверы автоматизации, элементы управления 
ActiveX и формы ActiveForm. 

    TComObject 
    TTypedComObj ect 
    TAutoObject 
    TActiveXControl 
    TCustomForm 
    TActiveForm 

    Класс TCustomForm вместо класса TForm использован в качестве предка класса 
TActiveForm, так как в TCustomForm включены только свойства и методы, уместные 
для формы ActiveX. 

    Страницы свойств в среде DAX 

    Другой частью среды DAX являются страницы свойств, которые используются в 
различных средах программирования для изменения значений свойств элементов 
управления на этапе разработки. Страницы свойств часто оказываются 
устаревшими, так как среды программирования обладают различными реализациями 
инспекторов свойств объектов, которые позволяют оперировать свойствами 
объектов во время разработки приложения. Но несмотря на это в создаваемые 
элементы управления ActiveX нужно всегда включать страницы свойств. Даже если 
эти страницы не будут использоваться ни для чего больше, то они хотя бы 
предоставят разработчику способ построения специальных окон редактирования 
более сложных свойств элемента управления. Как будет показано ниже, в Delphi 
можно довольно просто создавать страницы свойств. Ниже показана иерархия 
классов, которая поддерживает создание страниц свойств в Delphi. 

    TCustomForm 
    TPropertyPage     
    TActiveXPropertyPage 
    [TMyProperty Page] 
    При создании новая страница свойств будет наследована от класса TPropertyPage. 

    Фабрики объектов в среде DAX 

    Delphi предоставляет клиентам (контроллерам) объекты серверов СОМ 
посредством использования фабрик (factories) объектов, которые регистрируются 
с глобальным сервером СОМ Delphi СОМ Server (ComServer), определенным в модуле 
ComServ. Сервер СОМ Delphi обрабатывает все запросы Объектов СОМ и создает 
запрашиваемые объекты, если такие зарегистрированы. Классы фабрик объектов 
используются для поддержки объектов СОМ, типизированных объектов СОМ, объектов 
автоматизации и элементов управления, которые показаны ниже в порядке наследованйяТ 

    TComObj ectFactory 
    TActiveXPropertyPageFactory 
    TTypedComObj ectFactory 
    TAutoObjectFactory     
    TActiveXControlFactory 
    TActiveFormFactJory 

    Классы TActiveXControlFactory и TActiveFormFactory используются для 
регистрации элементов управления ActiveX и форм ActiveForm. Класс TComObj 
ectFactory использовался в главе 18, "Работа с OLE, серверы документов и 
элементы управления ActiveX", для регистрации объектов СОМ, а класс TAutoObj 
ectFactory использовался для регистрации объектов автоматизации, которые 
рассматривались в главе 20, "Автоматизация OLE". 

    Глава 21. Создание элементов управления ActiveX                           491 

    Что же делают эти объекты? Они инкапсулируют интерфейс IClassFactory, 
используемый для создания объектов соответствующего класса каждый раз, когда 
клиентское приложение запрашивает определенный объект. На эти классы также 
возложена ответственность за внесение записей в реестр Windows в соответствии 
с типом класса фабрики. Например, класс TActiveXControlFactory вносит в реестр 
информацию о сервере ActiveX и соответствующей библиотеке типов. 
    Получив представление о средствах Delphi, поддерживающих разработку 
объектов ActiveX, рассмотрим инструменты Delphi для создания объектов ActiveX. 
Как это ни странно, но начать придется не с кодирования, а с документации. 
Если быть более точным, то сначала придется создать библиотеку типов, которая 
будет использоваться в Delphi для генерации шаблона кода, базирующегося на 
иерархии классов среды DAX. Позже созданный шаблон будет заполнен, 
откомпилирован, зарегистрирован и т.д. Следовательно, прежде чем приступить к 
созданию объектов ActiveX, следует усвоить, что такое информация о типах и как 
использовать редактор библиотек типов (Type Library Editor) Delphi. 
Обозначенные аспекты описаны в следую-  | щем разделе. Если же вы хорошо 
понимаете, что такое информация о типах, то можете сразу перейти к разделу 
"Элементы управления ActiveX", а к разделу "Библиотеки типов" обратитесь 
только за справочной информацией. 

    Библиотеки типов 

    Библиотеки типов — это составные документы OLE, в которых содержится 
информация об объектах СОМ, элементах управления ActiveX и объектах 
автоматизации. Информация о типах включает перечисления, свойства и методы интерфейсов. 
    Библиотека типов предназначена для предоставления другим приложениям и 
средам программирования информации о составных объектах, которые в ней 
содержатся. В процессе разработки элементов управления ActiveX и объектов 
автоматизации Delphi сохраняет информацию о типах в файле с расширением TLB, 
который в качестве ресурса компонуется в модуль DLL или ЕХЕ. 
    В следующих разделах будут коротко описаны возможности редактора библиотек 
типов Delphi и типы, которые создаются для элементов управления ActiveX, форм 
ActiveForm, объектов автоматизации и т.п. 

    Редактор библиотек типов 

    Редактор библиотек типов Delphi используется для просмотра и 
редактирования библиотек типов. Основой интерфейса редактора является панель 
Object List (рис. 21.1), с помощью которой пользователь может изменять, 
добавлять и удалять элементы библиотеки типов. Элементами библиотек типов 
являются составные классы, свойства и методы интерфейсов и перечисления. 
Панель Object List представляет элементы в виде дерева объектов. В зависимости 
от типа элемента, выбранного в панели Object List, в правой части редактора 
библиотек типов появляются различные вкладки. Возможно, это будут вкладки 
Attributes, Members и Uses. 
    Для редактирования библиотеки типов текущего проекта выполните команду 
View^Type Library. Чтобы просмотреть библиотеку типов, не являющуюся частью 
проекта, выберите пункт меню File^Open. После этого в списка File of type 
выберите строку Type Library (*.tlb;*.dll;*.ocx;*.exe;*.olb), чтобы вывести 
все файлы, которые могут содержать информацию о типах. 
    Теперь более детально рассмотрим каждый элемент библиотеки типов. Начнем с 
информации о библиотеке. 

    Информация о библиотеке типов 

    Каждая библиотека типов включает раздел, описывающий саму библиотеку, — 
элемент библиотеки типов. Когда этот элемент выбран в панели Object List (см. 
рис. 21.1), в правой части экрана редактора библиотеки типов появляются две 
вкладки: Attributes и Uses. Два следующих раздела описывают назначение вкладок 
Attributes и Uses в элементе библиотеки типов. 

    Вкладка Attributes в описании библиотеки типов 

    Во вкладке Attributes (атрибуты) содержится общая информация и 
характеристики библиотеки типов. Показанные ниже атрибуты и флаги появляются в 
этой вкладке, когда в панели Object List выбран элемент библиотеки типов (см. 
рис. 21.1). В табл. 21.1 перечислены все атрибуты, а в табл. 21.2 — все флаги 
библиотеки типов. 

    492                                           Часть V. Работа с OLE 


    Рис. 21.1. Редактирование данных о библиотеке типов 


    Таблица 21.1. Атрибуты библиотеки типов 

    Атрибут           Описание 

    Name	Имя библиотеки типов 

    QUID	Глобально уникальный 128-разрядный идентификатор библиотеки типов 
    Version	Версия библиотеки типов, записанная в формате п.т, где п — старший 
и т — младший номера версии. В качестве номера версии может использоваться и 
единичное целое число. В качестве старшего и младшего номеров версий можно 
использовать числа от 0 до 65 535 
    LCID	Идентификатор места действия (locale), описывающий один национальный 
язык, который используется для всех текстовых строк в библиотеке типов и ее элементах 
    Help String	Краткое описание библиотеки. Настоятельно рекомендуется 
указывать эту строку во всех создаваемых библиотеках 
    Help File	Имя файла справки, связанной с библиотекой типов 
    Help Context	Идентификатор контекста справки библиотеки типов 


    Таблица 21.2, Флаги библиотеки типов                                       

    Флаг             Описание 

    None	Флаги не установлены 
    Restricted	Запрещает использовать библиотеку типов в средах 
программирования макросов, таких как Visual Basic 
    Control	Указывает, что библиотека содержит элемент управления, который 
будет использован на стороне сервера для порождения новых библиотек типов и 
классов составных объектов (CoClass) 
    Hidden	Указывает, что библиотека существует, но не должна быть показана в 
пользовательских броузерах 
    Вкладка Uses в описании библиотеки типов 
    Во вкладке Uses показаны все библиотеки, на которые ссылается 
просматриваемая библиотека. С помощью ссылок на другие библиотеки типов можно 
заимствовать определения элементов, таких как перечисления или интерфейсы. Это 
поможет разработчику определить собственные интерфейсы в собственной 
библиотеке типов. Например, основной ин

    Глава 21. Создание элементов управления ActiveX                           493 

    терфейс сервера автоматизации порожден от интерфейса IDispatch, но 
вам^.н&.придехся изобретать j<oneco, так как Delphi автоматически создает 
ссылку на библиотеку типов STDOLE32.TLB, в которой определен интерфейс 
IDispatch. Библиотека STDOLE32 . TLB является основной библиотекой типов Windows. 
    С каждой записью вкладки Uses связано две части информации. Первая часть— 
имя библиотеки, на которую создается ссылка, вторая — идентификатор GUID, 
который идентифицирует библиотеку типов в реестре Windows. 

    Перечисления (Enum) в библиотеках типов 

    Перечисления в библиотеках типов практически не отличаются от перечислений 
языка Object Pascal. Перечисление в библиотеке типов — это коллекция связанных 
констант, используемая как тип данных во всех остальных элементах библиотеки 
для определенТ1^с5оТ!сТв'"или методов. Кроме того, в зависимости от среды 
программирования константы перечисления могут использоваться с объектом 
ActiveX внутри среды программирования. В следующих двух разделах 
рассматривается назначение вкладок Attributes и Members в описании перечислений. 

    Вкладка Attributes в описании перечисления 

    На рис. 21.2 показано перечисление (Enum), выбранное в окне редактора 
библиотек типов Delphi с вкладкой Attributes в правой части окна редактора. В 
табл. 21.3 перечислены все возможные атрибуты, которые можно использовать с перечислением. 

    Рис. 21.2. Редактирование перечисления в библиотеке типов 

    Таблица 21.3. Атрибуты перечисления в библиотеке типов 

    Атрибут           Описание 

    Name	Имя перечисления 
    GUID	128-разрядный идентификатор GUID-перечисления 
    Help String	Краткое описание перечисления. Настоятельно рекомендуется 
указывать эту строку во всех создаваемых библиотеках 
    Help Context	Идентификатор контекста справки по перечислению 
    Version	Версия библиотеки типов, записанная в формате п.т, где п — старший 
и те — младший номера версии. В качестве номера версии может использоваться и 
единичное целое число. В качестве старшего и младшего номеров версий можно 
использовать числа от 0 до 65 535 

    494 Часть V. Работа с OLE 


    Вкладка Members в описании перечисления 

    Во вкладке Members определяются сами константы, составляющие перечисление. 
Формат определения константы показан ниже. 

    <Имя константы> = Оначение константы>; 
    helpstring = 'Строка описания'; 

    Настоятельно рекомендуется указывать строку описания для членов 
перечисления, так как приложения, использующие ваш объект СОМ, могут зависеть 
от строк описания. На рис. 21.3 показана вкладка Members описания перечисления. 

    Рис. 21.3. Редактирование элементов перечисления в библиотеке типов 


    Элементы Interface и Displnterface в библиотеках типов 

    Интерфейс в библиотеке типов — это коллекция определений свойств и 
методов. Клиент может получить доступ к интерфейсам либо посредством 
табдиццлттуальных_меюдов, либо с помощью специального интерфейса OLE I 
Dispatch, который позволяет использовать свойства и методы объектов через 
уникальный идентификатор или DispID. Элемент Displnterface определяет 
интерфейс, доступ к которому можно получить только через интерфейс IDispatch. 
Двойной интерфейс (dual interface) — это интерфейс, доступ к которому можно 
получить JI через таблицу виртуальных методов, и через интерфейс IDispatch. В 
следующих двух разделах рассматривается назначение вкладок Attributes и 
Members в описании интерфейсов" 

    Вкладка Attributes в описании интерфейса 

    На рис. 21.4 показан интерфейс, выбранный в окне редактора библиотек 
типов, с вкладкой Attributes в правой части окна редактора. В табл. 21.4 
перечислены все возможные атрибуты, которые можно использовать в описании 
интерфейса, а в табл. 21.5 — все флаги, используемые в описании интерфейса. 

    Таблица 21.4. Атрибуты интерфейсов в библиотеках типов                     

    Атрибут           Описание 

    Name	Имя перечисления 
    GUID	128-разрядный идентификатор GUID-перечисления 
    Help String	Краткое описание перечисления. Настоятельно рекомендуется 
указывать эту строку во всех создаваемых библиотеках 
    Help Context	Идентификатор контекста справки по перечислению 


    Глава 21. Создание элементов управления ActiveX 495 


    Окончание табл. 21.4 

    Атрибут           Описание 

    Version	Версия библиотеки типов, записанная в формате п. т, где и — 
старший и т — младший номера версии. В качестве номера версии может 
использоваться и единичное целое число. В качестве старшего и младшего номеров 
версий можно использовать числа от 0 до 65 535 
    Parent Interface	Имя интерфейса, являющегося базовым классом для 
выбранного интерфейса. Этот атрибут не применяется для интерфейсов Displnterface 

    Рис. 21.4. Редактирование атрибутов интерфейсов в библиотеке типов 

    Таблица 21.5. Флаги интерфейсов в библиотеках типов 

    Флаг             Описание 

    Displnterface	Элемент описывает методы и свойства объекта, доступ к 
которому можно получить только через метод Invoke интерфейса Idispatch 
    Hidden	Указывает, что интерфейс существует, но не должен быть показан в 
пользовательских броузе-рах 
    Nonextensible	Указывает, что реализация интерфейса IDispatch включает 
только те свойства и методы, которые показаны в описании интерфейса 
    Dual	Указывает, что интерфейс предоставляет методы и свойства через 
интерфейс IDispatch и таблицу виртуальных методов 
    OLE Automation	Указывает, что интерфейс может использовать только 
совместимые с автоматизацией типы данных. С элементом Displnterface этот флаг 
использовать нельзя, так как данный элемент совместим с автоматизацией по определению 
    Вкладка Members в описании интерфейса 
    Вкладка Members в описании интерфейса содержит свойства интерфейса и 
методы, определенные в этом интерфейсе. За исключением незначительных отличий, 
синтаксис объявлений констант и методов совпадает с синтаксисом языка Object 
Pascal. Первое отличие проявляется в том, что после описания каждого свойства 
и метода должен следовать уникаль

    496                                           Часть V. Работа с OLE 

    ный идентификатор или DispID. Обычно значения Di5pID начинаются с 1 и 
увеличиваются на 1 для каждого следующего элемента. Вторым отличием являются 
ключевые слова readonly и writeonly, которые позволяют запрещать запись и 
чтение свойств соответственно. Ниже показан пример определения методов и свойств. 

    property FrameCount: Integer; readonly; dispid 1; 
    property Play(FromFrame, ToFrame: Smallint; Count: Integer); dispid 2; 
    property OpenDatabase[DatabaseName, TableName, UserName, 
    Password : WideString]: WordBool; dispid 3; 

    Последним является определение параметризованного свойства с разрешением 
только чтения. В примере это свойство использовано не только для демонстрации 
такого типа свойств, но и потому, что некоторые серверы ActiveX предпочитают 
использовать параметризованные свойства вместо методов. На рис. 21.5 показана 
вкладка Members описания интерфейса в редакторе библиотек типов Delphi. 

    Рис. 21.5. Редактирование членов интерфейса в библиотеке типов 

    Если для описания интерфейса используется инструкция Displnterface, то для 
определения методов и свойств интерфейса можно использовать только совместимые 
с автоматизацией OLE типы данных. Совместимыми с OLE являются следующие типы 
данных: Byte, Smallint, Integer, Single, Double, Currency, TDateTime, 
WideString, WordBool и OleVariant. Для передачи многомерных структур данных 
можно использовать массивы данных типа OleVariant, описанные в главе 20, 
"Автоматизация OLE". 

    Вкладка Attributes в описании свойств и методов интерфейса 

    На рис. 21.6 показано свойство интерфейса, выбранное в окне редактора 
библиотек типов, с вкладкой Attributes в правой части окна редактора. В табл. 
21.6 перечислены все атрибуты, которые используются в определении членов 
интерфейса, а в табл. 21.7 — все возможные флаги. 

    Таблица 21.6, Атрибуты членов интерфейса в библиотеках типов 

    Атрибут           Описание 

    Declaration	Объявление свойства или метода 

    ID	Значение идентификатора DispID 
    Help String	Краткое описание свойства или метода 
    Help Context	Идентификатор контекста справки по свойству или методу 
    
    Глава 21. Создание элементов управления ActiveX 497 

    Рис. 21.6. Редактирование атрибутов в библиотеке типов 

    I Таблица 21.7. Флаги членов интерфейса в библиотеках типов                

    Флаг             Описание 

    Restricted	Запрещает использовать библиотеку типов в средах 
программирования макросов, таких как Visual Basic 
    Source	Указывает, что член возвращает объект или значение типа VARIANT, 
являющееся источником событий 
    Biddable	Указывает, что свойство поддерживает связывание (binding) данных 
    Request Edit	Указывает, что свойство поддерживает сообщение OnRequestEdit 
    Display Bindable	Указывает, что свойство должно быть показано пользователю 
как поддерживающее связывание данных (bindable) 
    Default Bindable	Указывает на одно поддерживающее связывание данных 
свойство, которое наилучшим образом представляет объект 
    Hidden	Указывает, что интерфейс существует, но не должен быть показан в 
пользовательских броузерах 


    Составные классы (CoClass) в библиотеках типов 

    Составной класс в библиотеке типов (CoClass) представляет весь элемент 
управления ActiveX, объект автоматизации или специальный объект СОМ. Составной 
класс включает интерфейсы и диспинтерфейсы, которые предоставляются 
клиентскому приложению. В следующих двух разделах рассматривается назначение 
вкладок Attributes и Members редактора библиотек типов в описаниях классов 
составных объектов. 

    Вкладка Attributes в описании классов составных объектов 

    В табл. 21.8 перечислены все атрибуты, а в табл. 21.9 — флаги, которые 
используются в описаниях составных классов. 

    Таблица 21.8. Атрибуты составных классов в библиотеках типов 

    Атрибут           Описание 

    Name	Имя составного класса (СоС1а5з) 
    GUID	Уникальный 128-разрядный идентификатор GUID составного класса (CoClass) 
    Help String	Краткое описание составного класса. Настоятельно рекомендуется 
указывать эту строку во всех создаваемых библиотеках 


    498 Часть V. Работа с OLE 


    Окончание табл. 21.8 

    Атрибут           Описание 

    Help Context	Идентификатор контекста справки по составному классу 
    Version	Версия библиотеки типов, записанная в формате п.т, где п версии. В 
качестве номера версии может использоваться и старшего и младшего номеров 
версий можно использовать	— старший и т — младший номера единичное целое 
число. В качестве числа от 0 до 65 535 
    
    Таблица 21.9. Флаги составных классов в библиотеках типов                  

   Флаг             Описание 

Licensed	Указывает, что во время разработки и выполнения требуется 
лицензия. Обычно используется вместе с элементами управления ActiveX
Control	Указывает, что составной класс является элементом управления 
Application Object	Указывает, что составной класс помещен во внешний 
(out-of-process) сервер (ЕХЕ). Используется исключительно с серверами автоматизации 


    Вкладка Members в описании составного класса 

    Во вкладке Members в описании составного класса можно добавлять и удалять 
интерфейсы и перечисления, которые составляют класс СОМ. В рассматриваемой 
вкладке содержится следующая информация. 
    • Имена интерфейсов и диспинтерфейсов, которые реализованы в классе СОМ. 
    • Идентификаторы GUID интерфейсов и диспинтерфейсов, реализованных в 
классе СОМ. 
    • Указания, является ли интерфейс или диспинтерфейс источником сообщений. 
    • Указания, является ли интерфейс или диспинтерфейс программируемым 
интерфейсом, используемым в языках программирования макросов, таких как Word 
Basic, Visual Basic, D.el.phi.^.Qbject PAL и Excel Basic.     —— • -
    И! Указания, запрещено ли использование интерфейса или диспинтерфейса в 
языках программирования макросов, таких как Word Basic, Visual Basic, Delphi, 
Object PAL и Excel Basic. 
    Чтобы добавить интерфейсы в составной класс или удалить их, нужно щелкнуть 
правой кнопкой мыши в области вкладки Members. На экране появится контекстное 
меню, в котором нужно выбрать команду Insert Interface или Remove Interface. С 
помощью контекстного меню можно также установить флаги Source, Default и 
Restricted. Новые интерфейсы можно выбирать из текущей библиотеки или из 
библиотек, на которые ссылается текущая библиотека типов. 

    Элементы управления ActiveX 

    Теперь займемся увлекательным делом — создадим элементы управления 
ActiveX. Рассмотрим, что собой представляет ActiveX и чем элементы управления 
ActiveX лучше или хуже стандартных компонентов Delphi на базе библиотек VCL. 
    Технология ActiveX компании Microsoft представляет собой технологию ОСХ, 
переделанную для обеспечения передачи элементов управления через службы 
Internet, в основном через \Vorld Wide Web. Я уверен, что читатель спросит: 
    "Это^с^хорошо, но как технология ActiveX может помочь мне?". Но неужели 
вам не хочется создать элементы управления, которые можно 
использрвать.не_1С)лы<р в, Delphi,, но..и в таких средах программирования, как 
Borland C++ Builder. Visual C++ и Visual Basic? Технология ActiveX 
предоставляет вам такую возможность. 
    Чтобы использовать эту возможность, Delphi предлагает с помощью среды DAX 
заключить потомка класса TWinControl в элемент управления ActiveX. Ниже 
перечислены платформы, на которых сертифицированы для выполнения элементы 
управления ActiveX, поставляемые с Delphi. 
    •I Borland Delphi версий 2 и 3. 
    • Borland C++Builder. 
    Я Borland Paradox 8. 
    •E Borland IntraBuiIder. 


    Глава 21. Создание элементов управления ActiveX                           499 


    • Microsoft Visual C++. 
    • Microsoft Visual Basic версий 4 и 5. 
    • Microsoft Internet Explorer 3.01. 
    • Microsoft ActiveX Control Pad. 
    • Microsoft Frontpage. 
    Создание элемента управления ActiveX предусматривает выполнение следующих этапов. 
    1. Элемент управления VCL должен быть вставлен в палитру компонентов 
Delphi и должен быть потомком класса TWinControl. Чтобы создать элемент 
управления ActiveX, являющийся потомком TGraphicControl, в большинстве случаев 
достаточно изменить базовый класс на TCustomControl. Этот способ использован в 
примере, который будет приведен немного позже. 
    2. Запустите MacTecia.ActiyeX Control, выбрав команду File^New и дважды 
щелкнув на пиктограмме ActiveX Control во вкладке ActiveX. В окне мастера 
выберите компонент VCL, который нужно преобразовать в элемент ActiveX, укажите 
имя элемента ActiveX, включите или отключите информацию о лицензировании, 
версии и т.п. После щелчка на кнопке OK Delphi создаст библиотеку типов со 
всеми свойствами, объявленными как public и published, методами и событиями. 
Дополнительно создаются два файла исходного кода: в одном из них содержатся 
определения из библиотеки типов (интерфейсы, диспинтерфейсы и т.д.), а во 
втором — реализации методов интерфейса, определенных в первом файле. 
    3. В процессе создания библиотеки типов Delphi может преобразовать не все 
конструкции языка то ли потому, что нет смысла преобразовывать отдельные 
конструкции, то ли потому, что она не знает, как преобразовать некоторые 
конструкции языка Object Pascal. Независимо от причины, по которой 
преобразование не выполнилось, в определение элемента ActiveX можно.легко 
добавить любые свойства, методы и события. Для этого откройте библиотеку типов 
(с помощью команды View^Type Library), внесите необходимые изменения и 
щелкните на кнопке Refresh панели инструментов редактора библиотек типов, что 
позволит Delphi обновить код. 
    4. Создайте код всех методов Get и Set, в которых не реализована 
необходимая функциональность или которые оставлены пустыми, как добавления к 
библиотеке типов. Это относится и к обработчикам событий. 
    5. Теперь вы, возможно, пожелаете создать одну или несколько страниц 
свойств. В средах, не поддерживающих инспек-   ; торов свойств, это даст 
возможность пользователю, щелкнув правой кнопкой мыши, вызвать некоторое 
подобие инспектора свойств для изменения значений свойств элемента управления. 
Для этого, как минимум, нужно создать ос
    LHOBHyro страницу свойств. Delphi обладает несколькими стандартными 
страницами свойств для управления цветом, шрифтами, изображением и списком 
строк Delphi. 
    6. Откомпилируйте и зарегистрируйте элемент управления. 
    7. ОСХ-файл можно импортировать в любую среду разработки, поддерживающую 
элементы управления ActiveX, которые созданы в Delphi. 

    Создание элемента управления ActiveX - PieX 

    Лучший способ разобраться в разработке элементов управления ActiveX — 
создать один элемент. Поэтому в данном разделе описан способ создания элемента 
ActiveX на базе простого компонента Delphi TPie. Если вы знакомы с компонентом 
TPie, то должны вспомнить, что он наследован от класса TGraphicControl и 
поэтому его нельзя превратить в элемент управления ActiveX непосредственно. 
Это относится ко всем потомкам класса TGraphicControl. Тем не менее, если 
изменить исходный код компонента TPie и использовать в качестве базового класс 
TCustomControl вместо класса TGraphicControl, компонент TPie станет явным 
кандидатом на преобразование в элемент управления ActiveX. 
    Следуйте приведенным выше указаниям и в файле PIES. РАЗ в каталоге 
\DEMOS\PROPEDIT\ замените базовый класс компонента TPie на TCustomControl. 
Если эти действий не будут выполнены, то новый компонент TPie не появится в 
мастере ActiveX Control. 
    После этого в путь поиска файлов в вашем проекте нужно добавить полный 
путь к файлу PIES. PAS (меню Project^Options, вкладка 
Directories/Conditionals, поле Search path). 

    500                                           Часть V. Работа с OLE 

    Затем следует установить компонент TPie в панель компонентов Delphi, чтобы 
его можно было преобразовать в элемент управления ActiveX. Для этого выполните 
команду File^Open и в списке File of type диалогового окна Open выберите 
значение Delphi package source (*.dpk). После этого перейдите в каталог . . 
\DEMOS\PROPEDIT\ и дважды щелкните на файле PIELIB. DPK. На экране появится 
диалоговое окно редактора модулей (Package Editor) Delphi. 
    Щелкните на кнопке Install, после чего закройте диалоговое окно. Компонент 
TPie появится во вкладке Samples, в палитре компонентов Delphi. Если вы не 
знакомы с этим компонентом, то поэкспериментируйте с ним перед началом его 
преобразования в элемент ActiveX. Выполнив двойной щелчок на установленном в 
форме компоненте TPie, обратите особое внимание на работу редактора этого компонента. 

    Использование мастера ActiveX Control 

    Чтобы запустить мастера ActiveX Control, нужно выбрать команду File^New и 
выполнить двойной щелчок на пиктограмме ActiveX Control вкладки ActiveX (рис. 21.7). 
    Первое поле мастера предлагает выбрать имя реального элемента управления 
VCL, который нужно преобразовать в элемент управления ActiveX. В списке VCL 
Class Name выберите компонент TPie (рис. 21.8). 

    Рис. 21.7. Запуск мастера ActiveX Control 

    Рис, 21.8. Выберите компонент TPie в мастере ActiveX Control, чтобы 
преобразовать этот компонент в элемент управления ActiveX 

    Если компонент TPie не появился во вкладке Samples в палитре компонентов 
Delphi, значит, не был модифицирован модуль PIES. РАЗ либо не был установлен 
модуль PIELIB. DPK. В остальных полях следует оставить значения, установленные 
по умолчанию, но запомните имена используемых файлов, так как очень скоро эти 
файлы вам придется просматривать. Установите флажок Include Design-time 
License, назначение которого описано в следующем разделе. 
    Щелкните на кнопке ОК, и Delphi создаст библиотеку типов для общедоступных 
(public) и опубликованных (published) свойств, методов и событий компонента 
TPie. Свойства Brush и Pen не добавлены в элемент управления ' 'SctiveX, так 
как они являются вложенными. Дополнительно Delphi создала файл проекта 
(PieXControl. dpr), модуль реализации (PieXIrnpl .раз), библиотеку типов 
(PieXControl. tib) и файл лицензии (PieXControl. lie). Кроме того, Delphi 
поддерживает модуль (PieXControlLib. раз), информация в котором соответствует 
данным в библиотеке типов. Этот модуль будет включен в раздел uses в каждом 
модуле реализации в проекте библиотеки ActiveX. 

    Проверка информации о типах 

    Прежде всего, рассмотрим библиотеку типов элемента PieXControl. Редактор 
библиотек типов не появляется на экране автоматически, поэтому нужно выполнить 
команду View=>Type Library. На рис. 21.9 показаны элементы библиотеки типов 
проекта PieXControl. 

    В табл. 21.10 перечислены элементы библиотеки типов проекта PieXControl. 

    Глава 21. Создание элементов управления ActiveX                           501 


    Таблица 21.10. Элементы библиотеки типов проекта PieXControl 

    Элемент           Описание 

    PieXControlLib Информация, относящаяся ко всей библиотеке 
    IpieX Интерфейс, определяющий свойства и методы элемента TPie, которые 
предоставляются клиентам 
    IpieXEvents Диспинтерфейс, крто,рый определяет 
предоставляемыеклиентам.события компонента TPie 
    PieX Составной класс (CoClass), предоставляющий клиенту интерфейсы PieX и PieXEvents 
    TxMouseButton Перечисление, которое определяет кнопки мыши 

    Рис. 21.9. Библиотека типов проекта pieXControl 

    Выбрав вкладку Members интерфейса IPieX, заметьте, что не все свойства 
компонента TPie предоставляются клиентам. В основном, клиентам не 
предоставляются подчиненные свойства компонента. Для демонстрации способов 
добавления свойств и методов в библиотеку типов добавим два свойства, которые 
предоставят клиентам доступ к подчиненным свойствам компонента TPie. 
    Добавление свойств и методов 
    Прежде чем добавлять свойства и методы, следует удостовериться, что в 
редакторе библиотек типов выбран интерфейс IPieX и открыта вкладка Members 
этого элемента. На этой вкладке показаны четыре элемента. Перечисленные ниже 
элементы следует вносить в конец приведенного списка. 

    property EndAngle: Integer; dispid 5; 
    property StartAngle: Integer; di5pid 6; 
    property BrushColor: Integer; dispid 7; 
    property PenColor: Integer; dispid 8; 

    Добавив эти свойства, разработчик сможет предоставить клиентам свойства 
компонента TPie Angle. StartAngle, Angle . EndAngle, Brush. Color и Pen 
.Color. Заметьте, что здесь использованы последовательные идентификаторы 
DispID, начиная со значения 5. Для каждого свойства и метода необходимо 
указывать уникальный идентификатор. 

    ПРЕДОСТЕРЕЖЕНИЕ 
    В качестве идентификаторов DispID всегда следует использовать 
положительные значения. Отрицательные значения идентификаторов зарезервированы 
системой Windows. 


    502 Часть V. Работа с OLE 

    После внесения приведенных выше свойств щелкните на кнопке Refresh, 
расположенной на панели инструментов редактора библиотек типов. После этого 
Delphi обновит исходный код в файле Pielmpi. раз. 
    Теперь рассмотрим два исходных файла, которые созданы Delphi для проекта 
PieXControl (не включая файла самого проекта). Сначала рассмотрим файл 
PIEXCONTROLLIB. РАЗ. Заметьте, что имя файла совпадает с внутренним именем 
библиотеки. Файл библиотеки (TLB) имеет такое же имя, что и файл исходного 
кода проекта. В основном файл PieXControlLib.pas отражает все, что определено 
в библиотеке типов (листинг 21.1). 

    Листинг 21.1. \UDELPHl3\CHP2l\PlEXCONTROLLlB. PAS. Представление 
определений, созданных с помощью среды DAX в библиотеке типов проекта 

    unit PieXControlLib; 
    { PieXControlLib Library } 
    { Version 1.0 } 
    interface 
    uses Windows, ActiveX, Classes, Graphics, OleCtrls, StdVCL; 
    const 
    LIBID_PieXControlLib: TGUID = '{88DAF8EO-5AA5-11DO-A45E-444553540000 } ' ; 
    const 
    { MouseButton } 
    mbLeft = 0; 
    mbRight = 1; 
    mbMiddle = 2; 
    const 
    { Идентификатор GUID составного класса. } 
    Class_PieX: TGUID = '(88DAF8E3-5AA5-11DO-A45E-444553540000}'; 
    type 
    { Предварительные объявления. } 
    IPieX = interface; 
    DPieX = dispinterface; 
    IPieXEvents = dispinterface; 
    PieX = IPieX; 
    MouseButton = TOleEnum; 
    ( Интерфейс Dispatch для элемента PieX. } 
    IPieX = interface(IDispatch) 
    ['{88DAF8E1-5AA5-11DO-A45E-444553540000}'] 
    procedure Paint; safecall; 
    function Get Visible: WordBool; safecail; 
    procedure Set_Visible(Value: WordBool); safecall; 
    function Get Enabled: WordBool; safecall; 
    procedure Set Enabled(Value: WordBool); safecall; 
    function Get Cursor: Smallint; safecall; 
    procedure Set Cursor(Value: Smallint); safecall; 
    function Get_EndAngle: Integer; safecall; 
    procedure Set_EndAngie(Value: Integer); safecall; 
    function Get StartAngle: Integer; safecall; 
    procedure Set StartAngle(Value: Integer); safecall; 
    function Get_BrushColor: Integer; safecall; 
    procedure Set_BrushColor(Value: Integer); safecall; 
    function Get_PenColor: Integer; safecall; 


    Глава 21. Создание элементов управления ActiveX                           503 


    procedure Set_PenColor(Value: Integer); safecall; 
    property Visible: WordBool read Get_Visible write Set_Visible; 
    property Enabled: WordBool read Get_Enabled write Set_Enabled; 
    property Cursor: Smallint read Get_Cur5or write Set_Cursor; 
    property EndAngle: Integer read Get_EndAngle write Set_EndAngle; 
    property StartAngle: Integer read Get_StartAngle write Set_StartAngle; 
    property BrushColor: Integer read Get_BrushColor write Set_BrushColor; 
    property PenColor: Integer read Get_PenColor write Set_PenColor; 
    end; 
    ( Объявление диспинтерфейса для интерфейса IPieX типа Dual. } 
    DPieX  = dispinterface 
    ['{88DAF8E1-5AA5-11DO-A45E-444553540000}'] 
    procedure Paint; dispid 1; 
    property Visible: WordBool dispid 2; 
    property Enabled: WordBool dispid 3; 
    property Cursor: Smallint dispid 4; 
    property EndAngle: Integer dispid 5; 
    property StartAngle: Integer dispid 6; 
    property BrushColor: Integer dispid 7; 
    property PenColor: Integer dispid 8; 
    end; 
    { Интерфейс событий для элемента PieX. } 
    IPieXEvents = dispinterface 
    ['{88DAF8E2-5AA5-11DO-A45E-444553540000}'] 
    procedure OnClick; dispid 1; 
    procedure OnDblClick; dispid 2; 
    end; 
    { Элемент управления ActiveX PieXControl. } 
    TPieX = class(TOleControl) private 
    FOnClick: TNotifyEvent; 
    FOnDblClick: TNotifyEvent; 
    FIntf: IPieX; 
    protected 
    procedure InitControlData; override; 
    procedure InitControlInterface(const Obj: lUnknown); override; 
    public 
    procedure Paint; 
    property Controllnterface: IPieX read FIntf; 
    published 
    property TabStop; 
    property Align; 
    property DragCursor; 
    property DragMode; 
    property ParentShowHint; 
    property PopupMenu; 
    property ShowHint; 
    property TabOrder; 
    property OnDragDrop; 
    property OnDragOver; 
    property OnEndDrag; 
    property OnEnter; 
    property OnExit; 
    property OnStartDrag; 
    property Visible: WordBool index 2 read GetWordBoolProp 
    write SetWordBoolProp stored False; 
    property Enabled: WordBool index 3 read GetWordBoolProp 
    write SetWordBoolProp stored Falser
    property Cursor: Smallint index 4 read GetSmallintProp 


    504                                           Часть V. Работа с OLE 


    write SetSmallintProp stored False; 
    property EndAngle: Integer index 5 read GetIntegerProp 
    write SetIntegerProp stored False; 
    
    property StartAngle: Integer index 6 read GetIntegerProp 
    write SetIntegerProp stored False; 
    
    property BrushColor: Integer index 7 read GetIntegerProp 
                         write SetIntegerProp stored False; 
    
    property PenColor: Integer index 8 read GetIntegerProp 
                         write SetIntegerProp stored False; 
    
    property OnClick: TNotifyEvent read FOnClick write FOnClick; 
    
    property OnDblClick: TNotifyEvent read .FOnDblClick 
                         write FOnDblClick; 
    end; 
    procedure Register; 
    implementation 
    uses ComObj ; 
    procedure TPieX.InitControlData; 
    const 
    CEventDispIDs: array[0..1] of Integer = ( 
    $00000001, $00000002); 
    CLicenseKey: array[0..38] of Word = ( 
    $007B, $0038, $0038, $0044, $0041, $0046, $0038, $0045, $0035, $002D, 
    $0035, $0041, $0041, $0035, $002D, $0031, $0031, $0044, $0030, $002D, 
    $0041, $0034, $0035, $0045, $002D, $0034, $0034, $0034, $0035, $0035, 
    $0033, $0035, $0034, $0030, $0030, $0030, $0030, $007D, $0000); 
    CControlData: TControlData = ( 
    ClassID: '{88DAF8E3-5AA5-11DO-A45E-444553540000}' ; 
    EventIID: '{88DAF8E2-5AA5-11DO-A45E-444553540000}' ; 
    EventCount: 2; 
    EventDispIDs: QCEventDispIDs; 
    LicenseKey: @CLicenseKey; 
    Flags: $00000000; 
    Version: 300; 
    FontCount: 0; 
    FontIDs: nil); 
    begin 
    ControlData := @CControlData; 
    end; 
    procedure TPieX.InitControlInterface(const Obj: lUnknown) ; 
    begin 
    FIntf := Obj as IPieX; 
    end; 
    procedure TPieX.Paint; 
    begin 
    Controllnterface.Paint; 
    end; 
    procedure Register; 
    begin 
    RegisterComponents('ActiveX', [TPieX]) ; 
    end; 
    end. 
    Первое, что вы видите в показанном файле, это объявление перечисления 
MouseButton и его констант. Далее следует интерфейс PieX, который определяет 
свойства и методы элемента управления ActiveX. Заметьте, что для каждого 
свойства в модуле Delphi определены методы Get и Set. Затем следует 
определение диспинтерфейса IPieXEvents. События определены, как диспинтерфейс, 
поскольку они генерируются по идентификатору DispID в контейнере клиента. 

    Глава 21. Создание элементов управления ActiveX                           505 

    Полная реализация библиотеки элемента управления ActiveX находится в файле 
Pielmpi.pas (листинг 21.2). Для нормального функционирования свойств нужно 
реализовать методы Get и Set, как показано ниже. 

    function TPieX.Get_EndAngle: Integer; safecall; 
    begin 
    Result := FDelphiControl-Angles.EndAngle;; 
    end; 
    procedure TPieX.Set EndAngle(Value: Integer); safecall; 
    begin 
    FDelphiControl.Angles.EndAngle := Value; 
    end; 
    function TPieX.Get_StartAngle: Integer; 
    begin 
    Result := FDelphiControl.Angles.StartAngle; 
    end; 
    procedure TPieX.Set_StartAngle(Value: Integer); 
    begin 
    FDelphiControl.Angles.StartAngle := Value; 
    end; 
    function TPieX.Get_BrushColor: Integer; safecall; 
    begin 
    Result := FDelphiControl.Brush.Color; 
    end; 
    procedure TPieX.Set BrushColor(Value: Integer); safecall; 
    begin 
    FDelphiControl.Brush.Color := Value; 
    end; 
    function TPieX.Get PenColor: Integer; safecall; 
    begin 
    Result := FDelphiControl.Pen.Color; 
    end; 
    procedure TPieX.Set PenColor(Value: Integer); safecall; 
    begin 
    FDelphiControl.Pen.Color := Value; 
    end; 

    Листинг 21.2. \UDELPHl3\CHp2l\PlElMpL. PAS. Реализация методов интерфейса 
и методов Get и set, определенных в файле PIEXCONTROLLIB . PAS 

    unit Pielmpi; 
    interface 
    uses 
    Windows, ActiveX, Classes, Controls, Graphics, Menus, Forms, StdCtrls, 
    ComServ, AxCtrls, PieXControlLib, Pies; 
    type 
    TPieX = class(TActiveXControl, IPieX) 
    private 
    { Private declarations } 
    FDelphiControl: TPie; 
    FEvents: IPieXEvents; 
    procedure ClickEvent(Sender: TObject) ; 
    procedure DblClickEvent(Sender: TObject); 
    protected 
    { Protected declarations } 


    506                                           Часть V. Работа с OLE 


    procedure InitializeControl; override; 
    procedure EventSinkChanged(const EventSink: lUnknown); override; 
    procedure DefinePropertyPages ( 
    DefinePropertyPage: TDefinePropertyPage); override; 
    function Get BrushColor: Integer; safecall; 
    function Get_Cursor: Smallint; safecall; 
    function Get Enabled: WordBool; safecall; 
    function Get_StartAngle: Integer; safecall; 
    function Get_EndAngle: Integer; safecall; 
    function Get Visible: WordBool; safecall; 
    function Get PenColor: Integer; safecall; 
    procedure Paint; safecall; 
    procedure Set BrushColor(Value: Integer); safecall; 
    procedure Set Cursor(Value: Smallint); safecall; 
    procedure Set Enabled(Value: WordBool); safecall; 
    procedure Set_EndAngle(Value: Integer); safecall; 
    procedure Set_StartAngle(Value: Integer); safecall; 
    procedure Set PenColor(Value: Integer); safecall; 
    procedure Set Visible(Value: WordBool); safecall; 
    end; 
    implementation 
    uses PieAngle, PieColors; 
    { TPieX } 
    procedure TPieX.InitializeControl; 
    begin 
    FDelphiControl := Control as TPie; 
    FDelphiControl.OnClick := ClickEvent; 
    FDelphiControl.OnDblClick := DblClickEvent; 
    end; 
    procedure TPieX.EventSinkChanged(const EventSink: lUnknown); 
    begin 
    FEvents := EventSink as IPieXEvents; 
    end; 
    procedure TPieX.DefinePropertyPages( 
    DefinePropertyPage: TDefinePropertyPage) ; 
    begin 
    ( Define property pages here.  Propery pages are defined by calling 
    DefinePropertyPage with the class id of the page.  For example, 
    DefinePropertyPage(Class_PieXPage); ) 
    DefinePropertyPage( Class_PieGeneralPropertyPage ); 
    DefinePropertyPage( Class_PieColorPropertyPage ); 
    end; 
    function TPieX.Get_EndAngle: Integer; safecall; 
    begin 
    Result := FDelphiControl.Angles.EndAngle; ; 
    end; 
    procedure TPieX.Set_EndAngle(Value: Integer); safecall; 
    begin 
    FDelphiControl.Angles.EndAngle := Value; 
    end; 
    function TPieX.Get BrushColor: Integer; safecall; 
    begin 
    Result := FDelphiControl.Brush.Color; 
    end; 
    procedure TPieX.Set_BrushColor(Value: Integer); safecall; 


    Глава 21. Создание элементов управления ActiveX                           507 


    begin 
    FDelphiControl.Brush.Color := Values
    end; 
    function TPieX.Get_PenColor: Integer; safecall; 
    begin 
    Result := FDelphiControl.Pen.Colors
    end; 
    procedure TPieX.Set PenColor(Value: Integer); safecall; 
    begin 
    FDeiphiControl.Pen.Color := Values
    end; 
    function TPieX.Get_Cursor: Smallint; 
    begin 
    Reault := Smallint(FDelphiControl.Cursor); 
    end; 
    function TPieX.Get_Enabled: WordBool; 
    begin 
    Result := FDelphiControl.Enabled; 
    end; 
    function TPieX.Get_Visible: WordBool; 
    begin 
    Result := FDelphiControl.Visible; 
    end; 
    procedure TPieX.Paints
    begin 
    FDelphiControl.Paint ; 
    ends
    procedure TPieX.Set_Cursor(Value: Smallint); 
    begin 
    FDelphiControl.Cursor := TCursor(Value) ; 
    ends
    procedure TPieX.Set_Enabled(Value: WordBool); 
    begin 
    FDelphiControl.Enabled := Valuesend; 
    procedure TPieX.Set_Visible(Value: WordBool); 
    begin 
    FDelphiControl.Visible :•= Values
    ends
    procedure TPieX.ClickEvent(Sender: TObject) ; 
    begin 
    if FEvents о nil then FEvents-OnClick; 
    ends
    procedure TPieX.DblClickEvent(Sender: TObject); 
    begin 
    if FEvents <> nil then FEvents.OnDblClick; 
    ends
    function TPieX.Get_StartAngle: Integers
    begin 
    Result := FDelphiControl.Angles.StartAngle; 
    ends
    procedure TPieX.Set_StartAngle(Value: Integer); 


    508                                           Часть V. Работа с OLE 


    begin 
    FDelphiControl.Angles.StartAngle := Value; 
    end; 
    initialization 
    TActiveXControlFactory.Create( 
    ComServer, 
    |         TPieX, 
    TPie, 
    Class_PieX, 
    1, 
    '{6DB6FBDO-96D3-11DO-AOCO-OOC04FC29155}', 
    0); 
    end. 

    В коде реализации присутствует несколько интересных фрагментов. Метод 
InitializeControl переопределен для установки элемента управления VCL, который 
представляет элемент ActiveX, и для выбора методов для каждого обработчика 
событий в файле реализации. 

    procedure TPieX.InitializeControl; 
    begin 
    FDelphiControl := Control as TPie; 
    FDelphiControl.OnClick := ClickEvent; 
    FDelphiControl.OnDblClick := DblClickEvent; 
    end; 

    .Методы обработки события являются подходящими кандидатами для вставки 
специального кода настройки элемента управления ActiveX. 
    Кстати о событиях. События диспинтерфейса должны быть связаны с каналами 
обработки событий (Event Sink) в методе 
EventSinkChang?cr~Hnace"ffo1<a3aH~npHMep такого метода. 

    procedure TPieX.EventSinkChanged(const EventSink: lUnknown); 
    begin 
    FEvents := EventSink as IPieXEvents; 
    end; 

    В конце файла Pielmpl.pas вы увидите фрагмент кода, создающий специальный 
класс среды DAX TActiveXControlFactory. После создания этот класс регистрирует 
элемент управления ActiveX вместе с глобальным объектом сервера СОМ Delphi 
ComServer. В процессе регистрации серверу ComServer передается идентификатор 
класса CLSID и ссылка на класс, благодаря чему сервер знает, что нужно 
создавать по запросу с выбранным идентификатором класса. Ниже показан 
соответствующий фрагмент кода. 

    initialization 
    TActiveXControlFactory.Create( 
    ComServer, 
    TPieX, 
    TPie, 
    Class_PieX, 
    1, 
    '{6DB6FBDO-96D3-11DO-AOCO-OOC04FC29155)', 
    0); 
    end. 

    Уникальный идентификатор GU1D, являющийся последним параметром 
конструктора TActiveXControlFactory. Create, используется в качестве значения 
лицензионного ключа. Вы можете спокойно изменять значение этого параметра, но 
в этом случае нужно внести соответствующие изменения в файл <Имя проекта>. 
lie, который создан, чтобы различать лицензирование элемента управления 
ActiveX на этапах разработки и выполнения. Практически элемент управления 
ActiveX уже создан, но перед тестированием создадим страницы свойств Angle и 
Color для этого элемента ActiveX. 

    Создание страниц свойств 

    Каждая страница свойств является отдельной формой, которая может 
использоваться для изменения значений свойств элементов ActiveX и контроля 
вносимых изменений во время разработки приложений. Страницы свойств 
определяются посредством вызова метода DefinePropertyPage для каждой страницы 
свойств. Этому методу передается идентифи

    Глава 21. Создание элементов управления ActiveX                           509 


    катор класса каждой страницы свойств. Перечисленные действия выполняются в 
переопределенном „методе DefinePropertyPages, в модуле реализации элемента 
управления ActiveX. Поскольку нужно определить две страницы свойств, выполните 
два вызова метода DefinePropertyPage, как показано ниже. 

    property!TPieX.DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage); 
    begin 
    DefinePropertyPage( Class_PieGeneralPropertyPage ); 
    DefineP|ropertyPage ( Class_PieColorPropertyPage ) ; 
    end; 
    Class_DC<j)lorPropPage 
    Class_DFontPropPage 
    Class_DplcturePropPage 
    Class_DStringPropPage 

    Для создания новой страницы свойств выберите команду File'=?New и во 
вкладке ActiveX дважды щелкните на пиктограмме Property Page. Вместо 
рассмотрения процесса создания страниц свойств обратимся к пройкту 
T'TEXCONTROL. DPR "каталога \UDELPHI3\CHP21\. Две интересующие нас страницы 
свойств определены в модулях PieAngle и PieColor. В каждом из них создана 
форма редактирования соответствующего свойства. Особое внимание нужно обратить 
на способ передачи значений свойств из элемента ActiveX в форму и передачи 
новых значений обратно. Это выполняется путем переопределения специальных 
методов tJpaatePropertyPage и UpdateObject. 

    procedure Т PieGeneralProperty Page.UpdatePropertyPage; 
    begin 
    { Обновление значений элементов__формы из объекта OleObject.} 
    StartAngleTrackBar. Pos.iTlon~"':= OleObject. Start'Angle; 
    EndAngleTrackBar.Position := OleObject.EndAngle; 
    end; 
    procedure TPieGeneralPropertyPage.UpdateObject; 
    begin 
    ( Обновление свойств объекта 01еОЬ^ес1;_,.значениями,.,из^^одмы. } 
    OleObject.StartAngle :"= StartAngleTrackBar.Position; 
    OleObject.EndAngle := EndAngleTrackBar.Position; 
    end; 


    Регистрация и установка элемента управления ActiveX 

    Для регистрации элемента управления ActiveX нужно просто воспользоваться 
какой-либо утилитой или приложением. которое вызывает экспортируемую элементом 
ActiveX функцию DllRegisterServer. Эта функция знает, как внести в реестр 
Windows записи об элементах ActiveX, данные о фабриках объектов которых 
зарегистрированы в глобальном объекте сервера СОМ среды программирования 
Delphi. Нами рассмотрена только одна фабрика объектов 
(TActiveXControlFactory), но для каждой страницы свойств существует своя 
фабрика объектов. 
    Чтобы зарегистрировать"элемент управления ActiveX^ воспользуйтесь командой 
Run^Register ActiveX Server. Чтобы проверить созданный элемент ActiveX в 
действии, установите его в среде Delphi. Для этого выберите команду 
Component'=>lnstall ActiveX control, и на экране появится диалоговое окно 
Import ActiveX Control (рис. 21.10). 
    Если в списке зарегистрированных элементов управления нет библиотеки 
PieXControlLib, то следует щелкнуть на кнопке New и добавить в список файл 
PieXControl.dll. После щелчка на кнопке OK Delphi автоматически вызовет 
функцию DllRegisterServer, и элемент управления появится в списке 
зарегистрированных элементов управления. Выберите созданный элемент в списке и 
щелкните на кнопке Add to package. Здесь есть две возможности: создать новый 
модуль-оболоч^ для элемента ActiveX и вставить созданный элемент в уже 
существующий модуль. Я бы посоветовал вставить созданный элемент в модуль 
PieLib.dpk, после чего нужно только перекомпилировать модуль, так как он уже установлен. 

    Рис. 21.10. Диалоговое окно Import ActiveX Control 


    510 Часть V. Работа с OLE 

    После выполнения описанных выше действий на вкладке ActiveX в палитре 
компонентов Delphi появится элемент управления PieX. Вот и все о создании, 
регистрации и установке элементов управления ActiveX в среде программирования 
Delphi 3. В др^гих.средах программирования. регистрация_и установка элементов 
ActiveX реализованы иначе, поэтому обратитесь к руководству по продукту для 
получения подробных инструкций. 

    Создание форм ActiveForm 

    Форма ActiveForm— это набор визуальных или невизуальных компонентов для 
создания смешанного элемента управления ActiveX. Другими словами, визуальные 
элементы управления ActiveX можно совмещать для создания простого 
комбинированного элемента ActiveX. Кроме того, можно создавать целые 
приложения, обладающие одной формой, которые будут распространяться как формы ActiveForm. 
    Использование невизуальных элементов означает, что в формах ActiveForm 
можно использовать объекты BDE для доступа к базам данных, или, что еще лучше, 
для доступа к данным можно использовать технологию брокеров данных 
производства Borland (Data Broker), которая разрабатывалась специально для 
доступа к распределенным множествам данных в рамках сети, такой как Internet. 
    Что касается выполняемых в формах ActiveForm действий, то тут нет каких-то 
особых ограничений. Единственным отличием от стандартных_фюрм Delphi является 
то, что клиентам предоставляются только те свойства, методы и события, 
"которые^вязаньГ непосредственно с формой ActiveX. Это означает, что все 
свойства, методы и события компонентов VCL, используемых в форме, не будут 
предоставляться клиентам; Названные элементы являются внутренними по 
отношениюк форме ActiveForm. 
    Если необходимо "предоставить клиентам доступ к внутренним свойствам 
компонентов VCL, то следует добавить в форму ActiveForm новые свойства и 
методы, как в процессе создания элемента управления ActiveX. За исключением 
таких случаев, методы свойства Get и Set будут получать и устанавливать 
значения внутренних компонентов, а не основного элемента управления VCL. 
    Процесс создания формы ActiveForm в основном совпадает с процессом 
создания элемента управления ActiveX, но для ясности ниже перечислены основные 
его этапы. 
    1. Мастера ActiveForm можно запустить с помощью команды File'=i>New и 
двойного щелчка на пиктограмме Ас11\/ёРс?ПтГ;"расположенной во вкладке 
ActiveX. Форма ActiveForm всегда "облачается" в компонент TActiveForm, 
следовательно, от пользователя требуется только указать имя создаваемого 
элеме"нта'АсПуеХ, имя модуля реализации, имя проекта, включить или отключить 
лицензирование и т.п. После щелчка на кнопке OK Delphi создаст библиотеку 
типов, в которую войдут все общедоступные и опубликованные свойства, методы и 
события класса TActiveForm. Кроме того, Delphi создаст два файла исходного 
кода. Один — с информацией из библиотеки типов (интерфейсы, диспинтерфейсы и 
т.д.), второй —для реализации методов интерфейса, объявленных в первом файле. 
    2. Вставьте в форму ActiveForm один или несколько визуальных или 
невизуальных компонентов. 
    3. После этого добавьте в форму одно или несколько свойств, методов или 
событий. Для этого откройте редактор библиотек типов (View^Type Library) и 
внесите необходимые изменения. Затем щелкните на кнопке Refresh, расположенной 
на панели инструментов редактора библиотек типов. Это позволит Delphi создать 
код оболочки для добавленных в библиотеку типов элементов. 
    4. Создайте код для всех методов Get и Set, функциональность которых не 
реализована полностью или которые оставлены пустыми для дополнений библиотеки 
типов. Это относится и к обработчикам событий. 
    5. После реализации функциональности 4юрмы ActiveForm разработчик, 
возможно, пожелает создать одну или несколько страниц свойств, чтобы позволить 
пользователям формы ActiveDForm изменять значения ее свойств в средах 
программирования, которые не обладают инспекторами свойств. По крайней" мерё7 
должна быть реализована основная ^страйица^свойств. Delphi предоставляет 
.разработчикам четыре стандартные страницы свойств для управления цветами, 
шрифтами, изображениями и списками строк Delphi. 
    6. Откомпилируйте и зарегистрируйте созданный элемент управления. 
    7. Теперь созданный файл ОСХ можно импортировать в любую среду 
программирования, которая поддерживает элемент управления ActiveX. 
    Поскольку создание формы ActiveForm во многом совпадает с созданием 
элемента управления ActiveX, здесь не приводится полное описание этого 
процесса. Тем не менее на дополнительно распространяемой дискете содержится 
проект формы ActiveForm, в которой помещены компоненты TDBChart, TTable и 
ПРИНЯЯ TCheckBox. Компонент TDBChart связан с таблицей Country, в которой 
хранятся данные о разных странах мира. Флажок TCheckBox используется для 
включения и отключения надписи на диаграмме. 

    Глава 21. Создание элементов управления ActiveX                           511 

    Этот проект является простейшим примером использования формы ActiveForm в 
качестве приложения с единственной формой. Проект ActiveFormXControl находится 
в каталоге \UDELPHI3\CHP21\ACTIVECHARTFORM на дополнительно распространяемой 
дискете. Загрузите проект в Delphi, откомпилируйте его и зарегистрируйте с 
помощью команды Run^Register ActiveX Server. 

    Распространение элементов управления ActiveX и форм ActiveForm в Web 

    Созданный элемент управления ActiveX или 4'орму ActiveForm можно 
использовать на сервере Web. Для этого нужно настроить параметры компилятора, 
влияющие на распространение в Web, и откомпилировать проект. Ниже приведены 
основные этапы этого процесса. 
    1. Выберите команду Project^Web Deployment Options. 
    2. В поле Target Dir укажите каталог на сервере Web, в который нужно 
установить элемент управления ActiveX или форму ActiveForm (файл с расширением 
ОСХ). Здесь можно использовать стандартный путь или путь UNC, например 
\\SERVERMACHINE\OCX_FILES\ или S: \OCX_FILES\. 
    3. В поле Target URL укажите адрес, по которому должен обратиться броузер 
клиента, чтобы получить доступ к элементу управления ActiveX или форме 
ActiveForm. Здесь нужно использовать корректный адрес URL, который указывает 
на сервер Web, например http: //ServerMachine/. В проект не следует включать 
имя самого файла ОСХ. 
    4. В поле HTML Dir нужно указать каталог, в котором Delphi создаст 
тестовый HTML-документ со ссылкой на создаваемый элемент ActiveX. Здесь можно 
использовать стандартный путь или путь универсального сетевого соединения UNC. 
Обычно в этом поле указывают тот же путь, что и в поле Target Dir, если только 
файлы ОСХ не хранятся отдельно от HTML-документов, которые используют эти 
элементы. Если вы не подключены к Web-серверу, можете создать тестовый каталог 
на собственном компьютере и использовать адрес URL, подобный file:///c:\TestRoot\. 
    5. Щелкните на кнопке ОК. 
    6. Выполните команду Project"^ Build All. Это создаст библиотеку ActiveX 
(файл с расширением ОСХ), которая содержит элемент управления ActiveX или 
форму ActiveForm. 
    7. Выполните команду Project^Web Deploy. Созданная библиотека ActiveX 
будет скопирована в каталог Target Dir, который указан в п. 2. В каталоге HTML 
Dir, указанном в п. 4, будет создан HTML-документ, имя которого совпадает с 
именем проекта библиотеки ActiveX. Расширение HTML-документа— НТМ. Этот файл 
содержит ссылку на элемент ОСХ, путь к которому указан в п. 3. 
    8. Вызовите броузер Web для просмотра тестового HTML-документа. 
    Когда тестовая страница просматривается в броузере, форма ActiveForm 
появляется на экране и выполняется в броузере как встроенное приложение. 
    Ниже будут рассмотрены другие аспекты распространения. 

    Использование модулей выполнения 

    Наиболее важный момент в этом процессе — распространение модулей 
выполнения (runtime packages). Если элемент управления ActiveX или форма 
ActiveForm использует модули, то следует включить опцию Deploy Required Packages. 

    Использование сжатия CAB 

    Пользователю предоставляется возможность использовать опцию Use CAB file 
compression, которая позволяет сжать элемент управления ActiveX или форму 
ActiveForm и любые дополнительные файлы, такие как файлы DPL или файлы 
лицензий. Эта возможность поддерживается только при использовании броузера 
Internet Explorer 3.01. На сегодняшний день броузер Netscape Navigator не 
поддерживает САВ-файлы. По умолчанию библиотека ActiveX, модули (если такие 
есть) и дополнительные файлы упаковываются в три САВ-файла. Возможна также 
упаковка всех файлов в один САВ-файл, но делать это не рекомендуется. Разделяя 
файлы по различным архивам CAB, вы можете избежать загрузки излишних файлов, 
которые уже установлены на компьютере пользователя. 

    512                                           Часть V. Работа с OLE 


    Использование подписей кода 

    Если вы хотите подписать проект элемента управления ActiveX или формы 
ActiveForm, то сначала включите опцию Code sign project, а после этого во 
вкладке Code Signing диалогового окна Web Deployment Options введите следующий текст. 

    Have obtained a Software Publishing Certification file (.SPC) Private Key (.PVK) 

    Что такое подпись кода? Это технология, встроенная в Microsoft Internet 
Explorer, известная как Authenticode. Она позволяет приложению Internet 
Explorer вместо стандартного предупреждения об использовании неизвестного 
приложения отображать сообщение о сертификате подлинности программного 
обеспечения в момент загрузки выполняемого кода, например программ установки 
через Internet, элементов управления ActiveX или форм ActiveForm. Подпись кода 
— это цифровой идентификатор (Digital ID) в компании VeriSign 
(www.verisign.com) с целью "получения сертификата на публикацию программного 
обеспечения Software Publishing Certificate и частного ключа Private Key, 
используемого для подписи всех распространяемых компанией выполняемых файлов. 
С помощью подписи кода разработчик может обеспечить пользователей информацией 
и страховкой при загрузке программного обеспечения из Internet. 
    Никаких требований, заставляющих разработчиков подписывать выполняемый 
код, не существует, но эта процедура предоставляет способ повышения надежности 
загрузки программного обеспечения из Internet. Более подробную информацию о 
получении цифрового идентификатора VeriSign Software Publisher Digital можно 
получить на Web-узле компании VeriSign по адресу http://www.verisign.com. 

    Внимание! Пожалуйста, запомните, что регистрация программного обеспечения 
производится для выбранного компьютера. Это значит, что регистрироваться для 
получения идентификатора Digital ID, получать идентификатор Digital ID и 
использовать этот идентификатор нужно на одном компьютере и в одной версии 
Internet Explorer. Если службу Authenticode планируется использовать более чем 
на одном компьютере, то нужно получить более чем один идентификатор Digital 
ID. Если установлена новая версия Internet Explorer, то нужно выполнить 
повторную регистрацию. 


    Резюме 

    В этой главе рассказывается, насколько в Delphi 3 облегчен процесс 
создания элементов управления ActiveX из существующих компонентов VCL 
(потомков класса TWinControl) и как создать элемент управления ActiveX из 
потомка класса TGraphicControl. 
    В первом примере (элемент управления PieX) был рассмотрен способ создания 
страниц свойств, особенно полезных для редактирования значений свойств, 
которые не предоставляются пользователям или принадлежат сложным типам данных. 
    Кроме того, здесь шла речь о создании форм ActiveForm, предоставляющих 
разработчику способ группирования визуальных и невизуальных компонентов в 
форме для создания комбинированных элементов управления ActiveX. И наконец, в 
этой главе рассматривался способ встраивания элементов управления ActiveX в 
документы Web (на данный момент эту возможность поддерживает только броузер 
Internet Explorer). 
    Усвоив материал этой главы, читатель придет к выводу, что область 
применения элементов практически не ограничена и Delphi 3 значительно 
облегчает разработку объектов ActiveX. Кроме того, в процессе разработки 
объектов ActiveX можно использовать любую из технологий программирования, 
представленных в Delphi. 

    Глава 21. Создание элементов управления ActiveX                           513 
    17 Использование Delphi 3. Специальное издание 
