В этой статье мы рассмотрим как правильно создавать динамические компоненты в среде программирования делфи, а так же рассмотрим работу с ними.
Первое с чего мы начнем это создание динамического компонента запускаем Delphi (в моем случае это RAD Studio 10 Seattle) идем в пункт меню FIle > New > VCL Forms Application - Delphi.
В инспекторе объектов выбираем нашу форму Form1 переходим на вкладку Events и дважды щелкаем ЛКМ по полю возле OnCreate тем самым мы создадим слушатель событий при созданий формы.
В Uses подключаем модуль Vcl.StdCtrls в нем описана кнопка. Создаем глобальную переменную BTN в разделе Var с типом TButton.
Слушателе событий OnCreate формы в логических блоках begin end пишем:
// Создаём компонент
BTN := TButton.Create(Form1);
// Указываем родителя (в данном случае эту форму)
BTN.Parent := Form1;
// Задаём расположение кнопки
BTN.Top := 30; // с верху 30
BTN.Left := 30; // слева 30
// Устанавливаем надпись на кнопку
BTN.Caption := 'Кнопка';
// Даем имя кнопке
BTN.Name:='BTN';
// Устанавливаем размер кнопки
BTN.Width:=100; // ширина 100
BTN.Height:=30; // высота 30
Свойство Parent устанавливает родителя вашего компонента на нем он будет создан (при удалении родителя в нашем случае это Form1 ваш компонент будет удален). Свойство Name устанавливается обязательно (индивидуальное) иначе при повторном создании компонента ваше приложение выдаст ошибку компонент с таким именем уже существует.
Теперь запускаем нашу программу например нажатием клавиши F9 и смотрим, что у нас получилось.
А как же быть если нужно создать несколько одинаковых компонентов спросите вы? Можно конечно создавать эти компоненты прописывая одно и то же, но лучше зациклить это действие (ибо так уменьшится и оптимизируется код).
Создание динамических компонентов в цикле.
Добавим к нашему коду переменную BTN_NAME_INDEX которая будет отвечать за индивидуальное имя кнопок и так же добавим переменную btn_i, и btn_j они будут счетчиком для циклов, и добавим переменную rasstoyanie в ней будет храниться расстояние между кнопками. Все эти переменные типа integer.
Немного изменим наш код:
rasstoyanie:=5; // Устанавливаем расстояние между кнопками
BTN_NAME_INDEX:=1; // Устанавливаем значение для первой кнопки
for btn_i := 1 to 8 do // повторяем цикл 8 раз
begin
// Создаём компонент
BTN := TButton.Create(Form1);
// Указываем родителя (в данном случае эту форму)
BTN.Parent := Form1;
// Задаём расположение кнопки
BTN.Top := 30*btn_i+rasstoyanie-30; // с верху 30
BTN.Left := 30; // слева 30
// Устанавливаем надпись на кнопку
BTN.Caption := 'Кнопка';
// Даем имя кнопке
BTN.Name:='BTN'+IntToStr(BTN_NAME_INDEX);;
// Устанавливаем размер кнопки
BTN.Width:=100; // ширина 100
BTN.Height:=30; // высота 30
inc(BTN_NAME_INDEX); // прибавляем к переменной BTN_NAME_INDEX единицу
end;
Запускаем программу и смотрим что получилось
А что же делать если нам нужно расположить компоненты таблицей скажем так как выглядит игра пятнашки. Для этого нам нужно создать вложенный цикл для этого нам и понадобится переменная btn_j она будет считать количество кнопок по горизонтали, а btn_i считает количество кнопок по вертикали. Изменим еще немного наш код:
rasstoyanie:=5; // Устанавливаем расстояние между кнопками
BTN_NAME_INDEX:=1; // Устанавливаем значение для первой кнопки
for btn_i := 1 to 8 do // повторяем цикл 8 раз
begin
for btn_j:=1 to 3 do // повторим цикл горизонтали 3 раза
begin
// Создаём компонент
BTN := TButton.Create(Form1);
// Указываем родителя (в данном случае эту форму)
BTN.Parent := Form1;
// Задаём расположение кнопки
BTN.Top := 30*btn_i+rasstoyanie-30; // с верху 30
BTN.Left := 100*btn_j+rasstoyanie-100; // слева 100
// Устанавливаем надпись на кнопку
BTN.Caption := 'Кнопка';
// Даем имя кнопке
BTN.Name:='BTN'+IntToStr(BTN_NAME_INDEX);;
// Устанавливаем размер кнопки
BTN.Width:=100; // ширина 100
BTN.Height:=30; // высота 30
inc(BTN_NAME_INDEX); // прибавляем к переменной BTN_NAME_INDEX единицу
end;
end;
Запускаем нашу программу и смотрим что у нас получилось.
Кнопки появились. Все бы хорошо но вот не задача при нажатии на кнопки ничего не происходит, что же делать? Нужно создать слушатель событий.
Обработчик (слушатель) событий для динамических компонентов.
Для начала нужно создать обработчик событий в разделе private назовем его BTNClick с параметром Sender . Sender имеет тип TObject, и имеет значение объекта - источника событий, в обработчике которого он используется.
procedure BTNClick(Sender: TObject); //1 клик
Теперь напишем содержимое нашего обработчика то есть опишем инструкции которые он будет выполнять. например после
implementation
{$R *.dfm}
Пишем следующий код:
procedure TForm1.BTNClick(Sender: TObject);
begin
if (Sender is TButton) then // Если объект кнопка то
begin
ShowMessage('Кнопка нажата'); // Выводим сообщение на экран
end;
end;
Теперь нам осталось только добавить наш слушатель событий к создаваемому компоненту в нашем случае это кнопки. Для этого немного изменим наш код дописав в него.
BTN.OnClick := BTNClick; // подключаем обработчик
Запускаем программу и жмем на любую кнопку смотрим что получилось.
Все работает как нам нужно. Теперь нам надо как то обратиться к динамическим компонентам например узнать его имя. Это нужно для того что бы в дальнейшем можно было получить значение какого либо свойства компонента либо изменить какое то значение.
Получение значений свойств динамического компонента.
Для того что бы получить какое-либо значение свойства компонента нужно воспользоваться (Sender as TComponent).свойство компонента в моем случае это name. Изменим немного код нашего обработчика.
if (Sender is TButton) then // Если объект кнопка то
begin
ShowMessage('Кнопка '+ (Sender as TComponent).Name+' нажата'); // Выводим сообщение на экран
end;
Запускаем программу смотрим, что получилось.
При нажатии на любую кнопку выводится на экран ее имя. Теперь нам нужно изменить значение свойств динамических компонентов, а для этого нужно в начале найти есть ли такой компонент.
Поиск динамических компонентов.
Для поиска и работы с компонентами есть функция FindComponent в модуле Classes Немного изменим наш обработчик.
if (Sender is TButton) then // Если объект кнопка то
begin
//ShowMessage('Кнопка '+ (Sender as TComponent).Name+' нажата'); // Выводим сообщение на экран
if FindComponent('BTN11')<>nil then // если компонент BTN11 найден то
ShowMessage('Кнопка BTN11 найдена');
end;
Запускаем нажимаем на любую кнопку и смотрим что получилось.
Теперь заменим надпись на кнопке.
Изменение свойств динамического компонента.
Снова меняем наш обработчик событий добавим в него (FindComponent('BTN11') as TButton).Caption:='Кнопка 11';.
Запускаем жмем любую кнопку и смотрим что получилось.
Создавать и редактировать динамические компоненты мы научились но перед закрытием программы нужно их удалить дабы очистить память.
Удаление динамических компонентов.
Обычно динамические компоненты очищаются при закрытии основной формы но мы сделаем это при клике по форме. В инспекторе объекта выбираем форму переходим на вкладку Events и двойным щелчком возле OnClick создаем слушатель событий при нажатии на форму.
Пишем код
var
i:integer;
begin
for i:= 13 to Form1.ComponentCount-1 do
begin
Form1.Components[0].Free;
end;
Здесь мы удаляем с первого по тринадцатый компонент на форме в цикле.
Запускаем жмем на форму смотрим что получилось.
Дополнение.
Создание компонентов
procedure TForm1.Button1Click(Sender: TObject);
var
memo:Tmemo;
begin
memo := Tmemo.Create(form1);
with memo do
begin
parent:=form1;
text:='1232';
width:=150;
height:=300;
top:=300;
left:=30;
name:='memo';
end;
end;
Уничтожение компонента
Component.Free;
либо
FreeAndNil(Component);