Miałem ten sam pomysł, jednak chcę go bardziej rozwinąć:
plik nagłówkowy np. Unit1.h#include <vector>
// ..............
private:
std::vector<TLabel *> LabelList;
plik źródłowy np. Unit1.cpp
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int x = 1;
do
{
LabelList.push_back( new TLabel(this) ) ;
std::vector<TLabel *>::iterator itLabel = LabelList.begin() + (x - 1);
String lName = "Label" + (String)x;
(*itLabel)->Name = lName;
TLabel *tmpLabel = dynamic_cast<TLabel *>( FindComponent(lName) );
tmpLabel->Parent = this;
tmpLabel->Left = 8;
tmpLabel->Top = 16 * x;
x++;
}while(x < 5);
}
Teraz pozostaje kwestia podłączenia zdarzeń do tych obiektów. Podłączę jedno zdarzenie OnClick do wszystkich obiektów, ale kliknięcie na jeden z nich wyświetli komunikat o tym, który obiekt został kliknięty. Dla urozmaicenia zdarzenie będzie podłączane do obiektów nie podczas ich tworzenia, ale po kliknięciu na drugi przycisk. Wcześniej jednak trzeba utworzyć funkcję, która będzie zdarzeniem.plik nagłówkowy np. Unit1.hprivate:
std::vector<TLabel *> LabelList;
void __fastcall LabelListClick(TObject *Sender);
plik źródłowy np. Unit1.cpp
void __fastcall TForm1::LabelListClick(TObject *Sender)
{
String lName = dynamic_cast<TLabel *>(Sender)->Name;
ShowMessage("Kliknięto w obiekt: '" + lName + "'.");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
std::vector<TLabel *>::iterator itLabel = LabelList.begin();
for(; itLabel < LabelList.end(); itLabel++)
{
TLabel *tmpLabel = dynamic_cast<TLabel *>((*itLabel));
tmpLabel->OnClick = LabelListClick;
}
}
//---------------------------------------------------------------------------
Trochę tutaj namieszałem, gdyż tworząc obiekty typu
TLabel odwoływałem się do nich poprzez nazwę, którą wcześniej przypisałem do
iteratora:
String lName = "Label" + (String)x;
(*itLabel)->Name = lName;
TLabel *tmpLabel = dynamic_cast<TLabel *>( FindComponent(lName) );
tmpLabel->Parent = this;
a przypisując im zdarzenie użyłem
iteratora:
TLabel *tmpLabel = dynamic_cast<TLabel *>((*itLabel));
By nie powtarzać kodu posłużyłem się dodatkowo rzutowaniem na tmpLabel. W pierwszym przypadku mogłem równie dobrze zamiast nazwy użyć iteratora, co więcej można im od razu przypisać zdarzenie:
int x = 1;
do
{
LabelList.push_back( new TLabel(this) ) ;
std::vector<TLabel *>::iterator itLabel = LabelList.begin() + (x - 1);
String lName = "Label" + (String)x;
// (*itLabel)->Name = lName;
TLabel *tmpLabel = dynamic_cast<TLabel *>( (*itLabel) );//( FindComponent(lName) );
tmpLabel->Name = lName;
tmpLabel->OnClick = LabelListClick;
tmpLabel->Parent = this;
tmpLabel->Left = 8;
tmpLabel->Top = 16 * x;
x++;
}while(x < 5);
Można też zrezygnować z rzutowania na tmpLabel i posłużyć się iteratorem:
int x = 1;
do
{
LabelList.push_back( new TLabel(this) ) ;
std::vector<TLabel *>::iterator itLabel = LabelList.begin() + (x - 1);
String lName = "Label" + (String)x;
(*itLabel)->Name = lName;
(*itLabel)->OnClick = LabelListClick;
(*itLabel)->Parent = this;
(*itLabel)->Left = 8;
(*itLabel)->Top = 16 * x;
x++;
}while(x < 5);
Pozostaje jeszcze kwestia niszczenia obiektów i czyszczenia tablicy:
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
std::vector<TLabel *>::iterator itLabel = LabelList.begin();
for(; itLabel < LabelList.end(); itLabel++) delete *itLabel;
// na koniec czyszczę listę
LabelList.clear();
}