32 Урока по Delphi:
Предыдущий урок Следующий урок
Урок 27 :
Создание собственных компонент
Содержание урока 27:
Обзор
Добавление новых объектов
в VCL
Заготовка для нового компонента
Соглашения по наименованиям
Выбор предка
Пример создания компонента
ex27.zip
-
Обзор
Поскольку Delphi является
открытой средой и позволяет не только использовать объекты из Библиотеки
Визуальных Компонент (VCL) в своей
программе, но и создавать новые объекты. Причем, ничего другого, кроме
Delphi, для этого не требуется. Создание
нового объекта в Delphi не является
очень сложной задачей, хотя для этого и требуется знание Windows
API, объектно-ориентированного программирования
и иерархии классов в VCL.
Может возникнуть вопрос;
если в Delphi уже есть своя библиотека,
то зачем еще создавать какие-то объекты?
Ответ прост: нельзя создать библиотеку на все случаи жизни и на все вкусы.
Новые компоненты, во-первых, позволяют расширить область применения Delphi:
например, с помощью библиотек объектов третьих
фирм разрабатывать приложения для работы в Internet.
Во-вторых, позволяют дополнить или настроить для себя имеющиеся в VCL
объекты (например, переопределить значения
свойств, устанавливаемые по умолчанию).
-
Добавление новых объектов
в VCL
Предположим, что у вас
появился уже готовый компонент. Как его добавить в VCL? Для
этого выберите пункт меню Options|Install Components… Появится
диалог, как на рис.1
Рис.A:
Диалог установки нового компонента
Нажмите “Add” и укажите
модуль, содержащий процедуру регистрации, нажмите “OK” и
после успешной перекомпиляции новый объект появится в палитре.
-
Заготовка для нового компонента
В среде Delphi есть
специальный эксперт, создающий заготовку для нового компонента. Вызвать
его можно в пункте меню File|New Component… (см
рис.2)
Рис.B:
Эксперт для создания нового компонента
В диалоге нужно указать имя нового класса (например, TMyButton),
предка класса (TButton) и
страницу палитры, куда поместить новый компонент (Samples).
Если нажать “OK”, то эксперт создаст
модуль - заготовку для нового компонента:
unit Unit1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes,
Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TMyButton = class(TButton)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TMyButton]);
end;
end.
Модуль содержит декларацию
нового класса и процедуру его регистрации в Палитре Компонент. В процедуре
RegisterComponents первый параметр
- имя страницы (можно указать свое имя - появится новая страница); второй
параметр - множество объектов для регистрации.
Теперь модуль нужно сохранить
под новым именем (например, NEW_BTN.PAS)
и приступить к дописыванию новых свойств и методов. После того, как эта
работа закончена и новый компонент отлажен, можно добавить его в Палитру
(см. предыдущую главу). Но перед этим желательно создать файл ресурсов,
в котором будет лежать пиктограмма для представления данного объекта в
Палитре Компонент. Файл ресурсов можно создать с помощью программы
Resource Workshop, называться он должен точно
так же, как модуль регистрации компонента и иметь расширение .DCR
(т.е., если объект регистрируется в модуле
NEW_BTN.PAS, то тогда имя файла ресурсов
будет NEW_BTN.DCR). В файле ресурсов
должен находиться ресурс типа BITMAP - картинка
размером 28x28 точки (можно меньше),
название картинки должно совпадать с именем класса (в нашем случае TMYBUTTON).
-
Соглашения по наименованиям
Если вы рассматривали исходные тексты VCL,
то могли видеть, что они следуют нескольким простым соглашениям при определении
новых классов. Delphi этого не требует,
имена методов, свойств и т.п. могут быть любыми, компилятору это безразлично.
Но если следовать этим соглашениям, то разработка новых компонентов и чтение
исходных текстов станет существенно проще.
Итак:
-
Все декларации типов начинаются
на букву T. Еще раз, Delphi
не требует этого, но это делает очевидным,
что "TEdit", например, есть определение
типа, а не переменная или поле класса.
-
Имена свойствам нужно давать
легко читаемые и информативные. Нужно помнить, что пользователь будет их
видеть в Инспекторе Объектов. И имя вроде "TextOrientation" много
удобнее, нежели "TxtOr". То же самое
относится к методам. Методы, доступные пользователю, должны иметь удобные
названия.
-
При создании свойств типа Event,
имя такого свойства должно начинаться с “On” (например,
OnClick, OnCreate и т.д.).
-
Имя метода для чтения свойства
должен начинаться со слова “Get”. Например,
метод GetStyle должен выполнять чтение
для свойства Style.
-
Имя метода для записи свойства
должен начинаться со слова “Set”. Например,
метод SetStyle должен выполнять запись
в свойство Style.
-
Внутреннее поле для хранения
данных свойства должно носить имя, начинающееся с буквы “F”. Например,
свойство Handle могло бы храниться
в поле FHandle.
Конечно же, есть исключения
из правил. Иногда бывает удобнее их нарушить, например, класс TTable
имеет свойства типа Event,
которые называются BeforePost, AfterPost и
т.п.
-
Выбор предка
Прежде, чем приступить к написанию
кода, нужно определиться, хотя бы приблизительно, что за компонент вы собираетесь
делать. Далее, исходя из его предполагаемых свойств, определите класс-предок.
В VCL имеется несколько базовых классов,
рекомендуемых для наследования:
-
TObject - Можно использовать
в качестве предка, если с этим компонентом не нужно работать во время дизайна.
Это может быть, например, класс, содержащий значения переменных среды (environment)
или класс для работы с INI файлами.
-
TComponent - Отправная
точка для многих невидимых компонент. Данный класс обладает встроенной
возможностью сохранять/считывать себя
в потоке во время дизайна.
-
TGraphicControl - Используйте
этот класс для создания видимых компонент, которым не нужен handle.
Такие компоненты рисуют прямо на своей поверхности и требуют мало ресурсов
Windows.
-
TWinControl - Базовый
класс для компонент, которые имеют окно. Данное окно имеет свой handle,
его используют при доступе к возможностям Windows через
API.
-
TCustomControl - Потомок
TWinControl, вводит понятие канвы (Canvas)
и метод Paint() для
лучшего контроля за прорисовкой компонента. Именно этот класс используется
в качестве базового для построения большинства видимых компонент, имеющих
оконный handle.
-
TXxxxx - Класс вроде
TEdit или TButton.
Используются с целью доопределения их свойств и методов или переопределения
значения свойств, принимаемых по умолчанию.
-
Пример создания компонента
Для примера создадим новый класс,
мутант TButton, в котором изменим значение
по умолчанию свойства ShowHint на True
и добавим новое свойство - счетчик нажатий
на кнопку. Заготовка модуля для создания нового компонента уже есть (см.
пункт Заготовка для нового компонента). Теперь исходный текст выглядит
так:
unit New_btn;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes,
Graphics,
Controls, Forms, Dialogs, StdCtrls;
type
TMyButton = class(TButton)
private
{ Private declarations }
FClickCount : Longint;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner : TComponent); override;
procedure Click; override;
property ClickCount : Longint read FClickCount
write
FClickCount;
published
{ Published declarations }
end;
procedure Register;
implementation
constructor TMyButton.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
ShowHint:=True;
FClickCount:=0;
end;
procedure TMyButton.Click;
begin
Inc(FClickCount);
inherited Click;
end;
procedure Register;
begin
RegisterComponents('Samples', [TMyButton]);
end;
end.
Для того, чтобы переопределить
начальное значение свойства при создании объекта, нужно переписать конструктор
Create, в котором и присвоить
этому свойству нужное значение (не забыв перед этим вызвать конструктор
предка).
Новое свойство для подсчета
нажатий на клавишу называется ClickCount. Его
внутреннее поле для сохранения значения - FClickCount
имеет тип Longint, емкости поля хватит
надолго.
-
Предыдущий урок Следующий урок
|