Создание визуальных компонентов во время выполнения программы

Александр Геннадьевич Фенстер, fenster@fenster.name
Для студентов 2 курса ММФ НГУ (вводный курс по C++ Builder).

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

При создании различных программ (а особенно простых игр сложности типа «Сапёра») регулярно возникает желание создавать визуальные компоненты (кнопки, компоненты типа TImage и т. п.) на этапе выполнения программы. В частности, вы можете захотеть создать сто кнопок и присвоить им всем очень похожие обработчики события OnClick. Не нужно это делать вручную.

Рассмотрим пример создания и удаления кнопки во время выполнения программы. Кнопка — это объект типа TButton. Для её создания необходимо выделить память под новый объект такого типа и вызвать его конструктор, а затем присвоить нужные значения его свойствам. Делается это, например, так:

TButton *bt = new TButton(Form1);
bt->Parent = Form1;
bt->Caption = "Caption";
bt->Left = 100;
bt->Top = 80;
/* и так далее */

Аналогично можно создать массив кнопок любого размера.

Обработка событий для динамически созданных компонентов

Чтобы присвоить такой кнопке обработчик, необходимо создать в классе, описывающем форму, метод, удовлетворяющий всем требованиям на обработчик (т. е. принимающий нужные параметры). Если вы не хотите разбираться с тем, как добавляются новые методы в классы (хотя хорошо бы, чтобы разобрались), можно просто поместить на форму кнопку (например, Button1) и обычным образом создать метод Button1Click, после чего использовать его для своей кнопки:

bt->OnClick = Button1Click;

Любой обработчик события принимает параметром TObject* Sender. Этот параметр при вызове обработчика указывает на объект, с которым связано данное событие. Например, определение, какая кнопка была нажата, можно реализовать так:

void TForm1::Button1Click(TObject *Sender)
{
    TButton *bt = static_cast<TButton *>(Sender); // приведение типа
    ShowMessage("Нажата кнопка" + bt->Caption);
}

Кроме того, каждый компонент имеет свойство Tag, в котором можно хранить произвольное целое число. Его также очень удобно использовать для определения того, какой из компонентов вызвал данное событие.