Версия текста: 1.2
Введение
Copy&Past
ActiveX Forms
Frames
Repository – репозитарий объектов
Заключение
Введение
Каждый раз, приступая к разработке нового
проекта, я ловлю себя на мысли, что когда-то я уже делал подобные формы. Поэтому
я решил поделиться несколькими мыслями о повторном использовании форм в Delphi.
Я не претендую на авторство описанных ниже методов, однако я еще не встречал
статьи, где данный вопрос был освещен достаточно полно (а может, я плохо
искал?).
Задачу повторного использования форм в Delphi
можно разбить на две части, а именно:
- Способы создания визуальных форм для
многократного использования без возможности быстрого внесения в
них дальнейших изменений.
- Способы создания визуальных форм, имеющих
возможность последующей гибкой настройки.
Первая часть задачи актуальна при создании
различных диалогов и форм для решения типовых задач (например, logon-диалог).
Внешний вид этих диалогов практически стандартизован, но по каким-то причинам
эти диалоги не реализованы (или реализованы не совсем так, как хотелось бы) в
составе библиотек Delphi. Не менее актуальна эта подзадача при создании форм,
предполагающих возможность их последующего вызова из других языков и сред
программирования.
Вторая же часть задачи актуальна при
проектировании форм, состоящих из нескольких «кусков», либо форм, некоторые
элементы которых должны от проекта к проекту менять свои атрибуты (например,
свойство Enabled или Visible), причем в начале проектирования не всегда можно
четко сказать, какие из элементов управления будут менять свои свойства.
Copy&Past
Первое, что приходит в голову – простое
копирование файлов форм из проекта в проект. Это самый простой и достаточно
эффективный способ, однако не лишенный некоторых неудобств.
Простое копирование файлов форм из проекта в
проект с последующей их доработкой приводит к необходимости вручную обновлять
эти файлы во всех проектах. Данная операция носит рутинный характер и часто не
бывает выполнена из-за элементарной забывчивости.
От версии к версии 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;
Данный код предельно упрощен, например, в нем
нет проверки ошибок при загрузке библиотеки.
ActiveX Forms
В ОС 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;
Frames
Два вышеописанных способа позволяют
изготавливать формы, которые можно использовать повторно. Однако использовать
эти способы для проектирования форм с возможностью гибкой настройки довольно
трудоемко. Начиная с 5-ой версии Delphi, появилась возможность строить формы из
заготовок-фреймов. Причем после вставки фрейма в форму есть возможность писать
обработчики событий элементов фрейма в форме. На одной форме можно разместить
несколько фреймов и организовать их взаимодействие друг с другом.
Воспользоваться фреймами очень просто. Этап
первый – создать фрейм (File/New/Frame). При этом в проект будет добавлен новый
фрейм. Этап второй – так же, как при проектировании форм, разместить на фрейме
визуальные и невизуальные компоненты. Возможно, написать обработчики событий для
компонентов для реализации нужного поведения компонентов фрейма. Этап третий –
поместить фрейм на форму. Для этого на закладке Standart палитры компонентов
следует выбрать значок Frames и кликнуть мышью на форме. Появится список
фреймов, включенных в данный проект. Выбрать нужный фрейм. Все. В сочетании с
репозитарием объектов фреймы позволяют свести к минимуму необходимость повторной
разработки элементов пользовательского интерфейса.
Repository – репозитарий объектов
Наконец, последний способ многократно
использовать формы (а так же и фреймы)– использование репозитария объектов
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.
Ну вот и все, надеюсь, вам понравилось.
Автор: Михаил Голованов
|