Discussion:
array of controls
(too old to reply)
didan
2008-02-06 15:03:28 UTC
Permalink
I need to create a variable amount of buttons at runtime. I don't know what's the best way to do it. I'm thinking about to create an array of controls so that I can create them by loop the array. I even don't know if there is a way to create a control array at design time.
Can you help? Thanks in advance
Asger Joergensen
2008-02-06 16:36:15 UTC
Permalink
Hi didan
Post by didan
I need to create a variable amount of buttons at runtime. I don't know what's the best way to do it. I'm thinking about to create an array of controls so that I can create them by loop the array. I even don't know if there is a way to create a control array at design time.
Can you help? Thanks in advance
typedef std::vector<TButton*> ButtenVector;

ButtenVector ButtenVec;

void __fastcall createButtons(int Count, TWinControl* Parent, int Left, int Top,
int Width, int Height, int Space, bool Vertical, TNotifyEvent Event)
{
for(int i = 0; i < Count; ++i)
{
TButton* NewButton = new TButton(Parent);
if(Vertical)
NewButton->SetBounds(Left, Top + i * (Space + Height), Width, Height);
else
NewButton->SetBounds(Left + i * (Space + Width), Top, Width, Height);
NewButton->Parent = Parent;
NewButton->Caption = "Button" + String(i);
NewButton->OnClick = Event;
ButtenVec.push_back(NewButton);
}
}

void __fastcall hideButtons()
{
int C = ButtenVec.size();
for(int i = 0; i < C; ++i)
ButtenVec[i]->Hide();
}

p.s. Please break Your text lines.

Kind regards
Asger
Asger Joergensen
2008-02-06 16:37:49 UTC
Permalink
Hi Asger

remember to include the vector

#include <vector>

Kind regards
Asger
didan
2008-02-06 18:56:42 UTC
Permalink
Thanks Asger!!!
Do you know how can i loop all the buttons on a form which are
created at design-time? Or I have to create these buttons in a certain way to do the loop?
Asger Joergensen
2008-02-07 07:25:51 UTC
Permalink
Hi didan
Post by didan
Thanks Asger!!!
Do you know how can i loop all the buttons on a form which are
created at design-time? Or I have to create these buttons in a certain way to do the loop?
void __fastcall ChangeButtonTextColor(TWinControl* Ctrl, TColor Cl)
{
int C = Ctrl->ControlCount;

for (int i = 0; i < C; ++i)
{
TButton *Button = dynamic_cast<TButton*>(Ctrl->Controls[i]);
if(Button)
Button->Font->Color = Cl;
}
}

TWinControl* Ctrl can be the Form, ScrollBox, Panel or anything that
can be a parent for other controls

There is also ComponentCount and a Components[int Index]

Kind regards
Asger

Clayton Arends
2008-02-06 19:00:57 UTC
Permalink
Asger pointed out the C++ way of doing things using the Standard Template
Library (STL). It is a perfectly valid example -- though, I didn't
scrutinize it ;-).

If you want to do things the VCL way then instead of using the vector
template you can use the generic TList type to store your buttons. The
problem with this approach is that TList stores void* objects and you must
explicitly cast your results. Other than that the algorithm is basically
the same:

// In class declaration (preferably with private visibility)
TList* Buttons;

// in class constructor
Buttons = new TList;

// in class destructor
delete Buttons; // TList doesn't own its children

// when creating the button
TButton* button = new TButton(owner); // owner can be the form or other
Buttons->Add(button);

// To access an element of the list (note the cast)
TButton* button = static_cast <TButton*> (Buttons->Items[index]);

The benefit of using the VCL way in a VCL application is that TList is
compiled in once. The STL way requires that code get injected for each new
type. For many types of lists this can result in code-bloated applications.

The benefit of the STL way is that it is strongly typed and any changes in
type will be pointed out by the compiler. Personally, in my VCL
applications I use a templated descendant of TList to enforce type use but
that's beyond the scope of this post.

HTH,
Clayton
Loading...