ЧАСТЬ IV

Разработка компонентов

15.                      Работа с пакетами
16.                     Создание компонентов
17.                    Сложные компоненты


345


    Работа с пакетами 

    ЭрикАбер 

    Если вы не первый день работаете с компьютером и вам доводилось писать 
программы, работающие под управлением MS DOS (помните старую добрую 
операционную систему MS DOS?), вы знаете, что. хотя DOS и предоставляет 
некоторые базовые функции (например, доступ к дискам, установка режимов 
отображения и т.п.), программисту приходится самому заботиться о многих 
дополнительных средствах, обеспечивающих работоспособность приложения. Если, к 
примеру, вы хотите, чтобы ваше приложение содержало контекстные меню, придется 
либо самостоятельно написать соответствующий программный код, либо 
позаимствовать его у другого программиста. В любом случае этот код становится 
частью приложения. И если позднее, при разработке нового приложения вы 
захотите использовать тот же интерфейс пользователя, такой же код снова нужно 
будет включить в новую программу. В связи с этим напрашивается следующее 
пожелание: как бы было хорошо, если бы некоторый код могло использовать сразу 
несколько приложений! По крайней мере, это уменьшило бы объем дискового 
пространства, за нимаемый вашим программным обеспечением. 
    Допустим, вам удалось обеспечить совместное использование такого кода 
среди своих приложений, но как быть с другими программами? Скорее всего, 
интерфейс, связанный с работой меню в вашем приложении, будет несколько 
отличаться от интерфейса в моем приложении, причем эти незначительные отличия 
только вызовут раздражение у пользователя, который будет работать с обеими программами. 
    В среде Windows обе эти проблемы решаются довольно легко. Во-первых, 
большинство функций меню и других средств интерфейса пользователя, а также 
операции, связанные с конкретной системой, встроены в саму систему, поэтому 
вам не придется снова и снова включать один и тот же программный код в свои 
приложения. Во-вторых, поскольку в системе существует только одна копия 
базового кода интерфейса пользователя, все приложения, использующие этот код, 
могут предоставить пользователю общепринятый стандартизованный интерфейс. 
(Конечно же, многие приложения не соблюдают эти правила •— ведь Windows не 
принуждает разработчика использовать ее стандартный интерфейс пользователя.) 

    ГЛАВА 15 

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

    Что собой представляют пакеты и подходят ли они для вашего приложения. 

    Установка пакетов 

    Установка пакетов компонентов и других пакетов с целью расширения и 
настройки как среды Delphi, так и создаваемых вами приложений. 

    Создание пакетов 

    Создание пакетов для использования в приложениях или для распространения 
среди других разработчиков. 

346

    В целях предоставления общих функций для многих приложений Windows 
использует библиотеки динамической компоновки (Dynamic Link Libraries, или 
DLL). Эти файлы представляют собой программные модули, которые могут совместно 
использоваться различными приложениями, запускаемыми в одно и то же время. 
Помимо использования библиотек DLL в качестве контейнеров-для базовых функций 
операционной системы Windows, разработчики приложений имеют возможность 
создавать специализированные библиотеки DLL, к которым обращаются их 
собственные приложения. 
    Подобно другим средам разработки приложений, ранние версии Delphi также 
предоставляли разработчикам возможность написания своих собственных библиотек 
DLL. Однако на них накладывались весьма существенные ограничения, самое 
"болезненное" из которых состояло в том, что разрабатываемые компоненты VCL не 
были доступны за пределами модулей. Другими словами, программный код главного 
модуля приложения не мог безопасно получить доступ к полям и методам 
компонента, реализованного в DLL, и наоборот. Другой важный недостаток 
заключался в том, что основной код VCL, добавляющий 100—200 Кбайт к приложению 
Delphi, должен был входить в состав DLL, так же как и основной модуль 
приложения, что сводило на_нет все_сокращения объема, достигаемые за счет 
размещения некоторого кода в совместно используемой библиотеке (DLL). 
    В Delphi 3 эти ограничения полностью устранены благодаря введению понятия^ 
лаке/я. Пакет представляет собой библиотеку DLL, содержащую такие объекты, как 
компоненты VCL, а также дополнительную информацию, которая позволяет совместно 
использовать код несколькими приложениями Delphi. Из этой главы вы узнаете, 
как применять в своих приложениях стандартные пакеты, предоставляемые Delphi 3 
и независимыми производителями компонентов, а также как создавать и 
использовать свои собственные пакеты. 

    Стоит ли использовать пакеты 

    Вы спросите: стоит ли вам использовать пакеты? Пакеты обладают рядом 
преимуществ, однако не лишены и некоторых недостатков. Причем не существует 
жестких и точных правил их применения на все случаи жизни, поэтому вы долж-"ны 
в каждой конкретной ситуации оценивать влияние пакетов на работу своих 
приложений. Использование 'пакетов напоминает использование традиционных 
библиотек DLL, поэтому многие аспекты применения последних подойдут и в Случае 
использования пакетов. 

    Устранение избыточности кода 

    Главное назначение пакетов состоит в уменьшении размера приложений за счет 
удаления избыточности кода. Если приложение довольно велико и состоит из 
определенного числа самостоятельных или не совсем самостоятельных модулей, 
возможно, имеет смысл представить эти модули в виде отдельных ЕХЕ-файлов или 
библиотек DLL. После компиляции модулей для использования в качестве пакетов 
распространяться будет только одна копия базовой структуры VCL (содержащаяся в 
пакете VCL30). 
    Отдельные модули станут, конечно, меньше в объеме, поскольку общий код не 
будет дублироваться, что, естественно, облегчит распространение приложений. 
Кроме того, когда наступит время модернизации одного из модулей, объем нового 
кода, передаваемого вашим пользователям, также уменьшится, что, 
соответственно, снизит стоимость поставки. 
    Если вы распространяете свои приложения по Internet или World Wide Web, 
использование пакетов может существенно сократить время, затрачиваемое 
пользователями на получение ваших приложений. Им придется скопировать данный 
пакет только один раз, и после его инсталляции он подойдет для всех приложений 
Delphi 3 (включая приложения, получаемые от других производителей). 
    Наилучший результат даст сочетание традиционного и электронного способов 
поставки программной продукции: сначала пользователи получают ваше приложение 
со всеми необходимыми пакетами на компакт-диске или дискете. А затем, чтобы 
усовершенствовать свои приложения до уровня самых последних версий, они 
"выкачивают" новые модули по сети. Использование пакетов позволяет сделать эти 
модули меньше, чем они были бы в любом другом случае. 
    Тем не менее разбиение приложения на модули и пакеты имеет свои 
недостатки. Вам придется особое внимание уделить совместной работе различных 
версий модулей и пакетов. Лучше всего это достигается благодаря гарантии 
совместимости в обратном направлении всех версий ваших пакетов (т.е. код в 
более новой версии пакета должен поддерживать вызов приложения, которому 
"известна" только более ранняя версия). Этот аспект использования пакетов 
более подробно рассматривается в разделе "Регистрация версий пакетов", далее в 
этой главе. 
    Кроме того, необходимо позаботиться о том, чтобы в процессе деинсталляции 
вашего приложения программа деинсталляции случайно не удалила пакеты, которые 
нужны для других приложений. (Такие программы инсталляции, как поставляемая с 
Delphi утилита InstallShield Express, должны автоматически справляться с 
подобными тонкостями, но вам следует обратить внимание на возможность 
возникновения потенциальных проблем такого рода.) 

    Глава 15. Работа с пакетами 347 


    Компоненты VCL 

    В Delphi 3 компоненты, которые будут инсталлированы в палитре компонентов, 
должны быть оформлены^ виде пакета. Следовательно, если вы планируете 
создавать и распространять компоненты, вам необходимо знать, как происходит 
построение пакетов. Полностью процесс создания компонентов и помещения их в 
пакеты рассмотрен в главе 16, "Создание компонентов" , но с общими понятиями, 
которые вам необходимо знать на данном этапе, вы познакомитесь уже здесь. 

    Когда не следует использовать пакеты 

    Если вы учитываете размеры пакетных файлов, имейте в виду, что приложение, 
использующее пакеты, всегда будет больше приложения, которое представлено в 
виде простого ЕХЕ-файла. Следовательно, вряд ли имеет смысл использовать 
пакеты, если они не будут совместно использоваться несколькими приложениями 
или если вы не уверены, что у ваших конечных поль зователей есть установленные 
в системе пакеты. 
    Рассмотрим, например, простое приложение Delphi. Размер непакетной версии 
ЕХЕ-файла составил бы около 200 Кбайт, в то время как версия с пакетами заняла 
бы только 30 Кбайт. Экономия 170 Кбайт выглядит довольно неплохо, пока вы 
помните, что все выполняемые ЕХЕ-файлы Delphi, работающие с пакетами, требуют 
наличия пакета VCL30, который занимает более 1 Мбайт. Простой анализ 
показывает, что использование пакетов не оправдывает себя в смысле общей 
экономии дискового пространства до тех пор, пока не задействовано по крайней 
мере шесть модулей (ЕХЕ или DLL), которые использовали бы VCL30. Точное число 
будет~зависеть от самих приложений и от конкретного выбора требуемых пакетов, 
но принцип довольно прост: не используйте пакеты для приложений только потому, 
что они существуют, а рассмотрите ситуацию с точки зрения конечного пользователя. 

    Установка и использование пакетов 

    Если у вас нет склонности к затворничеству и вы занимаетесь разработкой 
Delphi не в пещере, то вам, возможно, понадобятся пакеты, написанные другими 
программистами. Но, прежде чем воспользоваться ими, вы должны инсталлировать 
их в своей системе. 
    Существует две основные категории пакетов: времени выполнения (runtime) и 
времени разработки (design-time). Пакеты времени выполнения используются самим 
приложением Delphi: они содержат программный код, который реализует 
определенную часть функций приложения. Если вы распространяете приложение, 
которое использует пакеты времени выполнения, вы долж ны включить в поставку и 
копии этих пакетов (если, конечно, не уверены, что они уже установлены на 
машинах конечных пользователей). 
    В противоположность пакетам времени выполнения, пакеты времени разработки 
содержат код, который используется только в период разработки приложения, и он 
используется средой Delphi. Как разработчик Delphi, вы будете использовать 
пакеты времени разработки для построения приложений, но они никогда не станут 
составной частью конечного приложения. (С д ругой стороны, если ваш конечный 
продукт является компонентом Delphi, вам придется инкапсулировать его в пакет 
времени разработки, чтобы ваши пользователи—другие разработчики Delphi — могли 
его установить у себя.) 

    Установка пакетов времени выполнения 

    Если вы получите пакет времени выполнения в виде части компонента 
библиотеки VCL, этот пакет будет инсталлирован автоматически при установке 
самого компонента. ЙднакЪ не исключено, что вам придется собственноручно 
выполнить инсталляцию пакета времени выполнения, что происходит в случае, 
когда пакет состоит из набора функций, а не из компонентов. 
    Установка пакета времени выполнения — это простой двухступенчатый процесс. 
Сначала вы копируете пакетную библиотеку DLL в каталог, в котором загрузчик 
Windows сможет найти ее в процессе выполнения приложения, а затем 
модифицируете параметры своего проекта Delphi, чтобы известить компилятор о 
наличии этого пакета. Только и всего. 
    Пакеты представляют собой неявно связанные библиотеки DLL (загрузчик 
Windows находит и загружает любые пакеты, требуемые приложением, до загрузки 
самого приложения). Поскольку пакеты загружаются до приложения, которое их 
использует, вы не сможете включить в само приложение никаких данных о маршруте 
для поиска пакетов. Вместо этого вам остается пол ожиться на способность 
Windows находить эти самые пакеты. 
    Подробная информация о том, где размещать пакетные библиотеки DLL, 
представлена в разделе "Распространение пакетов", в конце этой главы. Она вам 
пригодится после того, как вы примете решение, как передавать свои приложения 
пользователям. Но что касается компьютера, на котором выполняется разработка, 
вам, скорее всего, захочется поместить пакеты вр емени выполнения в системный 
каталог Windows (обычно это \WINDOWS\SYSTEM или \WINDOWS\SYSTEM32) вместе со 
стандартными пакетами времени выполнения VCL. Помните, что если вы 
воспользуетесь другим каталогом, то вам, возможно, придется внести имя этого 
каталога в строку оператора PATH, чтобы загрузчик Windows мог найти 
соответствующие пакеты. 

    348  Часть IV. Разработка компонентов 

    He исключено, что вы, подобно мне, не любите сваливать файлы в системный 
каталог Windows. Но я, рас-Совет I   смотРев возможные альтернативы, пришел к 
выводу, что для компьютера разработчика это самое лучшее решение. 
    Для того чтобы сделать пакеты времени выполнения доступными для 
использования в своих проектах, вам необходимо оповестить IDE об их 
существовании. В главном меню IDE выберите команду Component^lnstall Packages. 
При этом вы попадете на вкладку Packages диалогового окна Project Options, 
показанного на рис. 15.1. (Обратите внимание на то, что вы можете открыть это 
же диалоговое окно с помощью команды Project^Options, щелкнув на вкладке Packages.) 
    Если вы откроете диалоговое окно Project Options в тот момент, когда в IDE 
не открыт ни один проект, любые сделанные вами изменения будут действовать по 
умолчанию, т.е. они будут применяться ко .всем новым проектам. С другой 
стороны, если вы внесете изменения в окне Project Options при любом открытом 
проекте в IDE, эти изменения коснутся только данного проекта, если, конечно, 
вы не включите опцию Default в нижнем левом углу этого диалогового окна. 
    Для того чтобы добавить пакет времени выполнения в список доступных 
пакетов, щелкните на кнопке Add в группе Runtime packages (а не на одноименной 
кнопке в группе Design packages). В результате откроется диалоговое окно Add 
Runtime Package, показанное на рис. 15.2. Затем вы можете либо ввести имя 
добавляемого пакета, либо использовать кнопку Browse для поиска нужного пакета. 

    I Совет 1 

    Рис.' 15.1. Используйте диалоговое окно Project Options, чтобы сделать 
пакеты времени выполнения доступными для использования в проектах 

    Рис. 15.2. Используйте диалоговое окно Add Runtime Package для установки 
пакета времени выполнения 

    Щелчок на кнопке Browse в диалоговом окне Add Runtime Package приведет к 
открытию стандартного диалогового окна Open File, которое можно использовать 
для перехода по каталогам для поиска файла пакета. После того как вы найдете 
нужный пакет и выберете его, щелкните на кнопке ОК, чтобы скопировать имя 
файла в поле Package Name диалогового окна Add Runtime Package, а затем снова 
щелкните на кнопке ОК для внесения пакета в список доступных пакетов времени 
выполнения в диалоговом окне Project Options. На данном этапе вы можете добавить 
еще несколько пакетов илйТлёлкнуть на кнопке ОК, чтобы закрыть диалоговое окно 
Project Options и принять сделанные изменения. 
    После выполнения описанных выше действий новоиспеченные пакеты времени 
выполнения станут доступными для использования в приложениях. Причем заметьте, 
что добавление пакетов в список доступных пакетов времени выполнения никогда 
не принесет вреда; даже если ваше приложение не использует ни одного из 
модулей, содержащихся в данном пакете, в конечном 
    ЕХЁ-файле не будет ни одной ссылки на пакет. 

    Установка компонентов и пакетов времени разработки 

    Пакеты времени разработки (как можно предположить из их названия) содержат 
код, который выполняется средой IDE во время разработки приложения. Обычно 
этим занимаются редакторы компонентов и свойств, эксперты и т.п. Вы никогда не 
будете связывать код из пакетов времени разработки с вашим приложением. 

    Глава 15. Работа с пакетами 349 

    J3 поставку компонента^УОг^независимого производителя Ьбычно входит два 
пакета — пакет времени выполнения, который реализует поведение компонента в 
процессе работы программы (причем некоторые из них могут применяться и во 
время разработки), и пакет времени разработки, который реализует поведение 
только во время разработки, как, например, редактор свойств. (Простой 
компонент, который не требует никаких редакторов компонентов или свойств, 
может содержать функции времени выполнения и времени разработки в одном 
пакете.) С другой стороны, мастер каких-либо функций обычно состоит только из 
кода времени разработки, поэтому здесь не будет соответствующего пакета 
времени выполнения. 
    Установка пакетов времени разработки аналогична инсталляции пакетов 
времени выполнения. Сначала вам придется скопировать библиотеки пакета DLL в 
каталог вашего жесткого диска (заметьте, что файлы пакетов используют 
расширение DPL, а не DLL, как обычные библиотеки DLL). В данном случае имеет 
смысл скопировать пакетные библиотеки DLL в каталог Delph i 3 . 0\BIN ввиду 
специфичности DLL для IDE Delphi. Затем перейдите в главное меню в IDE Delphi 
и выберите команду Component^lnstall Packages. При этом вы попадете во вкладку 
Packages диалогового окна Project Options (см. рис. 15.1). 
    Щелкните на кнопке Add в группе Design packages. При этом откроется 
диалоговое окно Add Design Package, которое является просто стандартным 
диалоговым окном открытия файла (рис. 15.3). Просмотрите каталоги, чтобы найти 
пакет, который вы хотите добавить, выберите файл и щелкните на кнопке ОК. В 
результате выбранный пакет добавится в список доступных пакетов времени разработки. 
    Как и в случае с пакетами времени выполнения, вы можете подключать пакеты 
времени разработки к текущему проекту. Все изменения, сделанные в списке 
пакетов времени разработки, повлияют только на текущий проект, если не 
установлена опция Default в нижнем левом углу этого диалогового окна. 
    После инсталляции пакета времени разработки можете выделить имя пакета в 
списке диалогового окна Project Options, а затем щелкнуть на кнопке 
Components, чтобы увидеть список компонентов, содержащихся внутри пакета. 
    Обратите внимание на то, что слева от каждого имени пакета, перечисленного 
в списке Design packages, находится флажок. Эти флажки предоставляют удобные 
средства для быстрого включения и исключения различных пакетов для каждого из 
ваших проектов. Если в текущем проекте, например, не предусмотрена работа с 
Internet, можно запретить пакеты Delphi Internet Components и Delphi Internet 
Solutions Pack Components и_тем самьш уменьшить "населешю^те^талитрь! 
компонентов. Если же вы хотите полностью удалить какой-нибудь пакет, 
воспользуйтесь кнопкой Remove. В этом случае выбранный пакет будет удален из 
списка доступных пакетов, а если позже вы захотите его восстановить, 
пригодится кнопка Add. 
    При исключении пакетов времени разработки вы, возможно, увидите диалоговое 
окно, подобное тому, которое показано на рис. 15.4. Как правило, на заданный в 
нем вопрос об удалении ссылки на пакет времени выполнения можно безопасно 
отвечать щелчком на кнопке Yes. Но если по какой-то причине вы посчитаете 
нужным исключить пакет компонента времени разработки, но все еще используете 
соответствующий пакет времени выполнения, щелкните на кнопке No. Единственной 
причиной отрицательного ответа может послужить стремление избежать применения 
компонента в процессе разработки (я могу расценить это как некоторое 
преувеличение), но по-прежнему иметь возможность создания экземпляра этого 
компонента во время работы приложения. 

    Г Совет 1 

    Рис. 15.3. Используйте диалоговое окно Add Design Package для выбора 
устанавливаемого пакета времени разработки 

    Рис. 15.4. При исключении пакета времени разработки вы можете получить 
вопрос об удалении ссылки на пакет времени выполнения 

    Возможность выборочного исключения пакетов компонентов является одной из 
новых замечательных возможностей Delphi 3.0. В предыдущих версиях Delphi, если 
бы вам понадобилось для различных проектов формировать различные наборы 
компонентов, пришлось бы перед загрузкой этих проектов вручную загружать 
различные библиотеки компонен

    350        асть IV. Разработка компонентов 

тов (Component Libraries). Теперь же достаточно модифицировать параметры 
проекта. Если вам приходилось работать в Delphi 2.0, вы знаете, сколько 
времени отнимает переконфигурация палитры компонентов, а в Delphi 3.0 это 
происходит практически мгновенно. 

    Использование пакетов в приложениях и библиотеках DLL 
    
    По умолчанию проектам Delphi 3 не разрешено работать с яреекд-ами, 
поэт-ому, чтобы приложения могли использовать пакеты, необходимо 
модифицировать параметры проектов. 
    С помощью диалогового окна Project Options можно глобально управлять 
использованием параметров (см. рис. 15.1). Установив флажок Build with runtime 
packages, вы включите все доступные пакеты в текущий проект. Если при этом 
окажется, что какой-нибудь используемый в проекте модуль содержится в одном из 
пакетов, конечный ЕХЕ-файл или библиотека DLL с компилируется таким образом, 
что в процессе выполнения б,удет выполняться обращение к коду в пакете, и 
компилятор не включит этот код в выполняемый файл. При сбросе флажка Build 
with runtime packages никакие пакеты не будут принимать участия в построении проекта. 
    Можно также выборочно запрещать использование отдельных пакетов путем их 
удаления из списка пакетов времени выполнения. Например, в диалоговом окне 
Project Options, показанном на рис. 15.5, представлен список пакетов времени 
выполнения, состоящий из пакетов VCL30, VCLX30 и VCLDB30. Это значит, что при 
работе приложения из пакетов будут вызываться только те модули, которые входят 
в состав перечисленных пакетов. Все остальные модули в проекте компилируются 
непосредственно в ЕХЕ-файл или библиотеку DLL. 

    Рис. 15.5. Используйте поле ввода имен пакетов времени выполнения в 
диалоговом окне Project Options для управления пакетами, применяемыми модулями проекта 

    Использование пакетов в библиотеках DLL практически не отличается от их 
использования в ЕХЕ-файлах. Однако здесь существует один дополнительный 
аспект. Если библиотека DLL предназначена для использования только 
приложениями Delphi, то; возможно, имеет смысл оформить ее в виде пакета. В 
этом случае приложение получает прямой доступ к любым классам и функциям, 
определенным в этом пакете. Вам остается только добавить имена модулей, 
входящих в пакет, в раздел uses приложения, и вы сможете использовать этот 
пакет, как если бы он был непосредственно скомпоно-" ван с вашим проектом. 
    Но если вы создаете библиотеку DLL, которая буд?г^спо^ыомть^?^щилйжениями, 
написанными на других языках, е,е~щ:льзя будет включить в пакет, так как 
другие системы не понимают формата пакетов. 
    Использование пакетов в приложениях и библиотеках DLL может существенно 
сократить размер конечных ЕХЕ- и DLL- файлов. А поскольку сами пакетные 
библиотеки DLL обычно не нуждаются в обновлении, это может существенно 
упростить процесс распространения обновлений и тем самым сократить накладные расходы. 

    Глава 15. Работа с пакетами 351 

    Г Совет 1 

    Создание пользовательских пакетов 

    В поставку Delphi 3 входят все средства, необходимые для создания пакетов 
времени выполнения и времени разработки. IDE Delphi включает редактор пакетов, 
который делает этот процесс даже приятным. Как и в других делах, в 
планировании нужно исходить из здравого смысла. Перед упаковыванием необходимо 
строить и тестировать все модули, которые будут размещаться в пакете, как 
обычные модули. Ведь после того как они окажутся в пакете, вы не сможете их 
модифицировать никаким другим путем, кроме как перестроить пакет, что отнимает 
больше времени и усилий, чем модификация обычного модуля. 
    Когда отдельный модуль включается в пакет, о пакете говорят, что он 
содержит этот модуль. Если пакет опирается на другой пакет, о нем говорят, что 
ему требуется этот другой пакет. Понятия содержит и требуется аналогичны 
понятию использует в обычном проекте Delphi, но здесь присутствуют некоторые различия. 
    Если модуль перечислен в разделе uses проекта Delphi, весь код, 
определенный в модуле, доступен для данного проекта. При создании проекта в 
ЕХЕ-файл входит только тот код, который реально используется. Но если модуль 
содержится в пакете, в пакет войдет весь код модуля. 
    Если в проекте Delphi используются пакеты, в ЕХЕ-файле будут содержаться 
ссылки на соответствующие пакетные библиотеки DLL и ЕХЕ-файл не будет 
работать, если эти пакетные библиотеки DLL недоступны во время выполнения. 
Если какой-нибудь пакет в ЕХЕ-файле требует наличия другого пакета, на этот 
другой пакет в ЕХЕ-файле также будет присутствовать ссылка, даже если в коде 
ЕХЕ-файла нет прямого обращения к этому другому пакету. Поэтому, если ваше 
приложение использует пакет А, а пакет А, в свою очередь, использует пакет Б, 
приложение не будет работать до тех пор, пока оба пакета не будут доступны в 
процессе выполнения, независимо от того, использует ли ваш код в явном виде 
какой-нибудь из модулей пакета Б. 
    Обычно весь код, который допустим в обычном модуле, допустим и в пакете. 
Но есть одно исключение: пакеты времени разработки не должны содержать 
процедур выхода. Пакет времени разработки может динамически загружаться и 
выгружаться средой IDE. Когда это происходит, при загрузке пакета вызываются 
все разделы инициализации (initialization) модулей этого пакета, а при его 
выгрузке — все разделы деи-нициализации (finalization), но не процедуры 
выхода. Если у вас есть модуль, содержащий процедур) выхода, то перед 
включением модуля в пакет времени разработки вы должны преобразовать эту 
процедуру в раздел деинициализации. 
    Если вы готовы к построению своего пакета, в главном меню IDE выберите 
команду File^New, и откроется диалоговое окно New items. Выберите пиктограмму 
Package во вкладке New и щелкните на кнопке ОК. Тем самым вы активизируете 
диалоговое окно New Package, показанное на рис. 15.6. Введите для своего 
пакета имя, которое будет использоваться средой IDE для ссылки на пакет. Оно 
также будет использовано в качестве имени для пакетной библиотеки DLL, поэтому 
на него налагаются ограничения имени файла. Для пакетов времени разработки вы 
также должны ввести описание (в поле Description), которое представляет собой 
текст, отображаемый в списке пакетов времени разработки в диалоговом окне 
Project Options среды IDE. Можно также ввести описание и для пакетов времени 
выполнения, но оно не используется средой IDE. 
    Щелкните на кнопке ОК, чтобы закрыть диалоговое окно New Package. При этом 
откроется редактор пакетов (Package Editor), отображенный на рис. 15.7. 
Основная часть этого окна содержит две вкладки со списками: список модулей, 
содержащихся в пакете, и список других пакетов, требуемых данным пакетом. Для 
перехода от одного списка к другому достаточно щелкнуть на соответствующей 
вкладке. Обратите внимание на то, что пакет VCL30, требуемый всеми пакетами, 
присутствует в списке вкладки Requires по умолчанию. 
    В верхней части редактора пакетов находятся кнопки, которые можно 
использовать для модификации содержимого создаваемого пакета. Рассмотрим 
назначение каждой кнопки слева направо. 
    •    Build/Save package (Построение/Сохранение пакета). После щелчка на 
этой кнопке выполнится сохранение и компиляция пакета, а также будет создан 
исходный файл пакета (DPK), скомпилированного файла пакета (DCP) и пакетной 
библиотеки DLL с расширением DPL, которое позволяет отличать ее от обычных 
библиотек DLL. 
    •    Add unit/Add package (Добавление модуля/Добавление пакета). При 
выбранной вкладке Contains используйте эту кнопку для добавления модуля в 
список модулей, содержащихся в этом пакете. Если выбрана вкладка Requires, 
используйте эту кнопку для добавления пакета в список пакетов, требуемых 
данным пакетом. 
    •    Remove unit/Remove package (Удаление модуля/Удаление пакета). 
Действие этой кнопки противоположно действию предыдущей. Чтобы удалить модуль 
или пакет, выделите его имя в списке Contains или Requires, а затем щелкните 
на этой кнопке. 
    •    View unit/View package (Просмотр модуля/Просмотр пакета). После 
выбора любого модуля в списке Contains и щелчка на этой кнопке будет отображен 
исходный код модуля в редакторе кода (предполагается, что IDE может найти 
исходный код). После выбора пакета в списке Requires и щелчка на этой кнопке 
откроется второй редактор пакетов, отображающий содержимое выбранного пакета. 

    352 Часть IV. Разработка компонентов 

    Package options (Параметры пакета). Щелчок на этой кнодке приведет к 
отображению диалогового окна Package Options (рис. 15.8). Во вкладке 
Description можно изменить описание пакета и установить атрибуты пакета. Вы 
можете включить/исключить пакет (на время разработки или выполнения, либо и 
то, и другое) и указать способ перестройки пакета. Если выб ирается параметр 
Rebuild as needed, IDE перестраивает проект, когда сочтет, что он нуждается в 
обновлении (например, при изменении одного из включаемых модулей). Если же 
выбран параметр Explicit rebuild, IDE не будет перестраивать пакет, пока вы не 
щелкнете на кнопке Build/Save package в редакторе пакетов. 

    Рис. 15.6. Используйте диалоговое окно New Package, чтббы дать своему 
пакету имя и описать его 

    Рис. 15.7. Используйте редактор пакетов для создания своего собственного пакета 

    • Install package (Инсталляция пакета). Используйте эту кнопку для 
инсталляции пакета в IDE, если он представляет собой компонент или другой 
пакет времени разработки. 
    И Update from source (Обновление). Используйте эту кнопку для обновления 
кода пакета, если вы выбрали параметр Explicit rebuild. 
    Рис. 15.8. Используйте диалоговое окно Package Options для управления 
способом создания пакета 
    Как видите, процесс создания пакета довольно прост: достаточно выполнить 
следующие действия. 
    1.    В список Contains добавьте модули, которые будут содержаться в пакете. 
    2.    В список Requires добавьте пакеты, требуемые данным пакетом. 
    3.    Если необходимо, модифицируйте параметры пакета. 
    4.    Щелкните на кнопке Build/Save package, чтобы создать пакет. 
    5.    Щелкните на кнопке Install package для инсталляции пакета в IDE (необязательно). 

    Глава 15. Работа с пакетами 
    353 12 Использование Delphi 3. Специальное издание 

пакет, если для него установлен параметр Rebuild as needed. Если IDE в 
состоянии найти соответствующие исходные файлы, она перекомпилирует пакет, 
предоставив вам обновленную пакетную библиотеку DLL. Если же ей не удастся 
найти исходных файлов, она скомпонует код модуля непосредственно в ваш проект, 
неж:пользуя пакет. 
    Ситуация усложнится, если такой модуль используется косвенно (например, 
проект А использует пакет Б, который требует наличия пакета В, содержащего 
модуль Г, который также является частью проекта А). Если не исключена 
возможность того, что одни пакеты могут иметь установленный параметр Rebuild 
as needed, в то время как другие — Explicit rebuild, то будет трудно точно 
предугадать, что случится при модификации этого модуля. Отсюда вытекает, что 
лучше не вносить изменений в "пакетный" модуль в проекте, который использует 
этот модуль. Вместо этого сначала модифицируйте модуль и обновите все свои 
пакеты, а затем выполните загрузку и построение проекта. 
    Если процесс создания пакета прошел успешно, в каталоге пакета будет 
создано три новых файла (помимо DCU-файлов, связанных с модулями в пакете). 
    DPK-файл. Являясь исходным файлом для всего пакета, он аналогичен 
DPR-файлу в обычном проекте Delphi. Несмотря на то что он представляет собой 
обыкновенный текстовый, файл, который можно редактировать в редакторе кода 
Delphi, делайте это осторожно. Обратитесь к документации по Delphi за 
подробной информацией о формате этого файла. В этом не будет необходимости, 
если вы не планируете компилировать свои пакеты с помощью компилятора 
командной строки. 
    DCP-файл. Это скомпилированный файл пакета. Он включает в себя всю 
символьную информацию из DCU-файлов, входящих в пакет, плюс дополнительные 
данные, требуемые IDE. Среда IDE должна иметь доступ к этому файлу для 
построения проектов, которые используют соответствующий пакет. 
    DPL-файл. Это пакетная библиотека DLL, которую вы распространяете вместе с 
приложениями, использующими этот пакет. 
    Завершив создание пакета, вы можете загрузить его в IDE для 
редактирования, выбрав из главного меню команду File^Open. В списке Files of 
type диалогового окна Open выберите элемент Delphi package source (*.DPK), 
чтобы отобразить все пакеты Delphi в текущем каталоге. 
    После выбора файла пакета и щелчка на кнопке ОК откроется редактор 
пакетов. Для редактирования пакета используйте методы, рассмотренные выше. 

    Синтаксис пакета 

    Существует несколько новых команд компилятора, связанных с пакетом, 
которые можно использовать для управления способом размещения модулей в 
проекте. Одни команды используются в файле модуля, другие — в DPK-файле пакета. 
    Следующие команды можно~йспользовать в модулях, которые предполагается 
внести в пакет. Разместите их в самом начале исходного файла модуля. 
    •    $G-, $IMPORTEDDATA OFF или $DENYPACKAGEUNIT  ON. Все эти команды 
имеют один и тот же эффект с точки зрения пакетов: они препятствуют включению 
данного модуля в пакет. Их стоит использовать в специальных случаях, когда 
важно, чтобы конкретный код содержался в ЕХЕ-файле, а не в отдельной 
библиотеке DLL. 
    •    $WEAKPACKAGEUNIT  ON. Модуль, содержащий эту команду, будет слабо 
пакетированным. Идея слабого пакетирования несколько туманна и трудна для 
понимания, и вряд ли вам часто придется ею пользоваться, поэтому она 
рассматривается в отдельном разделе, "Команда SWEAKPACKAGEUNIT". 
    Следующие команды можно использовать в DPK-файле пакета. 
    •    $DESIGNONLY ON помечает пакет исключительно как пакет времени 
разработки и эквивалентна отключению опции Runtime package в диалоговом окне 
Package Options. 
    •    $RUNONLY ON помечает пакет исключительно как пакет времени выполнения 
и эквивалентна включению опции Design package в диалоговом окне Package Options. 
    •    $IMPLICITBUILD OFF предохраняет пакет от неявной перекомпиляции и 
эквивалентна включению параметра Explicit rebuild в диалоговом окне Package Options. 
    Вам необходимо поинтересоваться командами $DESIGNONLY, $RUNONLY и 
$IMPLICITBUILD, если вы планируете создавать или редактировать DPK-файлы. В 
противном случае редактор пакетов сам при необходимости вставит эти команды. 

    354 Часть IV. Разработка компонентов 


    Команда $WEAKPACKAGEUNIT 

    Команда $WEAKPACKAGEUNIT была введена разработчиками Delphi для_Ёешен1ия 
слецифическсж jTgo6jieMbi, с 4^Ш^^Ш'1?1ЙЩ2У^''СЬ ПРИ реализации пакетов в 
Delphi 3. Они стремились предоставить доступ ко всём стандартнымбиблйоТёКам 
DLL Windows с помощью пакета VCL30. Но это привело к затруднениям, так как 
некоторые "стандартные" библиотеки DLL Windows на самом деле 
узкоспециализированы и не реализуются на всех компьютерах (например, 
библиотека PENWIN.DLL, инсталлируемая с приложением Реп Windows). Если бы в 
пакет VCL30 был включен модуль Penwin, который неявно ссылается на библиотеку 
PENWIN.DLL, никакое приложение, использующее VCL30, не работало бы ни на одной 
системе, в которой не была бы инсталлирована библиотека PENWIN.DLL, а это 
значит, что оно не работало бы на 99% систем Windows в мире. 
    Может показаться, что существует простое решение, состоящее в исключении 
ссылки на библиотеку PENWIN.DLL в пакете VCL(BO. Этот путь можно рассматривать 
как один из вариантов, но он приводит к возникновению другой трудности. 
Предположим, что вы получили компонент от производителя А и этот компо-'нент 
неявно ссылается наТэйблиотеку PENWIN.DLL. Кроме того, вы получили другой 
компонент от производителя Б, который сновав-таки ссылается на библиотеку 
PENWIN.DLL. В версиях, предшествующих Delphi 3, использование обоих 
компонентов в одном и том же приложении не вызвало бы проблемы. Обе ссылки в 
конце концов свелись бы к одной неявной ссылке на библиотеку PENWIN.DLL в 
конечном ЕХЕ-файле. Но с гуэимене.нием[пакетов .ситуация ,м§йаеТ?Я. Если два 
компонента будут реализованы в отдельных пакетах времени выполнения, каждая 
пакетная библиотека DLL будет содержать неявную ссылку на библиотеку 
PENWIN.DLL, поэтому она будет загружена дважды при загрузке приложения, 
которое использует эти два компонента. Это может вызвать проблемы, связанные с 
порядком инициализации и с ссылками на глобальные переменные в библиотеке DLL, 
приводящие к ситуации, которой фирма Borland хотела бы избежать. Речь идет р„ 
ситуации^коща приложение,, даетрренное с использованием пакетов, ведет себя не 
так, как приложение, построенное без пакетов. 
    Теперь на сцене появляются слабо пакетированные модули. И в чем же 
заключается слабое пакетирование? Модуль, исходный код которого включает 
команду $WEAKPACKAGEUNIT ON, содержится в пакете, но его код не присутствует в 
пакетной библиотеке DLL. В этом_явно^1у§?твует J<^oe-TO^aaoTHBOp_e4ne. 
Несмотря на то что код_не сааержится[ в naj<eTHOu.6,n6^noT' eRe^DLL, 
он~содержигся в оср3"$айле_пакета. Если приложение использует слабо 
пакетированный модуль, Ъго код'достается^ йз'ТСРЯрайла и присоединяется к 
ЕХЕ-файлу. В результате такого решения фирма Borland смдгла_шдпюда1ь Penwinи 
другие; модули в пакет VCL30, избежав проблем с множественной 
загруз^с^^блиотек^Ди,,^1дтйабрли(а.8_тр,,же вр§мя приложениям, использующим 
ТТа'кет ус^з6ГрабЪтатБТТва-1а^гКюте^,*на"которых библиотеку PENWIN.DLL не 
инсталлирована. 
    Вот почему вам почти никогда не придется использовать команду 
$WEAKPACKAGEUNIT. На самом деле существует только две причины ее 
использования. Первая (которая и побудила фирму Borland ввести слабое 
пакетирование) состоит в следующем. Если вы планируете распространять 
библиотеку DLL, которую, по вашим предположениям, разработчики компонентов 
Delphi будут использовать в пакетах, а они, в свою очередь, будут передаваться 
другим пользователям Delphi, то в этом случае стоит применить слабое 
пакетирование к модулю интерфейса библиотеки DLL, чтобы пользователи пакетов 
не столкнулись с конфликтами, когда два или больше компонентов обращаются к 
одному и тому же модулю интерфейса. 
    Вторая причина заключается в получении гарантии, что этот код компонуется 
прямо в ЕХЕ-файл приложения. Если вы распространяете пакет для использования 
другими разработчиками Delphi, он может содержать код, который по некоторой 
причине должен компоноваться непосредственно в ЕХЕ-файл приложения, а не в 
пакетную библиотеку DLL (например, утилитная функция, оптимизированная по 
скорости, которая, будучи оформленной как функция DLL, могла бы недопустимо 
замедлить работу). Используя слабо пакетированный модуль, вы также 
освобождаетесь от необходимости предоставления отдельного оси-файла для кода, 
который должен быть скомпилирован непосредственно в ЕХЕ-файл. 
    И в заключение отметим, что слабо пакетированные модулиJHQ могут 
срдер^жать глобальных переменных в разделах интерфейса и разделов 
инициализации (initialization) и деинйциализации (finaiization). 

    Регистрация версий пакетов 

    Главное, о чем вы должны помнить при создании пакетов времени выполнения 
для передачи пользователям вашего кода, — это то, что рано или поздно вы 
выпустите обновленную версию этого пакета. При этом вы должны быть уверены, 
что модернизация не окажет пагубного влияния на все существующие приложения, 
которые используют ранние версии данного пакета. 
    Чтобы процесс обновления пакета проходил без сучка и задоринки, необходимо 
выполнить следующих три шага. 
    1. Включить в пакет ресурс VERSIONINFO. 1. Включить в пакет ресурс 
VERSIONINFO. 3. Включить в пакет ресурс VERSIONINFO. 

    Глава 15. Работа с пакетами      355 

    Надеюсь, я ясно изложил свою точку зрения? Главной причиной прекращения 
работы приложения А при инсталляции приложения Б является перезапись 
программой инсталляции приложения Б критического файла, используемого 
приложением А, причем когда записанная версия оказывается устаревшей или 
несовместимой. Единственным способом, позволяющим избежать таких 
неприятностей, является включение в общие файлы точной информации о версии и 
использование довольно интеллектуальных программ инсталляции, чтобы они не 
заменяли новую версию файла более старой (большинство коммерческих утилит 
инсталляции и являются интеллектуальными). 
    Диалоговое окно параметров в редакторе пакетов включает вкладку 
Versionlnfo, которая работает аналогично вкладке Versionlnfo диалогового окна 
Project Options. Обязательно воспользуйтесь ею. За более подробной информацией 
о ресурсе Versionlnfo обращайтесь к главе 8, "Создание приложений". 
    Весьма желательно также делать свои обновленные пакеты совместимыми в 
обратном направлении. Например, если исходная версия пакета включала функцию 
Foo, которая вычисляла среднее значение массива целых чисел, то вряд ли стоит 
переопределять ее в новой версии пакета на возвращение объема жесткого диска. 
Кроме того, если в пакете объявляется класс, то любая модификация определения 
этого класса сделает новую версию пакета неприемлемой для приложений, 
рассчитанных на работу с исходным пакетом. Точка. 
    Если вам позарез нужно внести в пакет изменения, которые сделали бы его 
несовместимым в обратном направлении, присвойте обновленному пакету новое имя. 
Например, фундаментальный пакет Delphi называется VCL30. Если фирма Borland 
решит выпустить новые несовместимые версии, им будут даны такие имена, как 
VCL31, VCL35 и VCL40. В этом случае как старые, так и новые пакеты смогут 
сосуществовать в одной системе, и приложения, требующие того или иного пакета, 
будут функционировать корректно. 
    Безопасное обновление совместно используемых файлов было одной из самых 
серьезных проблем для Windows и других операционных систем со времени принятия 
концепции о файлах общего пользования. Не пожалейте сил и сделайте все, чтобы 
ваши пакеты были как можно более совместимыми в обратном направлении и 
содержали точную информацию об используемой версии продукта. Тем самым вы 
избавите как себя, так и своих пользователей от ужасной головной боли. 

    Распространение пакетов 

    Распространяя приложения, которые используют пакеты, вы должны включить в 
поставку и пакетные библиотеки DLL времени выполнения, используемые 
приложением, если вы не уверены, что на компьютерах пользователей 
инсталлированы необходимые пакеты. Лучше всего при этом включить в дистрибутив 
все пакеты и предоставить программе проверить, инсталлированыли пакеты, а 
также сравнить номера версий для определения необходимости перезаписи. Если 
нужная библиотека DLL не установлена или не найдена загрузчиком Windows, в 
начале работы приложения операционная система отобразит окно с сообщением об 
ошибке (рис. 15.9). 
    В какие каталоги следует инсталлировать пакеты? Существует три основных 
категории пакетов времени выполнения, а используемый каталог зависит от 
категории, которой он принадлежит. 
    1.    Системные пакеты используются всеми или почти всеми приложениями 
Delphi. К этой категории относятся пакеты времени выполнения, поставляемые с 
Delphi (VCL30   и т.п.). Они должны устанавливаться в системный каталог 
Windows, где их смогут разыскать все приложения, работающие с пакетами. 
    2.    Общие пакеты используются многими приложениями одного и того же 
производителя (при выпуске, например, комплекта приложений). Вы можете 
создать, к примеру, для основных производителей каталог "Общие файлы" и 
размещать там подобные пакеты. Поскольку этот каталог будет отсутствовать в 
системном пути, вам придется установить в системном реестре путь специально 
для данного приложения. Предположим, вы являетесь главным программистом 
SlamDunk  Corporation   и   ваше   новое   приложение  должно   по   умолчанию 
использовать   каталог  инсталляции \PROGRAM  FILES\SLAMDUNK\WHIZBANG\,   а  
его   пакеты   и  другие   общие   файлы   расположены   в   каталоге \PROGRAM 
FILES\SLAMDUNK\COMMON FILESV Ключи системного реестра должны совпадать с 
ключами, представленными на рис. 15.10. 
    Большинство программ инсталляции позволяет выполнять настройку записей 
системного реестра. Будем надеяться, что программы инсталляции приложений 
Delphi в конце концов будут включать полуавтоматическую возможность настройки 
информации о пути для конкретного приложения. 
    3.   Другие пакеты. Размещение пакета в одном каталоге с ЕХЕ- и 
DLL-файлами, которые его используют, имеет смысл, если использовать этот пакет 
будет несколько модулей. Помните, что если ваше приложение содержит небольшое 
количество модулей, требующих данный пакет, то вам, возможно, лучше 
скомпоновать код в модули и вообще не использовать пакет. 

    356         Часть IV. Разработка компонентов 

    Рис. 15.9. Типичное сообщение об ошибке, отображаемое Windows, когда она 
не может найти библиотеку DLL 

    Рис. 15.10. Установка в системном реестре пути для конкретного приложения 

    I Совет 1 

    Если вы занимаетесь построением библиотеки сервера OLE, то любые 
используемые им библиотеки DLL — включая пакетные DLL — должны быть размещены 
в системном каталоге Windows. Это требование вытекает из ограничения алгоритма 
поиска, используемого загрузчиком модулей Windows NT. За более подробной 
информацией об OLE обращайтесь к главе 18, "Работа с OLE, серверы документов и 
элементы управления ActiveX". 
    Если вы будете следовать описанным выше рекомендациям, у вас не возникнет 
трудностей с инсталляцией и запуском приложений, использующих пакеты. 
    Если вы передаете пакеты другим разработчикам Delphi, включите в поставку 
хотя бы DCP- и DPL-файлы. ОСР-файлы содержат информацию, используемую средой 
IDE для генерации связей с пакетными библиотеками DLL (а также код для любых 
слабо пакетированных модулей), в то время как DPL-файлы содержат реальный код 
пакетов времени выполнения. 
    Если ваш продукт состоит из нескольких пакетов и связанных файлов, процесс 
его распространения может сильно усложниться. Чтобы справиться с этой 
проблемой, можно воспользоваться утилитой Package Collection Editor (PCE.EXE), 
поставляемой вместе с Delphi 3. Она позволит объединить все файлы, относящиеся 
к вашим пакетам (DPL, DCP и т.д.), в коллекцию пакетов, которая представляет 
собой единый файл с расщирением DPC. Ваши пользователи смогут инсталлировать 
этот файл в свою среду IDE, и различные составляющие файлы будут автоматически 
выделены и инсталлированы из коллекции. 
    За детальными инструкциями по использованию утилиты Package Collection 
Editor обращайтесь к документации Delphi. Возможно, имеет смысл добавить файл 
РСЕ. ЕХЕ в меню Tools среды IDE, чтобы обеспечить легкий доступ к нему во 
время работы с Delphi. 

    Резюме 

    В этой главе описывались пакеты, которые открывают новые возможности 
Delphi 3. Пакеты позволяют группировать общий код и объекты в модули общего 
пользования, чтобы уменьшить общий размер приложений. Пакеты также являются 
средством, с помощью которого компоненты VCL распространяются и инсталлируются 
в среде IDE Delphi 3. В этой главе рассказывается обо всем, что необходимо 
знать для использования в приложениях пакетов, поставляемых с Delphi или 
приобретенных у независимых производителей, а также для создания своих 
собственных пакетов. 

    Глава 15. Работа с пакетами 357 

