Сообщений 0 Оценка 96 Оценить |
Введение Copy&Paste ActiveX Forms Frames Repository – репозитарий объектов Заключение |
Каждый раз, приступая к разработке нового проекта, я ловлю себя на мысли, что когда-то я уже делал подобные формы. Поэтому я решил поделиться несколькими мыслями о повторном использовании форм в Delphi. Я не претендую на авторство описанных ниже методов, однако я еще не встречал статьи, где данный вопрос был освещен достаточно полно (а может, я плохо искал?).
Задачу повторного использования форм в Delphi можно разбить на две части, а именно:
Первая часть задачи актуальна при создании различных диалогов и форм для решения типовых задач (например, logon-диалог). Внешний вид этих диалогов практически стандартизован, но по каким-то причинам эти диалоги не реализованы (или реализованы не совсем так, как хотелось бы) в составе библиотек Delphi. Не менее актуальна эта подзадача при создании форм, предполагающих возможность их последующего вызова из других языков и сред программирования.
Вторая же часть задачи актуальна при проектировании форм, состоящих из нескольких «кусков», либо форм, некоторые элементы которых должны от проекта к проекту менять свои атрибуты (например, свойство Enabled или Visible), причем в начале проектирования не всегда можно четко сказать, какие из элементов управления будут менять свои свойства.
Первое, что приходит в голову – простое копирование файлов форм из проекта в проект. Это самый простой и достаточно эффективный способ, однако не лишенный некоторых неудобств.
Простое копирование файлов форм из проекта в проект с последующей их доработкой приводит к необходимости вручную обновлять эти файлы во всех проектах. Данная операция носит рутинный характер и часто не бывает выполнена из-за элементарной забывчивости.
От версии к версии Delphi формат файлов форм может меняться. Это приводит к необходимости правки файлов при переходе на новые версии Delphi.
Чаще всего создается некая общая папка с формами, использующимися в различных проектах. Однако в состав Delphi входит средство, выполняющее функции хранилища форм – репозитарий объектов.
Использование DLL как хранилища форм
При необходимости использовать формы в других средах разработки или в различных версиях Delphi одновременно, можно "упаковать" формы в динамически загружаемые библиотеки (DLL). Этот способ позволяет распространять свои формы без предоставления исходного кода, что иногда может пригодиться в коммерческих целях. При использовании данного способа в DLL объявляется для экспорта ряд функций. Минимальный набор – функция модального показа формы.
В качестве примера создадим простейшую DLL с формой. Для этого в IDE выберем пункт File / New/Other, а в появившемся диалоге – пункт меню “DLL Wizard”. Сохраним модуль под именем FormDLL. В заготовку библиотеки добавим форму, которую затем и будем отображать в различных приложениях (File/New/Form). На форме расположим ListBox, заполнив его тремя значениями, и две кнопки – «OK» и «Отмена». Свойство формы BorderStyle установим в bsDialog, а свойство кнопок ModalResult – в mrOk и mrCancel, соответственно. Внешний вид формы приведен ниже.
Осталось написать код функции, отображающей форму и возвращающей выбор пользователя. Ниже приведен полный исходный код модуля FormDLL
library FormDLL; uses SysUtils, Windows, Classes, f_form in 'f_form.pas' {Form1}; {$R *.res} {Функция отображения формы} function ShowForm:Integer;stdcall; begin try Form1:=TForm1.Create(nil); Form1.ShowModal; if Form1.ModalResult= idOk then Result:=Form1.ListBox1.ItemIndex else Result:=-1; finally FreeAndNil(Form1); end; end; {Функции, экспортируемые из DLL} exports ShowForm; begin end. |
Вот и все. Использовать такую DLL очень просто – нужно поместить её в каталог нуждающегося в ней приложения. Можно организовать как статическую загрузку DLL (при старте приложения), так и динамическую (загружать и выгружать её по мере необходимости).
Для организации статической загрузки следует объявить функцию из DLL следующим образом:
function ShowForm:Integer;external 'FormDLL.dll'; |
после чего функцию можно использовать обычным для Delphi способом.
Организация динамической загрузки немного сложнее. Сперва необходимо соответствующим образом объявить процедурный тип:
TProc = function:integer;stdcall;
|
После этого можно загружать DLL и вызывать функцию:
var H:Cardinal; Proc:TProc; Res:Integer; Begin {Загрузка библиотеки} H:=LoadLibrary('FormDLL.dll'); {Получение адреса функции вывода формы} @Proc:=GetProcAddress(H,'ShowForm'); {Вызов функции и получение ее результата} Res:=Proc; {Выгрузим библиотеку} FreeLibrary(H); // Отобразим выбор пользователя case Res of 0:Label1.Caption:='Вася'; 1:Label1.Caption:='Вова'; 2:Label1.Caption:='Петя'; else Label1.Caption:='Никто'; end; |
Данный код предельно упрощен, например, в нем нет проверки ошибок при загрузке библиотеки.
В ОС Windows широко используется технология компонентно-ориентированного программирования ActiveX. В свою очередь Delphi позволяет воспользоваться этой технологией как для проектирования самих компонентов ActiveX, так и для их использования в приложениях. Я не буду здесь углубляться в тонкости технологии ActiveX, просто предложу вашему вниманию простой пример создания формы ActiveX и ее использования.
Что ж, начнем – File/New/Other. В появившемся диалоге перейдем на закладку ActiveX и выберем элемент ActiveXForm. На экране появится диалог установки параметров
Параметр VCL Class Name – класс-родитель для реализации всех ActiveX-форм в Delphi
Параметр New ActiveX Name – имя класса формы.
Implementation Unit – имя модуля, содержащего описание формы
Project Name – Имя проекта
Threading Model – потоковая модель. Описывает поведение формы при использовании ее несколькими потоками.
Оставим без изменений все параметры в диалоге и нажмем кнопку OK. При этом мы получим заготовку проекта с пустой формой. Разместим на форме ListBox и заполним его так же, как при использовании DLL. Далее нужно создать метод для получения выбора пользователя. Для этого выберем пункт меню IDE View/Type Library.
На экране появится редактор библиотеки типов, в которой описываются интерфейсы, реализуемые в нашей форме. Выберем интерфейс IActiveFormX и нажмем кнопку Method (всплывающая подсказка New Method). В левую часть будет добавлен новый метод с именем Method1. Переименуем его в Get_Result. В правой части диалога при этом будут отображаться параметры метода. Закладка Parameters при этом позволяет определить набор входных и выходных параметров, а также возвращаемое значение.
Добавим выходной параметр Res типа VARIANT*. Результат представлен на рисунке. Нажав кнопку Refresh в том же диалоге, мы обновим модуль реализации интерфейса формой ( в нашем проекте ActiveFormImpl1). Там появится заготовка для написания кода метода. Код метода очень прост:
procedure TActiveFormX.Get_result(out Res: OleVariant); begin if ListBox1.ItemIndex >=0 then Res:=ListBox1.Items[ListBox1.ItemIndex] else Res:='Никто'; end; |
Осталось скомпилировать проект (Ctrl+F9) и зарегистрировать ActiveX-форму в системе (Run/Register ActiveX Server). Можно пользоваться.
Чтобы воспользоваться полученным компонентом в Delphi, необходимо установить его в палитру компонентов. Для этого предназначен пункт меню Component/Import ActiveX Control. В диалоге импорта из представленного списка выберем наш ActiveFormProj1 Library и установим его кнопкой Install. По умолчанию он устанавливается на закладку ActiveX. Создадим проект нового приложения File/New|Application и на его главную форму поместим компонент ActiveFormX. Чтобы получить ввод пользователя, воспользуемся созданным методом Get_Result интерфейса ActiveX-формы:
var A:IActiveFormX; Str:OleVariant; begin A:=ActiveFormX1.ControlInterface; A.Get_Result(Str); ShowMessage(Str); end; |
Два вышеописанных способа позволяют изготавливать формы, которые можно использовать повторно. Однако использовать эти способы для проектирования форм с возможностью гибкой настройки довольно трудоемко. Начиная с 5-ой версии Delphi, появилась возможность строить формы из заготовок-фреймов. Причем после вставки фрейма в форму есть возможность писать обработчики событий элементов фрейма в форме. На одной форме можно разместить несколько фреймов и организовать их взаимодействие друг с другом.
Воспользоваться фреймами очень просто. Этап первый – создать фрейм (File/New/Frame). При этом в проект будет добавлен новый фрейм. Этап второй – так же, как при проектировании форм, разместить на фрейме визуальные и невизуальные компоненты. Возможно, написать обработчики событий для компонентов для реализации нужного поведения компонентов фрейма. Этап третий – поместить фрейм на форму. Для этого на закладке Standart палитры компонентов следует выбрать значок Frames и кликнуть мышью на форме. Появится список фреймов, включенных в данный проект. Выбрать нужный фрейм. Все. В сочетании с репозитарием объектов фреймы позволяют свести к минимуму необходимость повторной разработки элементов пользовательского интерфейса.
Наконец, последний способ многократно использовать формы (а так же и фреймы)– использование репозитария объектов Delphi. Репозитарий объектов – это централизованное хранилище форм, фреймов и заготовок проектов, предназначенных для повторного использования в среде Delphi. Форма, которую мы видим при выборе пункта меню File/New/Other, отображает содержимое репозитария. Добавить форму или фрейм в репозитарий не составляет никакого труда. Просто щелкните на них правой кнопкой мыши и выберите пункт меню “Add to repository”. На экран будет выведен диалог добавления.
Элементы этого диалога достаточно понятны:
Список Forms – список форм и фреймов, доступных для добавления.
Title – наименование под которым элемент будет виден в репозитарии
Description – описание элемента
Page – страница, на которой элемент будет отображаться.
Author – сведения об авторе данного элемента.
Поместить форму из репозитария объектов в проект несложно, более того, вы это фактически уже неоднократно делали – File/New/Other. Обратим внимание только на группу переключателей внизу формы: их три Copy, Inherit, Use. Copy – копирует форму из репозитария в новый модуль. Inherit – наследует класс объекта, описанного в репозитарии. Use – просто включает модуль из репозитария в текущий проект.
Диалог настройки страниц репозитария и добавленных объектов вызывается пунктом меню IDE Tools/Repository. Если вы любитель покопаться во внутренностях Delphi, то скажу, что описание репозитария хранится в файле delphi32.dro. Файл описания имеет формат ini файла Windows.
Ну вот и все, надеюсь, вам понравилось. Если у вас есть предложения и пожелания по данной статье, я буду рад получить их по адресу mgoblin@mail.ru
Сообщений 0 Оценка 96 Оценить |