 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
dkat Guest
|
Posted: Thu Apr 29, 2004 3:12 pm Post subject: Can you have arrays of BoxLists or other components? |
|
|
I'm really a old style C programmer. While I use Builder, C++, etc. I do
not have a mindset for that code writing.
In C programming if I wanted to do a identical code that used the same logic
but different variables I would simply make the variables arrays and then do
a for loop, while, or do to repeat the same calculations for each item of
the array. I have created a program that uses mulitiple list boxes and edit
boxes but they all are treated in somewhat the same way.
Simplified
I have a list box from which you choose an ingredient
I have an edit box next to it that you type in the amount in weight of the
material
When the amount changes the next ingredient box is made visible
There is a total box for the total weight of materials
This displays the total but if you type in a new total the individual
weights are changed to the proportions that match the total.
In C I would have put this in a loop but that is not possible with the
components not array items. So the question is - IS there any way to make
components be arrays items? So rather than G1Wt1 G1Wt2 (TEdit components),
etc. could I have G1Wt[14]? If so, does it mean that they have to be
created in programming rather than using the Builder Component add to form
Palette?
////////////////////////////////////Sample of Code as
is////////////////////////////////////////////////
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
if(total1)
PercentT1 = total1/ G1Total->Text.ToDouble();
else return;
if(G1Wt2->Visible==true)
{
G1Amt[0] = G1Amt[0]/PercentT1;
G1Wt1->Text=FloatToStr(G1Amt[0]);
if(G1Wt3->Visible==false)return;;
G1Amt[1] = G1Amt[1]/PercentT1;
G1Wt2->Text=FloatToStr(G1Amt[1]);
if(G1Wt4->Visible==false)return;;
G1Amt[2] = G1Amt[2]/PercentT1;
G1Wt3->Text=FloatToStr(G1Amt[2]);
if(G1Wt5->Visible==false)return;;
G1Amt[3] = G1Amt[3]/PercentT1;
G1Wt4->Text=FloatToStr(G1Amt[3]);
if(G1Wt6->Visible==false)return;;
G1Amt[4] = G1Amt[4]/PercentT1;
G1Wt5->Text=FloatToStr(G1Amt[4]);
if(G1Wt7->Visible==false)return;;
G1Amt[5] = G1Amt[5]/PercentT1;
G1Wt6->Text=FloatToStr(G1Amt[5]);
if(G1Wt8->Visible==false)return;;
G1Amt[6] = G1Amt[6]/PercentT1;
G1Wt7->Text=FloatToStr(G1Amt[6]);
if(G1Wt9->Visible==false)return;;
G1Amt[7] = G1Amt[7]/PercentT1;
G1Wt8->Text=FloatToStr(G1Amt[7]);
if(G1Wt10->Visible==false)return;;
G1Amt[8] = G1Amt[8]/PercentT1;
G1Wt9->Text=FloatToStr(G1Amt[8]);
if(G1Wt11->Visible==false)return;;
G1Amt[9] = G1Amt[9]/PercentT1;
G1Wt10->Text=FloatToStr(G1Amt[9]);
if(G1Wt12->Visible==false)return;;
G1Amt[10] = G1Amt[10]/PercentT1;
G1Wt11->Text=FloatToStr(G1Amt[10]);
if(G1Wt13->Visible==false)return;;
G1Amt[11] = G1Amt[11]/PercentT1;
G1Wt12->Text=FloatToStr(G1Amt[11]);
if(G1Wt14->Visible==false)return;;
G1Amt[12] = G1Amt[12]/PercentT1;
G1Wt13->Text=FloatToStr(G1Amt[12]);
if(G1Wt14Changed==false)return;;
G1Amt[13] = G1Amt[13]/PercentT1;
G1Wt14->Text=FloatToStr(G1Amt[13]);
}
//assign compound %
}
|
|
| Back to top |
|
 |
Chris Uzdavinis (TeamB) Guest
|
Posted: Thu Apr 29, 2004 3:24 pm Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
"dkat" <dkat (AT) hotmail (DOT) com> writes:
| Quote: | In C I would have put this in a loop but that is not possible with
the components not array items. So the question is - IS there any
way to make components be arrays items? So rather than G1Wt1 G1Wt2
(TEdit components), etc. could I have G1Wt[14]? If so, does it
mean that they have to be created in programming rather than using
the Builder Component add to form Palette?
|
You can put component pointers into an array, and then use the array
as you are describing. This won't happen automatically though, you
must build it yourself.
There are other ways too, but for keeping with the C idiom you are
wanting, this sounds like a reasonable solution. Main drawaback is
whenever you add a component, you must remember to manually add it
into your code that populates the array.
--
Chris (TeamB);
|
|
| Back to top |
|
 |
dkat Guest
|
Posted: Thu Apr 29, 2004 4:06 pm Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
"Chris Uzdavinis (TeamB)" <chris (AT) uzdavinis (DOT) com> wrote
| Quote: | "dkat" <dkat (AT) hotmail (DOT) com> writes:
In C I would have put this in a loop but that is not possible with
the components not array items. So the question is - IS there any
way to make components be arrays items? So rather than G1Wt1 G1Wt2
(TEdit components), etc. could I have G1Wt[14]? If so, does it
mean that they have to be created in programming rather than using
the Builder Component add to form Palette?
You can put component pointers into an array, and then use the array
as you are describing. This won't happen automatically though, you
must build it yourself.
There are other ways too, but for keeping with the C idiom you are
wanting, this sounds like a reasonable solution. Main drawaback is
whenever you add a component, you must remember to manually add it
into your code that populates the array.
--
Chris (TeamB);
|
I think I'm "happy" to hear that... Adding a component from the palette is
easy. I'm not sure where to begin on hand creating one... I guess it is
time to bite the bullet and just try though.....
|
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Thu Apr 29, 2004 4:38 pm Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
dkat wrote:
| Quote: | I think I'm "happy" to hear that... Adding a component from the palette is
easy. I'm not sure where to begin on hand creating one... I guess it is
time to bite the bullet and just try though.....
|
Of course you can use an array. But you don't need to.
Start to use the Tag property of the used TEdits.
Make Tag the same value as the index: So Edit5 gets a 5 for the Tag property.
The following function will return a pointer
to the TEdit with the rigth tag.
TEdit *__fastcall TForm2::GetTEdit ( int tag )
{
int count = -1;
while ( ++count < ComponentCount )
{
TEdit *Edit = dynamic_cast
if ( Edit && Edit->Tag == tag )
return Edit;
}
return NULL;
}
To demomstrate the use try:
void __fastcall TForm2::Button1Click(TObject *Sender)
{
TEdit *Edit = GetTEdit ( 3 );
if ( Edit )
ShowMessage ( Edit->Text );
}
And in a loop try:
void __fastcall TForm2::Button2Click(TObject *Sender)
{
int nr = 0;
while ( ++nr < 10 )
{
TEdit *Edit = GetTEdit ( nr );
if ( Edit )
ShowMessage ( Edit->Text );
}
}
Hans.
|
|
| Back to top |
|
 |
dkat Guest
|
Posted: Thu Apr 29, 2004 8:21 pm Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
--
/*****************************************/
Listen to
www.airamericaradio.com
/*****************************************/
"Hans Galema" <dontusethis (AT) dontusethis (DOT) nl> wrote
| Quote: | dkat wrote:
I think I'm "happy" to hear that... Adding a component from the palette
is
easy. I'm not sure where to begin on hand creating one... I guess it is
time to bite the bullet and just try though.....
Of course you can use an array. But you don't need to.
Start to use the Tag property of the used TEdits.
Make Tag the same value as the index: So Edit5 gets a 5 for the Tag
property.
The following function will return a pointer
to the TEdit with the rigth tag.
TEdit *__fastcall TForm2::GetTEdit ( int tag )
{
int count = -1;
while ( ++count < ComponentCount )
{
TEdit *Edit = dynamic_cast
if ( Edit && Edit->Tag == tag )
return Edit;
}
return NULL;
}
To demomstrate the use try:
void __fastcall TForm2::Button1Click(TObject *Sender)
{
TEdit *Edit = GetTEdit ( 3 );
if ( Edit )
ShowMessage ( Edit->Text );
}
And in a loop try:
void __fastcall TForm2::Button2Click(TObject *Sender)
{
int nr = 0;
while ( ++nr < 10 )
{
TEdit *Edit = GetTEdit ( nr );
if ( Edit )
ShowMessage ( Edit->Text );
}
}
Hans.
|
If I understand you correctly, I would then change the many lines of code
to
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
TEdit * Edit;
int tagcount = 1
while (tagcount<14)
{
Edit = GetTEdit(tagcount+1);
if(Edit->Visible==false)return;
Edit=GetTEdit(tagcount);
G1Amt[tagcount-1] = G1Amt[tagcount-1]/PercentT1;
Edit->Text=FloatToStr(G1Amt[tagcount-1]);
tagcount++;
}
}
That is really nice if I can get it to work. So far it is giving me an
EAccessViolation.... I hope to get it working because this would make the
code much closer to what it should be. Thank you. DKat
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
if(G1Wt2->Visible==true)
{
G1Amt[0] = G1Amt[0]/PercentT1;
G1Wt1->Text=FloatToStr(G1Amt[0]);
if(G1Wt3->Visible==false)return;;
G1Amt[1] = G1Amt[1]/PercentT1;
G1Wt2->Text=FloatToStr(G1Amt[1]);
if(G1Wt4->Visible==false)return;;
G1Amt[2] = G1Amt[2]/PercentT1;
G1Wt3->Text=FloatToStr(G1Amt[2]);
if(G1Wt5->Visible==false)return;;
G1Amt[3] = G1Amt[3]/PercentT1;
G1Wt4->Text=FloatToStr(G1Amt[3]);
if(G1Wt6->Visible==false)return;;
G1Amt[4] = G1Amt[4]/PercentT1;
G1Wt5->Text=FloatToStr(G1Amt[4]);
if(G1Wt7->Visible==false)return;;
G1Amt[5] = G1Amt[5]/PercentT1;
G1Wt6->Text=FloatToStr(G1Amt[5]);
if(G1Wt8->Visible==false)return;;
G1Amt[6] = G1Amt[6]/PercentT1;
G1Wt7->Text=FloatToStr(G1Amt[6]);
if(G1Wt9->Visible==false)return;;
G1Amt[7] = G1Amt[7]/PercentT1;
G1Wt8->Text=FloatToStr(G1Amt[7]);
if(G1Wt10->Visible==false)return;;
G1Amt[8] = G1Amt[8]/PercentT1;
G1Wt9->Text=FloatToStr(G1Amt[8]);
if(G1Wt11->Visible==false)return;;
G1Amt[9] = G1Amt[9]/PercentT1;
G1Wt10->Text=FloatToStr(G1Amt[9]);
if(G1Wt12->Visible==false)return;;
G1Amt[10] = G1Amt[10]/PercentT1;
G1Wt11->Text=FloatToStr(G1Amt[10]);
if(G1Wt13->Visible==false)return;;
G1Amt[11] = G1Amt[11]/PercentT1;
G1Wt12->Text=FloatToStr(G1Amt[11]);
if(G1Wt14->Visible==false)return;;
G1Amt[12] = G1Amt[12]/PercentT1;
G1Wt13->Text=FloatToStr(G1Amt[12]);
if(G1Wt14Changed==false)return;;
G1Amt[13] = G1Amt[13]/PercentT1;
G1Wt14->Text=FloatToStr(G1Amt[13]);
}
PercentT1 = total1/ G1Total->Text.ToDouble();
else return;
if(G1Wt2->Visible==true)
{
G1Amt[0] = G1Amt[0]/PercentT1;
G1Wt1->Text=FloatToStr(G1Amt[0]);
if(G1Wt3->Visible==false)return;;
G1Amt[1] = G1Amt[1]/PercentT1;
G1Wt2->Text=FloatToStr(G1Amt[1]);
if(G1Wt4->Visible==false)return;;
G1Amt[2] = G1Amt[2]/PercentT1;
G1Wt3->Text=FloatToStr(G1Amt[2]);
if(G1Wt5->Visible==false)return;;
G1Amt[3] = G1Amt[3]/PercentT1;
G1Wt4->Text=FloatToStr(G1Amt[3]);
if(G1Wt6->Visible==false)return;;
G1Amt[4] = G1Amt[4]/PercentT1;
G1Wt5->Text=FloatToStr(G1Amt[4]);
if(G1Wt7->Visible==false)return;;
G1Amt[5] = G1Amt[5]/PercentT1;
G1Wt6->Text=FloatToStr(G1Amt[5]);
if(G1Wt8->Visible==false)return;;
G1Amt[6] = G1Amt[6]/PercentT1;
G1Wt7->Text=FloatToStr(G1Amt[6]);
if(G1Wt9->Visible==false)return;;
G1Amt[7] = G1Amt[7]/PercentT1;
G1Wt8->Text=FloatToStr(G1Amt[7]);
if(G1Wt10->Visible==false)return;;
G1Amt[8] = G1Amt[8]/PercentT1;
G1Wt9->Text=FloatToStr(G1Amt[8]);
if(G1Wt11->Visible==false)return;;
G1Amt[9] = G1Amt[9]/PercentT1;
G1Wt10->Text=FloatToStr(G1Amt[9]);
if(G1Wt12->Visible==false)return;;
G1Amt[10] = G1Amt[10]/PercentT1;
G1Wt11->Text=FloatToStr(G1Amt[10]);
if(G1Wt13->Visible==false)return;;
G1Amt[11] = G1Amt[11]/PercentT1;
G1Wt12->Text=FloatToStr(G1Amt[11]);
if(G1Wt14->Visible==false)return;;
G1Amt[12] = G1Amt[12]/PercentT1;
G1Wt13->Text=FloatToStr(G1Amt[12]);
if(G1Wt14Changed==false)return;;
G1Amt[13] = G1Amt[13]/PercentT1;
G1Wt14->Text=FloatToStr(G1Amt[13]);
}
|
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Thu Apr 29, 2004 8:51 pm Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
dkat wrote:
He started with a "--", thereby making it impossible
to reply with quotes.
Then he included all of my post, which was not needed,
and annoying. Why do you let me scroll down so much ?
<reply>
If I understand you correctly, I would then change the many lines of code
to
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
TEdit * Edit;
int tagcount = 1
while (tagcount<14)
{
Edit = GetTEdit(tagcount+1);
if(Edit->Visible==false)return;
Edit=GetTEdit(tagcount);
G1Amt[tagcount-1] = G1Amt[tagcount-1]/PercentT1;
Edit->Text=FloatToStr(G1Amt[tagcount-1]);
tagcount++;
}
}
That is really nice if I can get it to work. So far it is giving me an
EAccessViolation.... I hope to get it working because this would make the
code much closer to what it should be. Thank you. DKat
</reply>
You should always go as far that you exactly can tell on which line
the EAccessViolation comes. Well you omitted some checks that I had
shown you. Be prepared that GetTEdit can return a NULL if the
requested tagnumber does not exist. So ALWAYS check;
Better code:
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
TEdit * Edit;
int tagcount = 1
while (tagcount<14)
{
Edit = GetTEdit(tagcount+1); // You start with Tag == 2 ?
if ( Edit )
{
if(Edit->Visible==false)return;
Edit=GetTEdit(tagcount);
if ( Edit )
{
G1Amt[tagcount-1] = G1Amt[tagcount-1]/PercentT1;
Edit->Text=FloatToStr(G1Amt[tagcount-1]);
}
}
tagcount++;
}
Remark: I see that you use:
if(Edit->Visible==false)return;
commonly used is:
if ( ! Edit->Visible ) return;
And then followed already know code again. Why ?
Please trim quotes.
Hans.
|
|
| Back to top |
|
 |
dkat Guest
|
Posted: Fri Apr 30, 2004 3:01 am Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
"Hans Galema" <dontusethis (AT) dontusethis (DOT) nl> wrote
| Quote: | dkat wrote:
He started with a "--", thereby making it impossible
to reply with quotes.
sorry - accident - signature |
finally figured out what the code does and it all now works. again, thank
you. as i said i really like this. i still want to figure out how to make
arrays of components (that is not working) but i feel really pleased to have
found this. thank you
TEdit *__fastcall TMainForm::GetTEdit ( int tag )
{
int count = 0;
TEdit *Edit;
while ( ++count < ComponentCount )
{
Edit = dynamic_cast
if (Edit && Edit->Tag == tag )
return Edit;
}
return NULL;
}
//--------------------------------------------------------------------------
-
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
int nr = 0;
T1Percent = total1/G1Total->Text.ToDouble();
while ( ++nr < G1Count )
{
TEdit *Edit = GetTEdit ( nr );
if ( Edit )
{
G1Wt[nr] = G1Wt[nr]/T1Percent;
Edit->Text=FloatToStr(G1Wt[nr]);
}
}
}
|
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Fri Apr 30, 2004 8:34 am Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
dkat wrote:
| Quote: | ... i still want to figure out how to make
arrays of components (that is not working)
|
An array of pointers, an array of components, an array of
pointers to components ? Oh, its all the same.
The Components array of TForm, used in GetTedit() is
already such an array.
Two possibilities:
1. You make the TEdit's at designtime.
Just to exercise, take a new TForm and place
a TPanel on it, On the TPanel four TEdits.
Leave all names. Place two TButton's.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// There are four TEdits (Edit1,Edit2,Edit3,Edit4)
// placed on a Panel1 first
if ( Edits ) return; // private: TEdit **Edits;
maxtedits = 4; // private: int maxtedits;
Edits = new TEdit* [maxtedits + 1];
Edits[0] = NULL; // there is no Edit0
Edits[1] = Edit1;
Edits[2] = Edit2;
Edits[3] = Edit3;
Edits[4] = Edit4;
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if ( ! Edits ) return; // private: TEdit **Edits;
int nr = 0;
while ( ++nr <= maxtedits )
ShowMessage ( Edits[nr]->Text );
}
Hee, we did not use the panel. Maybe with method 2 ?
Dont forget to delete [] Edits; when you delete the form.
1. You create the TEdits at runtime.
We leave that first.
| Quote: | TEdit *__fastcall TMainForm::GetTEdit ( int tag )
{
int count = 0;
TEdit *Edit;
while ( ++count < ComponentCount )
{
Edit = dynamic_cast
|
You changed that function in two ways. What I had posted was:
int count = -1;
while ( ++count < ComponentCount )
{
TEdit *Edit = dynamic_cast
First, count should really be initialised with -1, as 0 is the
index of the first possible Component.
Further, you placed the declaration of Edit at the beginning
of the function. That makes code difficult to read. Just
introduce a variable where you really need it. If the while had
come much later in the function, then the reader could not see
what the type of Edit was at it's first use. It is also
only needed inside the while loop. So why place it outside ?
Or is that your C style ?
| Quote: | TEdit *Edit = GetTEdit ( nr );
if ( Edit )
{
G1Wt[nr] = G1Wt[nr]/T1Percent;
|
G1Wt[nr] /= T1Percent;
| Quote: | Edit->Text=FloatToStr(G1Wt[nr]);
}
else |
ShowMessage ( "There is no TEdit with Tag: " + IntToStr ( nr ) );
Of course you could place the 'else' in the GetTEdit function.
Hans.
|
|
| Back to top |
|
 |
dkat Guest
|
Posted: Mon May 03, 2004 7:17 pm Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
I just want to thank you both again. I'm having so much fun with this now
and I could not have done it without the help.
"dkat" <dkat (AT) hotmail (DOT) com> wrote
| Quote: |
I'm really a old style C programmer. While I use Builder, C++, etc. I do
not have a mindset for that code writing.
In C programming if I wanted to do a identical code that used the same
logic
but different variables I would simply make the variables arrays and then
do
a for loop, while, or do to repeat the same calculations for each item of
the array. I have created a program that uses mulitiple list boxes and
edit
boxes but they all are treated in somewhat the same way.
Simplified
I have a list box from which you choose an ingredient
I have an edit box next to it that you type in the amount in weight of the
material
When the amount changes the next ingredient box is made visible
There is a total box for the total weight of materials
This displays the total but if you type in a new total the individual
weights are changed to the proportions that match the total.
In C I would have put this in a loop but that is not possible with the
components not array items. So the question is - IS there any way to make
components be arrays items? So rather than G1Wt1 G1Wt2 (TEdit
components),
etc. could I have G1Wt[14]? If so, does it mean that they have to be
created in programming rather than using the Builder Component add to form
Palette?
////////////////////////////////////Sample of Code as
is////////////////////////////////////////////////
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
if(total1)
PercentT1 = total1/ G1Total->Text.ToDouble();
else return;
if(G1Wt2->Visible==true)
{
G1Amt[0] = G1Amt[0]/PercentT1;
G1Wt1->Text=FloatToStr(G1Amt[0]);
if(G1Wt3->Visible==false)return;;
G1Amt[1] = G1Amt[1]/PercentT1;
G1Wt2->Text=FloatToStr(G1Amt[1]);
if(G1Wt4->Visible==false)return;;
G1Amt[2] = G1Amt[2]/PercentT1;
G1Wt3->Text=FloatToStr(G1Amt[2]);
if(G1Wt5->Visible==false)return;;
G1Amt[3] = G1Amt[3]/PercentT1;
G1Wt4->Text=FloatToStr(G1Amt[3]);
if(G1Wt6->Visible==false)return;;
G1Amt[4] = G1Amt[4]/PercentT1;
G1Wt5->Text=FloatToStr(G1Amt[4]);
if(G1Wt7->Visible==false)return;;
G1Amt[5] = G1Amt[5]/PercentT1;
G1Wt6->Text=FloatToStr(G1Amt[5]);
if(G1Wt8->Visible==false)return;;
G1Amt[6] = G1Amt[6]/PercentT1;
G1Wt7->Text=FloatToStr(G1Amt[6]);
if(G1Wt9->Visible==false)return;;
G1Amt[7] = G1Amt[7]/PercentT1;
G1Wt8->Text=FloatToStr(G1Amt[7]);
if(G1Wt10->Visible==false)return;;
G1Amt[8] = G1Amt[8]/PercentT1;
G1Wt9->Text=FloatToStr(G1Amt[8]);
if(G1Wt11->Visible==false)return;;
G1Amt[9] = G1Amt[9]/PercentT1;
G1Wt10->Text=FloatToStr(G1Amt[9]);
if(G1Wt12->Visible==false)return;;
G1Amt[10] = G1Amt[10]/PercentT1;
G1Wt11->Text=FloatToStr(G1Amt[10]);
if(G1Wt13->Visible==false)return;;
G1Amt[11] = G1Amt[11]/PercentT1;
G1Wt12->Text=FloatToStr(G1Amt[11]);
if(G1Wt14->Visible==false)return;;
G1Amt[12] = G1Amt[12]/PercentT1;
G1Wt13->Text=FloatToStr(G1Amt[12]);
if(G1Wt14Changed==false)return;;
G1Amt[13] = G1Amt[13]/PercentT1;
G1Wt14->Text=FloatToStr(G1Amt[13]);
}
//assign compound %
}
|
|
|
| Back to top |
|
 |
george Guest
|
Posted: Mon May 03, 2004 8:14 pm Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
"dkat" <dkat (AT) hotmail (DOT) com> wrote:
| Quote: |
I'm really a old style C programmer.
|
So am I. Does it help you to know that all components on a form
are assigneed an index number. You also have a tag that you
can set how you like and use as a flag to control processing.
In the following example I loop through all components on the
form and hide or show depending on the tag value.
void __fastcall TForm1::DealHide() // start of dealing
{ TControl *DealControl; // defines a control for this
function
for (int i=0;i<Form1->ComponentCount;i++) // loops
thro' all the components on the form
{ DealControl = dynamic_ cast<TControl *>( Form1->Components [i]); // links each component to the function's control
if (DealControl) // checks link is successful
{ if (DealControl->Tag==1) DealControl->Show(); // process for tag value 1
if (DealControl->Tag==2) DealControl->Hide(); // process for tag value 2
// NB tag value 0 has no action
} }
}
george
|
|
| Back to top |
|
 |
JD Guest
|
Posted: Tue May 04, 2004 8:17 am Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
"dkat" <dkat (AT) hotmail (DOT) com> wrote:
| Quote: | [...] In C programming if I wanted to do a identical code
that used the same logic but different variables I would
simply make the variables arrays and then do a for loop,
while, or do to repeat the same calculations for each item
of the array.
|
FWIW - all components are already in an array. It may not be
setup logically the way that you want to work with it but once
you understand how it is setup, it's easy to form your code.
One of the posts in this thread already demonstrated using the
Form's Components and ComponentCount properties and I want to
expand on that example:
// count the number of TEdits
int TotalEdits = 0;
for( int x = 0; x < ComponentCount; ++x )
{
if( Components[ x ]->ClassNameIs("TEdit") )
{
++TotalEdits;
}
}
// allocated an array of TEdit pointers
TEdit** MyEdits = NULL;
if( TotalEdits ) MyEdits = new TEdit*[ TotalEdits ];
// assign the array
for( int Index = 0, x = 0; x < ComponentCount; ++x )
{
if( Components[ x ]->ClassNameIs("TEdit") )
{
MyEdits[ Index ] = dynamic_cast<TEdit*>( Components[ x ] );
++Index;
}
}
// or
for( int x = 0; x < ComponentCount; ++x )
{
TEdit* pEdit = dynamic_cast
if( pEdit )
{
MyEdits[ pEdit->Tag ] = pEdit;
}
}
// use the array
for( int x = 0; x < TotalEdits; ++x )
{
if( MyEdits[ x ]->Tag == 11 )
{
ShowMessage( "Found Edit 11" );
break;
}
}
// destroy the array of pointers
if( MyEdits ) delete [] MyEdits;
A few comments about the sample: Note the use of dynamic_cast.
In C, one would:
TEdit* pEdit = (TEdit*) Components[ x ];
and while still legal in C++, that type of casting is prone to
errors and should be avoided because it converts the pointer
without regard to classes.
The C++ way is to use dynamic_cast instead. It will fail if you
try to cast an object to something that it isn't and if it fails
it returns NULL (which evaluates to false), otherwise it returns
a pointer (which evaluates to true).
I also used ClassNameIs. In that case, since I already tested
it to be a TEdit, I didn't need to test the result of dynamic_cast.
As stated earlier, the Components property is an array but it
is also a multidimentional variable-length array. Assume that
you have a form with a main panel and all other components are
on that panel. In this case, the form's ComponentCount would
be one and the main panel's ComponentCount would reflect the
other components:
for( int x = 0; x < ComponentCount; ++x )
{
TPanel* pPanel = dynamic_cast
if( pPanel )
{
for( int y = 0; y < pPanel->ComponentCount; ++y )
{
if( pPanel->Components[ y ]->ClassNameIs("TEdit") )
{
// found a TEdit
}
}
}
}
or
for( int x = 0; x < MainPanel->ComponentCount; ++x )
{
if( MainPanel->Components[ x ]->ClassNameIs("TEdit") )
{
// found a TEdit
}
}
Now, with all of that said, there is another way to accomplish
what you want. If you set the form's KeyPreview to true and
assign the form an OnKeyPress event:
void __fastcall TMainForm::KeyPress(TObject *Sender, char &Key)
{
if( Key == VK_RETURN )
{
TEdit* pEdit = dynamic_cast<TEdit*>( ActiveControl );
if( pEdit )
{
if( pEdit->Tag > 0 )
{
// the user is finished with this edit
CalculateTheTotals();
// make the next edit visible - maybe
if( pEdit->Tag < TotalEdits - 1 )
{
MyEdits[ pEdit->Tag + 1 ]->Visible = true;
// set the focus
MyEdits[ pEdit->Tag + 1 ]->SetFocus();
}
else
{
// the last edit field has been entered
}
// swallow the enter key so that the bell doesn't ring
Key = 0;
}
}
}
}
//-------------------------------------------------------------
void __fastcall TMainForm::CalculateTheTotals()
{
if( !total1 ) return;
PercentT1 = total1 / G1Total->Text.ToDouble();
for( int x = 0; x < TotalEdits; ++x )
{
if( MyEdits[ x ]->Visible )
{
G1Amt[ x ] = G1Amt[ x ] / PercentT1;
MyEdits[ x ]->Text = FloatToStr( G1Amt[x] );
}
else break;
}
}
//-------------------------------------------------------------
void __fastcall TMainForm::Calculate1Click(TObject *Sender)
{
CalculateTheTotals()
}
//-------------------------------------------------------------
As a final note - it's also possible to use the same event for
multiple components by using the Sender parameter:
void __fastcall TMainForm::EditChange(TObject *Sender)
{
if( total1 )
{
TEdit* pEdit = static_cast<TEdit*>( Sender );
PercentT1 = total1 / G1Total->Text.ToDouble();
for( int x = 0; x < pEdit->Tag; ++x )
{
G1Amt[ x ] = G1Amt[ x ] / PercentT1;
MyEdits[ x ]->Text = FloatToStr( G1Amt[x] );
}
}
}
~ JD
|
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Tue May 04, 2004 9:36 am Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
JD wrote:
| Quote: | One of the posts in this thread already demonstrated using the
Form's Components and ComponentCount properties and I want to
expand on that example:
|
Then let me implode on that example. You don't need an extra array,
as you can use the Tag property of the TEdits. I showed how to to
that in the function:
TEdit *__fastcall TForm1::GetTEdit ( int nr )
....
But it is nasty work to assign all those Tag's where you
make Tag equal 3 for Edit3.
You can do away with the Tag to. Simply use the Name of
the controls. We need a different GetTEdit.
TEdit *__fastcall TForm1::GetTEditByName ( AnsiString Name )
{
int count = -1;
while ( ++count < ComponentCount )
{
TEdit *Edit = dynamic_cast
if ( Edit && Edit->Name == Name )
return Edit;
}
return NULL;
}
Demo:
void __fastcall TForm1::Button3Click(TObject *Sender)
{
TEdit *Edit = GetTEditByName ( "Edit2" );
if ( Edit )
ShowMessage ( Edit->Text );
}
And in a loop:
void __fastcall TForm1::Button4Click(TObject *Sender)
{
int nr = 0;
while ( ++nr < 10 )
{
AnsiString Name = "Edit" + IntToStr ( nr );
TEdit *Edit = GetTEditByName ( Name );
if ( Edit )
ShowMessage ( Edit->Text );
}
}
Hans.
|
|
| Back to top |
|
 |
JD Guest
|
Posted: Tue May 04, 2004 10:13 am Post subject: Re: Can you have arrays of BoxLists or other components? |
|
|
Hans Galema <dontusethis (AT) dontusethis (DOT) nl> wrote:
| Quote: | [...] Then let me implode on that example.
|
I didn't intend to promote using an array. I just thought that
the previouse Components example was lacking and since the OP
is new to CBuilder ...
| Quote: | You don't need an extra array,
|
Agreed but I wouldn't use TEdit's any way. In fact, I have an
app that does much of what he's doing with formulas and
ingredients and concentration by weight and/or volume and I
use a TStringGrid for it.
~ JD
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|