Введение в создание компонент

advertisement
Семенова Н. С.
Создание собственных компонент
1/4
Введение в создание компонент
Что такое компоненты? Это самостоятельные объекты, которые вы можете использовать в различных
программах на Delphi (и на C++ Builder). Например, разные кнопочки, checkbox'ы, таймеры и более
сложные объекты, которые вы видите на Палитре компонентов - это компоненты. Компоненты вы
можете делать и сами - и как раз этому и посвящен эта лабораторная работа.. Компоненты могут быть
простыми (кнопочка, которая пищит при нажатии на нее) и очень сложными (встроенный WEBбраузер). Компоненты можно писать с нуля, определяя в них все методы, свойства и события, а можно
воспользоваться некоторым уже готовым компонентом (классом компонента) и просто добавить в него
то, что отсутствует в классе родителя. Или же переопределить методы родительского класса, если они
работаю не так, как вам надо. Отметьте сразу, что убрать что-либо из родительского класса нельзя если, скажем, некоторое свойство есть у родительского компонента, то оно будет и у компонента,
произведенного от него.
Компоненты могут быть видимыми (как большинство), так и невидимыми (как таймер) на этапе
выполнения. Также компонент может и часто должен различать два своих состояния - состояние на
этапе разработки программы (не компонента, а именно программы), использующей компонент и
состояние на этапе работы программы. Классический пример такого компонента - это таймер. Во время
разработки программы он не "тикает", по время же работы программы - может "тикать" (т. е. посылать
сообщение WM_TIMER).
Компоненты, которые вы разрабатываете, могут состоять из нескольких других компонентов.
Например, вы можете сделать компонент, представляющий из себя поле для ввода некоторых данных
(Edit) и метку радом с ним (Label). Конечно, можно не заводить отдельный компонент, а использовать
Edit и Label отдельно, но такой компонет позволяет делать многие операции автоматически (например,
одновременное выравнивание Edit и Label), так что если вам приходиться заниматься этим достаточно
много, то создание даже такого простого компонента может сэкономить массу времени.
Компоненты распространяются в виде отдельных файлов, так что установка в среды программирования
Delphi или C++ Builder не займет много времени. Установленные компоненты появятся на Палитре
компонентов - на отдельной или уже существующей вкладке. Разумеется, установленные компоненты
можно будет потом при желании удалить. Компоненты, которые использует программа, могут
непосредственно включаться в exe-файл, а могут и использоваться в отдельном файле. Второй вариант
может оказаться предпочтительнее, если данный компонент использует несколько программ.
Часто компоненты третьих фирм распространяются вместе с исходным кодом, так что вы сможете при
желании слегка "подправить" их код, исходя из вашей задачи.
Компоненты - это не единственная технология такого рода. Например, есть еще элементы ActiveX от
Microsoft. В новой платформе .NET тоже можно делать пользовательские элементы. У каждой из этих
технологий есть и плюсы, и минусы.
Создаем первый компонент
Создадим компонент TRandom (универсальная игральная кость). Его основная задача - это выдавать
случайные числа от min до max (min и max будут в числе его свойств). Кроме того, у него будет метод
Random, который, который и будет выдавать случайное число в указанных пределах. И, наконец, у
компонента будет событие GetMax, которое будет возникать, когда на нашей "игральной кости"
выпадет максимально возможное количество очков. Внешне наш компонент будет выглядеть как Label,
т. е. выдаваемое им случайное число будет выводиться в виде надписи.
Для создания заготовки для нового компонента зайдите в меню Component и выберите New Component:
Семенова Н. С.
Создание собственных компонент
2/4
Появится окно New Component, в котором вам надо выбрать класс-предок для вашего компонента
(combobox Ancestor type) - тут задайте TLabel [StdCtrls] (т. е. наш компонент - потомок класса TLabel),
имя вашего класса (Class name) - тут можно впечатать все, что угодно, мы тут задали TRandom
(хорошей практикой является задание для всех ваших компонентов некоторого префикса), вкладка на
палитре компонентов для размещения нашего нового компонента (можно выбрать как существующую
вкладку, так и задать свою) - мы задали свою вкладку с именем My Components. Значение остальных
полей можно оставить без изменения - в Unit file name задается имя файла для компонента (по
умолчанию предлагается имя класса без буквы T) и места на диске, в которых компонент будет
искаться - тут тоже лучше все оставить как есть.
Нажимаем OK. Появится окно с некоторым количеством кода. Давайте посмотрим, что за код мы тут
имеем. Во-первых, мы имеем заготовку для нашего класса:
...
type
TRandom = class(TLabel)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;
...
Как вы видите, класс пока пуст - ничего содержательного.
Чуть пониже мы видим код для регистрации нашего компонента:
...
procedure Register;
begin
RegisterComponents('My Components', [TRandom]);
end;
...
Функция RegisterComponents в качестве первого параметра имеет имя вкладки на Палитре компонентов,
куда наш компонент будет проинсталлирован и вторым - имя класса самого компонента.
Семенова Н. С.
Создание собственных компонент
3/4
В принципе у нас уже есть вполне рабочий компонент. Только ничего полезного он делать не умеет.
Поэтому необходимо добавить к нему свойства, методы и события.
Добавление свойств.
У нашего компонента должно быть два свойства - min и max для задания минимальной и максимальной
границ для выдаваемого случайного числа. Делаем это следующим образом:
...
TRandom = class(TLabel)
private
{ Private declarations }
Fmin: Integer;
Fmax: Integer;
...
published
{ Published declarations }
property min: Integer read Fmin write Fmin;
property max: Integer read Fmax write Fmax;
end;
...
Свойство min (и абсолютно аналогичное свойство max) мы заводим следующим образом - во-первых,
мы объявляем в классе закрытую переменную Fmin нужного типа и во-вторых, мы в разделе published
нашего класса объявляем само свойство. Свойство объявляется с помощью ключевого слова property, за
которым следует имя свойства (min), его тип (Integer в данном случае) и как мы это свойство читаем и
записываем. Так как наше свойство min это, фактически, внутренная переменная Fmin, то после слов
read и write мы соответственно пишем имя этой переменной класса. Так как мы поместили свойства в
published-секцию нашего класса, то эти свойства появятся в Инспекторе объектов. Если нам надо
сделать свойство только для чтения или только для записи, то в этом случае надо писать лишь части
read или write, соответственно.
Заметьте, кстати, что имена внутренних полей принято начинать на букву F - чтобы сразу было
понятно, что это имя поля.
Пока наши свойства имеют обычный тип (Integer).
Добавление методов
Приступаем к добавлению метода. Назовем мы его GetNumber, и он будет выдавать случайное число от
min до max.
Сначала мы должны объявить новый метод в классе компонента. Это мы сделаем в public-секции, так
как наш метод должен вызываться извне:
type
TRandom = class(TLabel)
...
public
{ Public declarations }
Function GetNumber: Integer;
Далее в этом же файле мы должны написать реализацию этого метода:
Function TRandom.GetNumber: Integer;
var
Семенова Н. С.
Создание собственных компонент
4/4
i: Integer;
begin
//Включение датчика случайных чисел.
Randomize;
//Получаем случайное число от Fmin до FMax.
i:= System.Random(Fmax - Fmin + 1)+ Fmin;
//Выводим результат на компонент.
self.Caption := IntToStr (i);
//Возвращаем результат.
Rand:=i;
end;
То, что делается, ясно из комментария. Отметьте только, что мы используем полное имя для функции
Random, чтобы не было конфликта с именем нашего модуля.
Добавленная нами функция выведет случайное число на компонент и возвратит его же в качестве
возвращаемого значения.
Задание:
Создать компонент TRandomPicture. Функционально он мало отличается от компанента, который
описан выше. Единственное отличие - выдаваемое им случайное число будет выводиться в виде
рисунка – количеством точек на игральной кости. Для этого, прежде всего, необходимо изменить класс,
наследником которого является TRandomPicture. Предусмотреть тот факт, что могут меняться размеры
компонента - рисунок должен перерисовываться в новых размерах.
Download