Board index » cppbuilder » Probably a simple question

Probably a simple question


2006-12-12 02:03:31 AM
cppbuilder19
I put some Labels into a Panel and want to access the Caption of these Labels.
I was hoping something like this should work:
for(I=0; I<25; I++)
Panel1->Components[I]->Caption=Numbers[I];
- but it does not. Yet this probably gives you an idea of what I am trying to do.
Can someone help?
Regards Knut
 
 

Re:Probably a simple question

"Knut Olsen-Solberg" < XXXX@XXXXX.COM >wrote in message
Quote
I put some Labels into a Panel and want to access the Caption of these
Labels. I was hoping something like this should work:

for(I=0; I<25; I++)
Panel1->Components[I]->Caption=Numbers[I];

- but it does not.
The Components[] property returns a TComponent pointer. TComponent does not
have a Caption property. You need to type-cast the pointer to a TLabel in
order to access the Caption, ie:
for(I = 0; I < 25; ++I)
static_cast<TLabel*>(Panel1->Components[I])->Caption = Numbers[I];
Gambit
 

Re:Probably a simple question

Remy Lebeau (TeamB) wrote:
Quote
"Knut Olsen-Solberg" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...


>I put some Labels into a Panel and want to access the Caption of these
>Labels. I was hoping something like this should work:
>
>for(I=0; I<25; I++)
>Panel1->Components[I]->Caption=Numbers[I];
>
>- but it does not.


The Components[] property returns a TComponent pointer. TComponent does not
have a Caption property. You need to type-cast the pointer to a TLabel in
order to access the Caption, ie:

for(I = 0; I < 25; ++I)
static_cast<TLabel*>(Panel1->Components[I])->Caption = Numbers[I];


Gambit
The program can now be built, but when it is started:
.. class ElistError with message 'List index out of bounds (0)'
Knut
 

{smallsort}

Re:Probably a simple question

"Knut Olsen-Solberg" < XXXX@XXXXX.COM >wrote in message
Quote
The program can now be built, but when it is started:
.. class ElistError with message 'List index out of bounds (0)'
Obviously, you are trying to access a component at an invalid index. Since
the offending index is 0, that means there are not objects in the
Components[] list at all. Where exactly did you put that code? You are
probably trying to access the list too soon.
Gambit
 

Re:Probably a simple question

Knut Olsen-Solberg < XXXX@XXXXX.COM >wrote:
Quote

[...] It is done in the FormCreate function.
Never ever use the form's OnCreate event. It is a Delphi
remnant that can execute before the constructor which is
illegal in C++. Also, never ever use OnDestroy because it
can executes after the destructor. Use the constructor and
destructor instead.
Quote
I now have Label1 and Label2 in Panel1. If I move the Labels
they cannot be taken outside the Panel1, so they should
belong to Panel1?
The component's Parent property determines where the component
will live on-screen. If you want it to switch to a different
Parent then just change the Parent property.
Quote
The following is working:

Label1->Caption=Numbers[1];

But the following does NOT work (if that is of any interest):

Panel1->Label1->Caption=Numbers[1];
That's because the Label1 is not a member of Panel1. However,
they both are memebrs of Form1 so the following is correct:
Form1->Label1->Caption = Numbers[1];
Form1->Panel1->Caption = Numbers[1];
~ JD
 

Re:Probably a simple question

Remy Lebeau (TeamB) wrote:
Quote
"Knut Olsen-Solberg" < XXXX@XXXXX.COM >wrote in message
news:457e73cc$ XXXX@XXXXX.COM ...


>The program can now be built, but when it is started:
>.. class ElistError with message 'List index out of bounds (0)'


Obviously, you are trying to access a component at an invalid index. Since
the offending index is 0, that means there are not objects in the
Components[] list at all. Where exactly did you put that code? You are
probably trying to access the list too soon.


Gambit
It is done in the FormCreate function.
I now have Label1 and Label2 in Panel1. If I move the Labels they cannot be taken outside the Panel1, so they should belong to Panel1?
The following is working:
Label1->Caption=Numbers[1];
But the following does NOT work (if that is of any interest):
Panel1->Label1->Caption=Numbers[1];
Knut
 

Re:Probably a simple question

Knut Olsen-Solberg < XXXX@XXXXX.COM >wrote:
Quote

Please trim your posts.
Quote
Using the constructor made no difference...
The point is that OnCreate can execute before the form's ctor
(before the form and it's objects are created). When this
happens, you can expect to get numeriouse errors all related
to the objects not being created yet and the *only* reason
that it works now is because the form's OldCreationOrder
is set.
~ JD
 

Re:Probably a simple question

JD wrote:
Quote
Knut Olsen-Solberg < XXXX@XXXXX.COM >wrote:

>[...] It is done in the FormCreate function.


Never ever use the form's OnCreate event. It is a Delphi
remnant that can execute before the constructor which is
illegal in C++. Also, never ever use OnDestroy because it
can executes after the destructor. Use the constructor and
destructor instead.


>I now have Label1 and Label2 in Panel1. If I move the Labels
>they cannot be taken outside the Panel1, so they should
>belong to Panel1?


The component's Parent property determines where the component
will live on-screen. If you want it to switch to a different
Parent then just change the Parent property.



>The following is working:
>
>Label1->Caption=Numbers[1];
>
>But the following does NOT work (if that is of any interest):
>
>Panel1->Label1->Caption=Numbers[1];


That's because the Label1 is not a member of Panel1. However,
they both are memebrs of Form1 so the following is correct:

Form1->Label1->Caption = Numbers[1];
Form1->Panel1->Caption = Numbers[1];

~ JD

Using the constructor made no difference...
Knut
 

Re:Probably a simple question

Remy Lebeau (TeamB) wrote:
Quote
"Knut Olsen-Solberg" < XXXX@XXXXX.COM >wrote in message
news:457e73cc$ XXXX@XXXXX.COM ...


>The program can now be built, but when it is started:
>.. class ElistError with message 'List index out of bounds (0)'


Obviously, you are trying to access a component at an invalid index. Since
the offending index is 0, that means there are not objects in the
Components[] list at all. Where exactly did you put that code? You are
probably trying to access the list too soon.


Gambit
I have now placed Panel1 on the Form1. Into Panel1 I drop Label1 and Label2.
Is there a way to access the Labels as an array, not by their names. I try:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
static_cast<TLabel *>(Panel1->Components[0])->Caption=5000;
}
Not working. class ElistError with message 'List index out of bounds (0)'
Anyone know how to do this?
Knut
 

Re:Probably a simple question

Knut Olsen-Solberg < XXXX@XXXXX.COM >writes:
Quote
It is done in the FormCreate function.
That may be your problem. You should never use the FormCreate
function, because it's a fundimentally broken design in C++ that
happens to work perfectly well in Delphi. It's a shame, because the
VCL being written in Delphi practically encourages you to use it,
considering the IDE will pop you into FormCreate if you double-click
the form. (I've made a stink about this for years and was ignored,
and finally given up trying.)
The problem is that FormCreate can run BEFORE your form is actually
constructed, so it may be accessing variables that have not yet been
created or initialized, and if that doesn't crash, it may still have
its effects wiped out when the members do get initialized. But in any
case, accessing a variable before it's constructed is undefined
behavior, and a crash is likely.
Instead of using FormCreate, do the work in the form's constructor,
and see if that improves things.
If it doesn't visibly improve things, then you've still improved
things, as you've solved serious problems that you haven't yet had to
look into.
--
Chris (TeamB);
 

Re:Probably a simple question

No, I do'nt use the FormCreate any more (I got a tip earlier).
My question was:
I have now placed Panel1 on the Form1. Into Panel1 I drop Label1 and Label2.
Is there a way to access the Labels as an array, not by their names. I try:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
static_cast<TLabel *>(Panel1->Components[0])->Caption=5000;
}
Not working. class ElistError with message 'List index out of bounds (0)'
Anyone know how to do this?
Knut
 

Re:Probably a simple question

in the constructor the components may well not have been
created, so trying to access them then is not a good idea.
So when you try to access the first component: Components[0]
it does not exist and you get an array error.
Try in OnShow event.
Alternatively, if you want to access the labels as an array,
create them dynamically as an array using (untested)
TLabel **Labels = new (TLabel*[2]);
Labels[0] = new TLabel(this);
Labels[0]->Parent = this;
Labels[1] = new TLabel(this);
Labels[1]->Parent = this;
don't forget to delete array afterwards in destructor
HTH Pete
"Knut Olsen-Solberg" < XXXX@XXXXX.COM >wrote in message
Quote

No, I do'nt use the FormCreate any more (I got a tip
earlier).
My question was:

I have now placed Panel1 on the Form1. Into Panel1 I drop
Label1 and Label2.
Is there a way to access the Labels as an array, not by
their names. I try:

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
static_cast<TLabel
*>(Panel1->Components[0])->Caption=5000;
}

Not working. class ElistError with message 'List index
out of bounds (0)'
Anyone know how to do this?
 

Re:Probably a simple question

Pete Fraser wrote:
Quote
in the constructor the components may well not have been
created, so trying to access them then is not a good idea.
So when you try to access the first component: Components[0]
it does not exist and you get an array error.
Try in OnShow event.
There is no event OnShow or similar...
Knut
 

Re:Probably a simple question

All forms have an OnShow event
HTH Pete
"Knut Olsen-Solberg" < XXXX@XXXXX.COM >wrote in message
Quote
Pete Fraser wrote:

>in the constructor the components may well not have been
>created, so trying to access them then is not a good
>idea.
>So when you try to access the first component:
>Components[0] it does not exist and you get an array
>error.
>Try in OnShow event.

There is no event OnShow or similar...
 

Re:Probably a simple question

"Pete Fraser" < XXXX@XXXXX.COM >writes:
Quote
in the constructor the components may well not have been
created, so trying to access them then is not a good idea.
So when you try to access the first component: Components[0]
it does not exist and you get an array error.
Try in OnShow event.
This is the kind of thing that drives me crazy about the VCL. It's
not C++ and changes the rules of C++ classes if they inherit from
VCL. I seem to remember warnings about OnShow possibly having the
same sort of problem that OnCreate has, but it has been years since
I've done any real VCL programming, and don't remember the issues.
--
Chris (TeamB);