Створення модуля компонента

Перед початком роботи по створенню нового компонента потрібно створити окремий каталог для модуля і інших файлів компонента. Після цього можна приступити до створення модуля компонента.
Для того щоб створити модуль компонента, необхідно з меню Component вибрати команду New Component і в поля діалогового вікна New Component (рис. 16.1) ввести інформацію про створюваний компоненті.

Рис. 16.1. Діалогове вікно New Component

Поле Ancestor type має містити базовий тип для створюваного компонента. Базовий тип компонента можна задати безпосереднім введенням імені типу або вибором зі спадного списку. Для компоненту, базовим компонентом є стандартний компонент Edit (поле введення-редагування). Тому базовим типом для типу розробляється компонента є тип TEdit.

У поле Class Name необхідно ввести ім’я класу компоненту, наприклад TNkEdit. Згадайте, що в Delphi імена типів повинні починатися буквою т.

 

У поле Palette Page потрібно ввести ім’я вкладки палітри компонентів, на яку після створення компонента буде додано його значок. Назва вкладки палітри компонентів можна вибрати зі списку. Якщо в поле Palette Page ввести ім’я ще не існуючої вкладки палітри компонентів, то безпосередньо перед додаванням компонента вкладка з вказаним ім’ям буде створена.
У поле Unit, file name знаходиться автоматично сформоване ім’я файлу модуля створюваного компонента. Delphi привласнює модулю компонента ім’я, яке збігається з ім’ям типу компонента, але без літери T. Натиснувши на кнопці з трьома крапками, можна вибрати каталог, в якому повинен бути збережений модуль компоненту.
Після натискання кнопки ОК  до поточного проекту додається сформований Delphi-модуль, який представляє собою заготовку (шаблон) модуля компонента. Текст цього модуля наведений у лістингу 16.1.

Лістинг 16.1. Шаблон модуля компонента

unit NkEdit; interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls;
type
TEdit1 = class (TEdit)

private
{ Private declarations}

protected
{ Protected declarations}

public
{ Public declarations}

published
{ Published declarations}

end;
procedure Register;

implementation
procedure Register;

begin
RegisterComponents ( 'Samples', [TNkEdit]);

end;
end.

В оголошенні нового класу вказано тільки тип батьківського класу. В розділ реалізації поміщена процедура Register, яка використовується під час установки створеного програмістом компонента на зазначену вкладку палітри компонентів Delphi для реєстрації нового класу.

У сформований Delphi оголошення класу нового компонента потрібно внести доповнення: оголосити властивість, поле даних цього властивості, функцію доступу до поля даних, процедуру установки значення поля даних, конструктор і деструктор. Якщо на деякі події компонент повинен реагувати не так, як базовий, то в оголошення класу потрібно помістити опис відповідних процедур обробки подій.
У лістингу 16.2 наведено текст модуля компонента NkEdit після внесення всіх необхідних змін.

Лістинг 16.2. Модуль компонента NkEdit

unit NkEdit;

interface
uses
Windows, Messages, SysUtils,

Classes, Graphics, Controls,

Forms, Dialogs, StdCtrls;

type
TNkEdit = Class (TEdit)

private
FNumb: single; // число, що знаходиться в полі редагування
// Це опис функції доступу
// і процедури установки поля FNumb
function GetNumb: single;
procedure SetNumb (value: single);

protected
procedure KeyPress (var Key: Char);

override;

public
published
constructor Create (AOwner: TComponent);

override; property Numb: single

// властивість компонента

read GetNumb write SetNumb;

end;
procedure Register;

implementation
// процедура реєстрації компонента
procedure Register;
begin
RegisterComponents ( 'Samples', [TNkEdit]);
end;
// конструктор компонента
constructor TNkEdit.Create (AOwner: TComponent);
begin
// do not forget to call the ancestors 'constructor
inherited Create (AOwner);

end;
// функція доступу до поля FNumb

function TNkEdit.GetNumb: single;

begin
try // поле Text може бути порожнім Result: = StrToFloat (text); except
on EConvertError do begin
Result: = 0; text: = '';

end;

end;

end;
// процедура запису в поле FNumb

procedure TNkEdit.SetNumb (Value: single);

begin
FNumb: = Value;
Text: = FloatToStr (value);

end;
// процедура обробки події KeyPress

procedure TNkEdit.KeyPress (var key: char) ;

begin
case key of
'0' .. '9', # 8, # 13:;
'-': if Length (text) <> 0 then key: = # 0;
else
if not ((key = DecimalSeparator) and
(Pos (DecimalSeparator, text) = 0))

then key: = # 0;

end;
inherited KeyPress (key);

// виклик процедури обробки події
// OnKeyPress батьківського класу
end;

end.

В опис класу TNkEdit додано оголошення властивості Numb, яке представляє собою число, яке перебуває в поле редагування. Для зберігання Значення властивості Numb використовується поле FNumb. Функція GetNumb необхідна для доступу до поля FNumb, а процедура setNumb – для установки значення властивості.
Конструктор класу TNkEdit спочатку викликає конструктор батьківського класу (TEdit), присвоює значення властивості Text, потім встановлює значення властивості Numb.

Реакція компонента NkEdit на натискання клавіші клавіатури визначається процедурою обробки події TNkEdit.KeyPress, яка заміщає відповідну процедуру базового класу. Як параметр процедура TNkEdit.KeyPress отримує код натиснутої клавіші. Перед викликом процедури обробки події OnKeyPress батьківського класу код натиснутоюклавіші перевіряється на допустимість. Якщо натиснута неприпустима для компонента NkEdit клавіша, то код символу замінюється на нуль. Допустимими для компонента NkEdit є цифрові клавіші, роздільник цілої і дробової частин числа (в Залежно від настройки Windows: крапка чи кома), “мінус”, “Backspase “ (Дозволяє видалити помилково введений символ) і “Enter”.

Тут слід згадати, що в тексті програми дробова частина числової константи відокремлюється від цілої крапкою. Під час роботи програми при вводі вихідних даних користувач повинен використовувати той символ, який заданий в налаштуванні Windows. В якості роздільник зазвичай застосовують кому (це для Росії стандартна настройка) або точку. Наведена процедура обробки події OnKeyPress враховує, що настройка Windows може змінюватися, і тому самі ввели символ порівнюється ні з константою, а зі значенням глобальної змінної DecimalSeparator, яка містить символ-роздільник, використовуваний в Windows в даний момент.
Після введення тексту модуля компонента модуль потрібно відкомпілювати і зберегти.