Урок 1. Введение в создание компонентов
Что такое компоненты? Это самоастоятельные объекты, которые вы можете
использовать в различных программах на Delphi (и на C++ Builder).
Например, разные кнопочки, checkbox'ы, таймеры и более сложные обекты,
которые вы видите на Палитре компонентов - это компоненты. Компоненты вы
можете делать и сами - и как раз этому и посвящен этот раздел.
Компоненты могут быть простыми (кнопочка, которая пишит при нажатии на
нее) и очень сложными (встроенный WEB-браузер). Компоненты можно писать с
нуля, определяя в них все методы, свойства и события, а можно
воспользоваться некоторым уже готовым компонентом (классом компонета) и
просто добавить в него то, что отсутствует в классе родителя. Или же
переопределить методы родительского класса, если они работаю не так, как
вам надо. Отметьте сразу, что обрать что-либо из родительского класса
нельзя - если, скажем, некоторое свойство есть у родительского
компонента, то оно будет и у компонента, произведенного от него.
Компоненты могут быть видимыми (как большинство), так и невидимыми
(как таймер) на этапе выполнения. Также компонент может и часто должен
различать два своих состояния - состояние на этапе разработки программы
(не компонета, а именно программы), использующей компонент и состояние
на этапе работы программы. Классический пример такого компонента - это
таймер. Во время разработки программы он не "тикает", по время же работы
программы - может "тикать" (т. е. посылать сообщение WM_TIMER).
Компоненты, которые вы разрабатываете, могут состоять из нескольких
других компоненетов. Например, вы можете сделать компонент,
представляющий из себя поле для ввода некоторых данных (Edit) и метку
радом с ним (Label). Конечно, можно не заводить отдельный компонент, а
использовать Edit и Label отдельно, но такой компонет позволяет делать
многие операции автоматически (например, одновременное выравнивание Edit
и Label), так что если вам приходиться заниматься этим достаточно
много, то создание даже такого простого компонента может сэкономить
массу времени.
Компонеты распространяются в виде отдельных файлов, так что установка
в среды программирования Delphi или C++ Builder не займет много
времени. Установленные компоненты появятся на Палитре компонентов - на
отдельной или уже существующей вкладке. Разумеется, установленные
компоненты можно будет потом при желании удалить. Компоненты, которые
использует программа, могут непосредственно включаться в exe-файл, а
могут и использоваться в отдельном файле. Второй вариант может оказаться
предпочтительнее, если данный компонент использует несколько программ.
Часто компонеты третьих фирм распространяются вместе с исходным
кодом, так что вы сможете при желании слегка "подправить" их код, исходя
из вашей задачи.
Компоненты - это не единственная технология такого рода. Например,
есть еще элементы ActiveX от Microsoft. В новой платформе .NET тоже
можно делать пользовательские элементы. У каждой из этих технологий есть
и плюсы, и минусы, которые сейчас мы обсуждать не будем.
Урок 2. Создаем первый компонент
На этом занятии мы начнем создавать наш первый компонент TRandom
(универсальная игральная кость). Его основная задача - это выдавать
случайные числа от min до max (min и max будут в числе его свойств).
Кроме того, у него будет метод Random, который , который и будет
выдавать случайное число в указанных пределах. И, наконец, у компонента
будет событие GetMax, которое будет возникать, когда на нашей "игральной
кости" выпадет максимально возможное количество очков. Внешне наш
компонент будет выглядеть как Label, т. е. выдаваемое им случайное число
будет выводиться в виде надписи.
Для создания заготовки для нового компонента зайдите в меню Component и выберите New Component:
Появится окно 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. Добавление свойств
Подолжаем работать с компонентом, который мы начали на прошлом занятии.
У нашего компонента дожно быть два свойства - 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). На последующих
занятиях мы посмотрим, как можно задавать перечисляемые свойства,
объектные и другие.
Урок 4. Добавление методов
Приступаем к добавлению метода. Назовем мы его GetNumber, и он будет выдавать случайное число от min до max.
Сначала мы должны объявить новый метод в классе компонента. Это мы
сделаем в public-секции, так как наш метод должен вызываться извне:
type
TRandom = class(TLabel)
...
public
{ Public declarations }
Function GetNumber: Integer;
Далее в этом же файле мы должны написать реализацию этого метода:
Function TRandom.GetNumber: Integer;
var
i: Integer;
begin
//Включение датчика случайных чисел.
Randomize;
//Получаем случайное число от Fmin до FMax.
i:= System.Random(Fmax - Fmin + 1)+ Fmin;
//Выводим результат на компонент.
self.Caption := IntToStr (i);
//Возвращаем результат.
Rand:=i;
end;
То, что делается, ясно из комментария. Отметьте только, что мы
используем полное имя для функции Random, чтобы не было конфликта с
именем нашего модуля.
Добавленная нами функция выведет случайное число на компонент и возвратит его же в качестве возвращаемого значения.
Урок 5. Добавление событий
Теперь настало время выяснить, как к компоненту добавлять события.
Сейчас мы добавим событие, которое будет наступать, когда выдаваемое
методом GetNumber случайное число будет максимальным (т. е. равным max).
При использовании нашего компонента можно будет в обработчике этого
события написать все что угодно. Этим уже будет заниматься не наш
компонент, а программа, использующая его.
А вот такие добавления надо сделать в коде нашего компонента.
Во-первых, мы должны наше событие объявить в private-части нашего
класса:
TRandom = class(TLabel)
private
{ Private declarations }
...
// Объявление события.
FGetMax: TNotifyEvent;
Как вы видите, события имеют тип TNotifyEvent.
Далее мы должны опубликовать наше событие - для того, чтобы оно появлялось в Инспекторе объектов Delphi:
published
{ Published declarations }
...
// Публикация события.
property GetMax: TNotifyEvent read FGetMax write FGetMax;
Как тут видно, при использовании нашего компонента это событие будет видно под именем GetMax.
И, наконец, мы должны вызвать наше событие в нужном месте нашего
кода. А именно мы хотим, чтобы оно возбуждалось, когда случайное число,
получаемое в методе GetNumber нашего компонента, оказывалось равным
максимально возможному, т. е. Fmax:
Function TRandom.GetNumber: Integer;
...
begin
...
i:= System.Random(Fmax - Fmin + 1)+ Fmin;
// Возбуждение события.
if (Assigned(FGetMax) and (i = Fmax)) then FGetMax(self);
Как вы видите, перед возбуждением события мы проверяем, а был ли ему вообще назначен обработчик. Это мы делаем в выражении
Assigned(FGetMax)
Вот, собственно, и все с добавлением в наш класс события.
Урок 6. Инсталляция компонента
Для инсталляции сначала необходимо сохранить файл с компонентом на
жестком диске. Сделайте это обязательно, если вы еще работаете с
исходником компонента и он у вас еще открыт.
После этого выбирем пункт Install Component... меню Component:
В появившемся окне Install Component в поле Unit file name задайте
путь к pas-файлу вашего компонента, в поле Package file name - имя
пакета, в который будет установлен наш компонент. Этот пакет уже должен
существовать (по умолчанию все новые компоненты добавляются в пакет
dclusr.dpk). Если вы хотите установить компонент в новый пакет, то
воспользуйтесь в этом окне вкладкой Into new package.
Нажимайте на OK для продолжения инсталляции компонента и закрытия
окна. Через некоторое время появится окно Package , в котором
перечислены все компоненты пакета, в который мы записываем наш
компонент. Нажимаем в нем на кнопку Compile для компиляции и устанки
пакета:
С инсталляцией компонента все!
Урок 7. Испытание компонента
Для испытания компонента запустите Delphi. Сейчас наш компонент уже
должен быть на вкладке My Components (так как мы задали эту вкладку для
него при вызове метода RegisterComponents):
Перенесите его двойным щелчком на форму. Выделив экземпляр нашего
компонента на форме, перейдите на вкладку Events Инспектора объектов:
Как вы видите, тут присутствует наше событие GetMax (его мы определили на уроке 5). Задайте двойным щелчком обработчик для нашего события. В обработчике напишите, например, такой код:
procedure TForm1.Random1GetMax(Sender: TObject);
begin
Form1.Caption:='Event GetMax';
end;
Добавьте еще на форму кнопку, в обработчике которой напишите, например, следующее:
procedure TForm1.Button1Click(Sender: TObject);
begin
Random1.GetNumber;
end;
Кроме того, в Инспекторе объектов задайте значения свойств min и max:
Запускайте программу. При нажатии на кнопку на нашем компоненте будут
появляться случайные числа от min до max. Если появится максимальное
число, то форма поменяет заголовок, как мы это и задали в обработчике
события для нашего компонента:
|