How to create an array of buttons in Borland C ++ Builder and work with it?
Specific question
How to create an array of buttons in Borland C ++ Builder and work with it?
I am using Borland C ++ Builder 6 and Borland Developer Studio 2006 (Turbo C ++ 2006).
purpose
To work with a lot of buttons on a form, just using a for loop with an index, for example changing their title, size and position.
I know if I have a button named Button1
and inside the click event of that button, if I create another button (via TButton *Button2 = new TButton(Form1)
) I can assign Button1
to Button2
( Button2 = Button1
) and these I can just change the title Button1
with Button2->Caption
. So I would like to expand on it by assigning real component pointers to array elements so that they work with all of them with a loop for
.
Ok if someone found a way to add all buttons as an array in the form, better :)
Trying to
The following tests were run by placing the appropriate code in TForm1 :: Button1Click (), the button event on the form:
-
Test 1
- Description: Create an array directly
-
Code:
TButton Buttons[3];
-
Result: Compilation error:
> [C++ Error] Unit1.cpp(23): E2248 Cannot find default constructor > to initialize array element of type 'TButton'
- Comments:
- I've tested several variants of this test (for example,
TButton Buttons = new TButton[3]
working with a functioncalloc
, etc.), but they all point to the problem thatTButton
there is no no-argument constructor, i.e.TButton()
, but onlyTButton (TComponent *AOwner)
,TButton(void *ParentWindow)
andTButton(const TButton &)
; - Any way to use operator
new
with arguments for constructor prototypesTButton
for an array?
- I've tested several variants of this test (for example,
-
Test 2
- Description: Create a vector
-
Code: Also add
#include "vector.h"
to the block header ...vector<TButton> Buttons; Buttons[0].Caption="it is ok"; Buttons[1].Caption="mayday, mayday";
-
Result: Debugger exception on third line:
> Project Project1.exe raised exception class EAccessViolation > with message 'Acceess violation at address 401075B9 in module > 'vcl60.bpl'. Read of address 00000254'. Proccess stopped. Use > Step or Run to continue.
- Comments:
- Yes, I expected it to be raised, but I put it here for someone to tell how to allocate memory for more elements on this vector after creation as it
vector<TButton> Buttons(3);
doesn't work for the same reason as test1 failed :(
- Yes, I expected it to be raised, but I put it here for someone to tell how to allocate memory for more elements on this vector after creation as it
General question
How do I do this for any visual component?
source to share
All your attempts have failed for the same reason - you are trying to create an array / vector of actual object instances TButton
instead of an array / vector of pointer instances in TButton
.
To create a fixed-length array of pointer buttons :
TButton* Buttons[3];
...
Buttons[0] = Button1;
Buttons[1] = Button2;
Buttons[2] = Button3;
...
for(index = 0; index < 3; ++index)
{
TButton *Btn = Buttons[index];
// use Btn as needed...
}
To create a dynamic-length array of pointer buttons :
TButton** Buttons;
...
Buttons = new TButton*[3];
Buttons[0] = Button1;
Buttons[1] = Button2;
Buttons[2] = Button3;
...
for(index = 0; index < 3; ++index)
{
TButton *Btn = Buttons[index];
// use Btn as needed...
}
...
delete[] Buttons;
To create a pointers button vector :
std::vector<TButton*> Buttons;
...
Buttons.push_back(Button1);
Buttons.push_back(Button2);
Buttons.push_back(Button3);
...
for(index = 0; index < 3; ++index)
{
TButton *Btn = Buttons[index];
// use Btn as needed...
}
/*
Or:
for(std::vector<TButton*>::iterator iter = Buttons.begin(); iter != Buttons.end(); ++iter)
{
TButton *Btn = *iter;
// use Btn as needed...
}
*/
source to share
Wonderful Typedef + Pseudo Array = Solution
-
Wonderful Typedef:
-
After hours of searching, I saw
typedef
this stack overflow and google search network and thought why not:typedef TButton* TButtons;
-
Well this changes everything, because I can execute:
TButtons Buttons[3];
-
-
Pseudo Array:
-
The problem remained in how to allocate memory for the data stored in this array
Buttons[3]
, but knowing the 2nd paragraph of the "Purpose" section of my question, I thought: forget the new data, the data is there, point to there (this is how I call it to build pseudo-array, because I'm only creating an array of pointers to existing data):TButtons Buttons[3] = {Button1, Button2, Button3};
- Where
Button1
,Button2
andButton3
were already created when I placed them in the form normally (via my mouse).
-
Working example
- Create a new vcl / forms application project;
- Place the 3 buttons on the left in the figure below (
Button1
,Button2
,Button3
) to demonstrate this solution and one large button (Button4
) as shown below to perform an action; -
Paste the following code when you press the fourth button, the big (
Button4
);typedef TButton* TButtons; TButtons Buttons[3] = {Button1, Button2, Button3}; int index; for(index=0;index<3;index++) { Buttons[index]->Caption=(AnsiString)"teste "+index+" - "+(1+random(100)); Buttons[index]->Left=25+4*random(100); Buttons[index]->Top=25+4*random(100); }
- Perform "Shazam!" run and play with it ...
source to share