Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to assign values to several dynamiclay created TEdit's

5 views
Skip to first unread message

Oren Halvani

unread,
Jul 19, 2004, 9:24:27 AM7/19/04
to
hi dear builders,

a while ago Remy posted me a sample how to create 20 dynamic TEdit's..

my problem is that i've got a ComboBox, that gives the user the option
to "feed" the dynamicaly created TEdit's with several values...BUT how
do i access the TEdit's ?? Their names are created in the constructor..
and i need to access them from a TButton->OnClick(...) and here they
are unknown, so how is it possible?

can someone please help me on that..?


Oren

/***************************************************************/
std::vector<TEdit*> Edits; // global..

__fastcall Form1::Form1(TComponent* Owner) : TForm(Owner)
{
const int b = 20; const int width = 110; const int height = 21;

Edits.clear();
int anzahl = 20;

for(int x = 0; x < anzahl; ++x)
{
TEdit *LeftEdit = new TEdit(this);
LeftEdit->Parent = this;
LeftEdit->Name = "txtLeft" + IntToStr(x); // HERE i'm creating the names
(left Edit's)
//...
LeftEdit->SetBounds(4, b + (height*x) + 2, width, height);

TEdit *RightEdit = new TEdit(this);
RightEdit->Parent = this;
RightEdit->Name = "txtRight" + IntToStr(x); // HERE i'm creating the names
(right Edit's)
//...
RightEdit->SetBounds(6 + width, b + (height*x) + 2, width, height);
RightEdit->Tag = reinterpret_cast<int>(LeftEdit);
Edits.push_back(RightEdit);
}
}


// here i feed the TEdit's...


void __fastcall Form1::cmdInsert_SampleClick(TObject *Sender)
{
switch(Box_Sample->ItemIndex) //ComboBox
{
case 0:
txtLeft0->Text = "Ä"; txtRight0->Text = "&Auml;";
txtLeft1->Text = "Ö"; txtRight1->Text = "&Ouml;";
txtLeft2->Text = "Ü"; txtRight2->Text = "&Uuml;";
txtLeft3->Text = "ä"; txtRight3->Text = "&auml;";
txtLeft4->Text = "ö"; txtRight4->Text = "&ouml;";
txtLeft5->Text = "ü"; txtRight5->Text = "&uuml;";
txtLeft6->Text = "ß"; txtRight6->Text = "&szlig;";
break;

//...
}
}


Hans Galema

unread,
Jul 19, 2004, 10:06:04 AM7/19/04
to
Oren Halvani wrote:

> my problem is that i've got a ComboBox, that gives the user the option
> to "feed" the dynamicaly created TEdit's with several values...BUT how
> do i access the TEdit's ?? Their names are created in the constructor..
> and i need to access them from a TButton->OnClick(...) and here they
> are unknown, so how is it possible?

You pushed all your TEdit's in -which you forgot to mention-:

std::Vector<TEdit*> Edits;

So simply loop through Edits looking for the wanted Name.

Hans.

Remy Lebeau (TeamB)

unread,
Jul 19, 2004, 1:05:44 PM7/19/04
to

"Oren Halvani" <NoS...@fdtd.com> wrote in message
news:40fb...@newsgroups.borland.com...

> BUT how do i access the TEdit's ??

You need to pay more attention to the code samples I give you. I already
showed you how to access them.


Gambit


Oren Halvani

unread,
Jul 19, 2004, 1:31:48 PM7/19/04
to

"Remy Lebeau (TeamB)" <gambit47...@no.spam.yahoo.com>
schrieb im Newsbeitrag news:40fbff33$1...@newsgroups.borland.com...


OK, i could do it like that:

void ins(TEdit *one)
{
one->Text = "ä";
}

// But..

void __fastcall TfrmMulti_StringReplace::cmdInsert_SampleClick(TObject *Sender)
{
std::for_each(Edits.begin(), Edits.end(), ins); // I DO NOT NEED ALL
EDIT'S..only 7

//....
}

Oren

Tim Howard

unread,
Jul 19, 2004, 2:10:25 PM7/19/04
to
OK,

First off, you can just do a vector.at( someint ) and get just the one
you need.

Also, you might want to consider a map if you need to access certain
"random" TEdits. Like mapping an identifier that you make up like some
integer to keep track of them.

map< int, TEdit* > someMap;

Then when you put them in your map simliar to this

someMap[ 1 ] = thisTEdit;

You can always get back top that specific one.


Hope that helps..


cheers,


tim


p.s. using the overloaded index [] operator inserts a new item at that
position if it doesn't exist. If that's not the behavior you are
seeking, use find instead.

Remy Lebeau (TeamB)

unread,
Jul 19, 2004, 2:54:56 PM7/19/04
to

"Oren Halvani" <NoS...@fdtd.com> wrote in message
news:40fc...@newsgroups.borland.com...

> OK, i could do it like that:

That is not what I was referring to. I already showed you how to access
both Left and Right edits given a particular TEdit pointer. How you get
that pointer to begin with is up to you.

> std::for_each(Edits.begin(), Edits.end(), ins); // I DO
> NOT NEED ALL EDIT'S..only 7

Then you need to explain - IN DETAIL - exactly what you really want to do.


Gambit


Remy Lebeau (TeamB)

unread,
Jul 19, 2004, 2:58:55 PM7/19/04
to
"Tim Howard" <tim_N0SPAM_@netsimplex_NOSPAM_.com> wrote in message
news:40fc...@newsgroups.borland.com...

> First off, you can just do a vector.at( someint ) and


> get just the one you need.

Better to use the '[]' operator instead.

> map< int, TEdit* > someMap;

Since he is giving each TEdit a name, better to use AnsiString or
std::string instead of an int.

map< AnsiString, TEdit* > someMap;

> someMap[ 1 ] = thisTEdit;

someMap[ "txtRight" + IntToStr(x) ] = RightEdit;

Or:

someMap[ RightEdit->Name ] = RightEdit;


Gambit


Tim Howard

unread,
Jul 19, 2004, 3:22:35 PM7/19/04
to
It's Remy, "The Enforcer", coming to a theatre near you.. To kick your
ass that is.. :) j/k

tim

Oren Halvani

unread,
Jul 19, 2004, 7:21:41 PM7/19/04
to

"Remy Lebeau (TeamB)" <gambit47...@no.spam.yahoo.com>
schrieb im Newsbeitrag news:40fc18ca$1...@newsgroups.borland.com...

> > OK, i could do it like that:

> That is not what I was referring to. I already showed you how to access
> both Left and Right edits given a particular TEdit pointer. How you get
> that pointer to begin with is up to you.

but i cannot use pointers.. i need to access them by their names for example:

txtLeft7->Text = "seven"; txtRight7->Text = "seven";
txtLeft11->Text = "eleven"; txtRight11->Text = "eleven";
txtLeft4->Text = "four"; txtRight4->Text = "four";


> > std::for_each(Edits.begin(), Edits.end(), ins); // I DO
> > NOT NEED ALL EDIT'S..only 7

> Then you need to explain - IN DETAIL - exactly what you really want to do.

dear Remy,

i thought i've done this in the first post...anyway..i've got a ComboBox, that


gives
the user the option to "feed" the dynamicaly created TEdit's with several
values...

BUT how do i access the TEdit's ? Their names are created in the CONSTRUCTOR..
and i need to access them from a TButton->OnClick(...) Event..and of course here
they are unknown...the names that i'm creating here:

__fastcall Form1::Form1(TComponent* Owner) : TForm(Owner)
{
const int b = 20; const int width = 110; const int height = 21;

Edits.clear();
int anzahl = 20;

for(int x = 0; x < anzahl; ++x)
{
TEdit *LeftEdit = new TEdit(this);
LeftEdit->Parent = this;

LeftEdit->Name = "txtLeft" + IntToStr(x); // NOT GLOBAL...
//.....


are NOT global, so i cannot access them from Button1->Click(...)

i hope i've explained myself now better..


Oren


Remy Lebeau (TeamB)

unread,
Jul 19, 2004, 8:09:44 PM7/19/04
to

"Oren Halvani" <NoS...@fdtd.com> wrote in message
news:40fc...@newsgroups.borland.com...

> but i cannot use pointers..

Yes, you can. Simply look up the pointer that has the name you are looking
for. You need the pointer in order to actually update the Text. A pointer
is a pointer regardless of where you get it from.

> i need to access them by their names for example:

You are thinking of the auto-generated pointers that the IDE creates for
you. You are limiting your thinking too much.

Try this code:

std::vector<TEdit*> Edits;

TEdit* __fastcall FindEditByName(const AnsiString &Name)
{
std::vector<TEdit*>::iterator iter = Edits.begin();
while( iter != Edits.end() )
{
if( (*iter)->Name == Name )
return *iter;
}
return NULL;
}

void __fastcall UpdateEdits(int Number, const AnsiString &Left, const
AnsiString &Right)
{
TEdit *pEdit = FindEditByName("txtLeft" + IntToStr(Number));
if( pEdit )
{
reinterpret_cast<TEdit*>(pEdit->Tag) = Left;
pEdit->Text = Right;
}
}

__fastcall Form1::Form1(TComponent* Owner)
: TForm(Owner)
{
const int b = 20; const int width = 110; const int height = 21;

Edits.clear();
int anzahl = 20;

for(int x = 0; x < anzahl; ++x)
{
TEdit *LeftEdit = new TEdit(this);
LeftEdit->Parent = this;
LeftEdit->Name = "txtLeft" + IntToStr(x);

//...
LeftEdit->SetBounds(4, b + (height*x) + 2, width, height);

TEdit *RightEdit = new TEdit(this);
RightEdit->Parent = this;
RightEdit->Name = "txtRight" + IntToStr(x);

//...
RightEdit->SetBounds(6 + width, b + (height*x) + 2, width,
height);
RightEdit->Tag = reinterpret_cast<int>(LeftEdit);

Edits.push_back(RightEdit);
}
}


void __fastcall Form1::cmdInsert_SampleClick(TObject *Sender)
{
switch( Box_Sample->ItemIndex )

{
case 0:
UpdateEdits(0, "Ä", "&Auml;");
UpdateEdits(1, "Ö", "&Ouml;");
UpdateEdits(2, "Ü", "&Uuml;");
UpdateEdits(3, "ä", "&auml;");
UpdateEdits(4, "ö", "&ouml;");
UpdateEdits(5, "ü", "&uuml;");
UpdateEdits(6, "ß", "&szlig;");
break;
//...
}
}

Alternatively, since you are naming the Edits based on their indexes anyway,
you could just access those indexes directly without looking for the names
at all:

std::vector<TEdit*> Edits;

void __fastcall UpdateEdits(int Index, const AnsiString &Left, const
AnsiString &Right)
{
std::vector<TEdit*>::iterator = Edits.begin() + Index;
if( iter != Edits.end() )
{
TEdit *pEdit = *iter;
reinterpret_cast<TEdit*>(pEdit->Tag) = Left;
pEdit->Text = Right;
}
}

__fastcall Form1::Form1(TComponent* Owner)
: TForm(Owner)
{
const int b = 20; const int width = 110; const int height = 21;

Edits.clear();
int anzahl = 20;

for(int x = 0; x < anzahl; ++x)
{
TEdit *LeftEdit = new TEdit(this);
LeftEdit->Parent = this;

//...
LeftEdit->SetBounds(4, b + (height*x) + 2, width, height);

TEdit *RightEdit = new TEdit(this);
RightEdit->Parent = this;

//...
RightEdit->SetBounds(6 + width, b + (height*x) + 2, width,
height);
RightEdit->Tag = reinterpret_cast<int>(LeftEdit);

Edits.push_back(RightEdit);
}
}


void __fastcall Form1::cmdInsert_SampleClick(TObject *Sender)
{
switch( Box_Sample->ItemIndex )

{
case 0:
UpdateEdits(0, "Ä", "&Auml;");
UpdateEdits(1, "Ö", "&Ouml;");
UpdateEdits(2, "Ü", "&Uuml;");
UpdateEdits(3, "ä", "&auml;");
UpdateEdits(4, "ö", "&ouml;");
UpdateEdits(5, "ü", "&uuml;");
UpdateEdits(6, "ß", "&szlig;");
break;
//...
}
}

> i thought i've done this in the first post...

Not clear enough.

> anyway..i've got a ComboBox
<snip>

You just asked the exact same questions as your original message again. If
your original message had been clear enough the first time, I wouldn't have
asked you to clearify the issue.


Gambit


Corey Murtagh

unread,
Jul 19, 2004, 8:11:10 PM7/19/04
to
Oren Halvani wrote:

> "Remy Lebeau (TeamB)" <gambit47...@no.spam.yahoo.com>
> schrieb im Newsbeitrag news:40fc18ca$1...@newsgroups.borland.com...
>
>>>OK, i could do it like that:
>
>>That is not what I was referring to. I already showed you how to access
>>both Left and Right edits given a particular TEdit pointer. How you get
>>that pointer to begin with is up to you.
>
> but i cannot use pointers.. i need to access them by their names for example:
>
> txtLeft7->Text = "seven"; txtRight7->Text = "seven";
> txtLeft11->Text = "eleven"; txtRight11->Text = "eleven";
> txtLeft4->Text = "four"; txtRight4->Text = "four";

The names you've given the dynamically-created components are properties
of the objects, not object names. Object names are source code tokens
which are used to identify objects to the compiler. They aren't used by
the program at runtime, only during compile and debugging.

What you're trying to do is add new members to a class at runtime, which
is simply not possible with C++ or most other compiled languages. If
you're absolutely determined that you /have/ to be able to do this then
C++ is not the language for you.

To reiterate: YOU CAN NOT ADD MEMBERS TO A C++ CLASS AT RUNTIME.

Now that we've established that you can't do /exactly/ what you wanted,
here's a way to get close:

---- in Form1.h:
#include<vector>

class TForm1 : public TForm
{
__published:
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User Declarations
public:
__fastcall TForm1(TComponent* Owner);

std::vector<TEdit*> txtLeft;
std::vector<TEdit*> txtRight;
};

---- in Form1.cpp:


__fastcall Form1::Form1(TComponent* Owner) : TForm(Owner)
{

for (int x = 0; x < 20; ++x)
{
// setup left edit


TEdit* LeftEdit = new TEdit(this);

//...

// setup right edit


TEdit* RightEdit = new TEdit(this);

//...

// add to vectors
txtLeft.push_back(LeftEdit);
txtRight.push_back(RightEdit);
}
}

void __fastcall TForm1::Button1Click(TObject *Sender)


{
switch(Box_Sample->ItemIndex) //ComboBox
{
case 0:

txtLeft[0]->Text = "Ä"; txtRight[0]->Text = "&Auml;";
// ...
break;
}
}

As you can see, the difference between this and the code you posted
originally is simply that the edit numbers are used as indices into the
vector... so txtLeft0 becomes txtLeft[0].

This is a very small compromise, neh?

--
Corey Murtagh
The Electric Monk
"Quidquid latine dictum sit, altum viditur!"

tim_N...@netsimplex_nospam_.com

unread,
Jul 19, 2004, 3:38:03 PM7/19/04
to
This message was cancelled from within Mozilla.

Oren Halvani

unread,
Jul 20, 2004, 4:32:10 AM7/20/04
to
first thank you very, very much for your help Remy..

there was a little typo in your code:

void __fastcall UpdateEdits(int Number, const AnsiString &Left, const AnsiString
&Right)
{
TEdit *pEdit = FindEditByName("txtLeft" + IntToStr(Number));
if(pEdit)
{

reinterpret_cast<TEdit*>(pEdit->Tag) = Left; // Cannot convert 'const
System::AnsiString' to 'Stdctrls::TEdit *'.
pEdit->Text = Right;
}
}

i've changed it to this: reinterpret_cast<TEdit*>(pEdit->Tag) = pEdit;

but than the program freezed :-) any ideas...=?

Oren


Remy Lebeau (TeamB)

unread,
Jul 20, 2004, 2:42:31 PM7/20/04
to

"Oren Halvani" <NoS...@fdtd.com> wrote in message
news:40fc...@newsgroups.borland.com...

> there was a little typo in your code:

There were two typos:

> TEdit *pEdit = FindEditByName("txtLeft" + IntToStr(Number));

Should be:

TEdit *pEdit = FindEditByName("txtRight" + IntToStr(Number));

> reinterpret_cast<TEdit*>(pEdit->Tag) = Left;

Should be:

reinterpret_cast<TEdit*>(pEdit->Tag)->Text = Left;

> i've changed it to this: reinterpret_cast<TEdit*>(pEdit->Tag) = pEdit;

That is not correct. See above.


Gambit


Oren Halvani

unread,
Jul 20, 2004, 6:30:35 PM7/20/04
to
that does the job:

/******************************************************/
void __fastcall UpdateEdits(int Index, const AnsiString &Left, const AnsiString
&Right)
{
std::vector<TEdit*>::iterator iter = Edits.begin() + Index;
if(iter != Edits.end())
{
TEdit *pEdit = *iter;


reinterpret_cast<TEdit*>(pEdit->Tag)->Text = Left;

pEdit->Text = Right;
}
}
/******************************************************/

Remy ---> T.H.A.N.K.S !!!!!!!!!!!!!!!!!!!!!


0 new messages