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

Dynamic created TLabel does not seem to use the programaticly setted Anchor Property

34 views
Skip to first unread message

Julien Moorrees

unread,
Jan 14, 2004, 12:28:02 PM1/14/04
to
Hi all,

I have created a Dynamic TLabel, wich is found on a dynamicly created
TPanel. The properties of these dynamic items are copied from another
object on the form. When i view the Static TPanel on the Designer, all
the anchors work correct (I can resize the window, and everything goes
along with it). But when running the program and then resizing the
window, the dynamicly created panels does not work correct anymore.

I use the following code:
( pnlReceiveFile and lblStatusReceiving are hidden)


fileTransferPanels[fileTransferPanelCount]=new TPanel(pnlFileTransfer);
fileTransferPanels[fileTransferPanelCount]->Anchors =
pnlReceiveFile->Anchors;
fileTransferPanels[fileTransferPanelCount]->Alignment =
pnlReceiveFile->Alignment;
fileTransferPanels[fileTransferPanelCount]->Height =
pnlReceiveFile->Height;
fileTransferPanels[fileTransferPanelCount]->Width = pnlReceiveFile->Width;
fileTransferPanels[fileTransferPanelCount]->Color = pnlReceiveFile->Color;
fileTransferPanels[fileTransferPanelCount]->BevelOuter =
pnlReceiveFile->BevelOuter;
fileTransferPanels[fileTransferPanelCount]->Align =
pnlReceiveFile->Align;
fileTransferPanels[fileTransferPanelCount]->Top =
fileTransferPanelCount*pnlReceiveFile->Height;
fileTransferPanels[fileTransferPanelCount]->Visible=true;
fileTransferPanels[fileTransferPanelCount]->Parent = pnlFileTransfer;


TLabel *tLbl = new TLabel(fileTransferPanels[fileTransferPanelCount]);
tLbl->Alignment = lblStatusReceiving->Alignment;
tLbl->Anchors = lblStatusReceiving->Anchors;
tLbl->AutoSize = lblStatusReceiving->AutoSize;
tLbl->Caption = lblStatusReceiving->Caption;
tLbl->Height = lblStatusReceiving->Height;
tLbl->Left = lblStatusReceiving->Left;
tLbl->Name = lblStatusReceiving->Name;
tLbl->Top = lblStatusReceiving->Top;
tLbl->Transparent = lblStatusReceiving->Transparent;
tLbl->Width = lblStatusReceiving->Width;
tLbl->Font = lblStatusReceiving->Font;
fileTransferPanels[fileTransferPanelCount]->InsertControl(tLbl);
tLbl->Parent = fileTransferPanels[fileTransferPanelCount];

Remy Lebeau (TeamB)

unread,
Jan 14, 2004, 2:21:57 PM1/14/04
to

"Julien Moorrees" <n...@nims.nl> wrote in message
news:40057c01$1...@newsgroups.borland.com...

> fileTransferPanels[fileTransferPanelCount]=new TPanel(pnlFileTransfer);
> fileTransferPanels[fileTransferPanelCount]->Anchors =
> pnlReceiveFile->Anchors;

<snip>

There is an easier way to copy properties from one instance to another
without manually coding every single assignment. Have a look at using the
VCL's native RTTI (runtime type information), via the functions declared in
the TypInfo unit. For example:

#include <typinfo.hpp>

// there is a bug in BCB5 where tkProperties is not defined correctly
#if( (__BORLANDC__ >= 0x0550) && (__BORLANDC__ < 0x0560) )
#undef tkProperties
#define tkProperties (Typinfo::TTypeKinds() << tkInteger << tkChar \
<< tkEnumeration << tkFloat << tkString << tkSet << tkClass \
<< tkWChar << tkLString << tkWString << tkVariant << tkArray \
<< tkRecord << tkInterface << tkInt64 << tkDynArray)
#endif

PTypeInfo pTypeInfo = (PTypeInfo) pnlReceiveFile->ClassInfo();
TPropList PropList;
int Count = GetPropList(pTypeInfo, tkProperties, (PPropList) &PropList);

TPanel *pnlNew = new TPanel(pnlFileTransfer);
pnlNew->Parent = pnlFileTransfer;
for(int x = 0; x < Count; ++x)
{
if( PropList[x]->Name != "Top" )
{
SetPropValue(pnlNew, PropList[x]->Name,
GetPropValue(pnlReceiveFile,
PropList[x]->Name, false));
}
else
pnlNew->Top = (fileTransferPanelCount * pnlReceiveFile->Height);
}
fileTransferPanels[fileTransferPanelCount] = pnlNew;

> TLabel *tLbl = new TLabel(fileTransferPanels[fileTransferPanelCount]);
> tLbl->Alignment = lblStatusReceiving->Alignment;

<snip>

Likewise, the same can be done with the TLabel as well:

pTypeInfo = (PTypeInfo) lblStatusReceiving->ClassInfo();
Count = GetPropList(pTypeInfo, tkProperties, (PPropList) &PropList);

TLabel *tLbl = new TLabel(fileTransferPanels[fileTransferPanelCount]);

tLbl->Parent = fileTransferPanels[fileTransferPanelCount];
for(int x = 0; x < Count; ++x)
{
SetPropValue(tLbl, PropList[x]->Name,
GetPropValue(lblStatusReceiving,
PropList[x]->Name, false));
}

> fileTransferPanels[fileTransferPanelCount]->InsertControl(tLbl);

There is no need to call InsertControl(), setting the Parent property will
do that automatically for you.

The alternative approach to this issue is to not copy TPanel and TLabel
instances individually to begin with, but instead to just derive a new class
from TPanel that contains a TLabel internally, and implement an Assign()
method for it. Then you simply create a new instance of your class when
needed and call Assign(), ie:

fileTransferPanels[fileTransferPanelCount] = new
TMyPanel(pnlFileTransfer);
fileTransferPanels[fileTransferPanelCount]->Assign(pnlFileTransfer);


fileTransferPanels[fileTransferPanelCount]->Top =

(fileTransferPanelCount * pnlReceiveFile->Height);

In fact, if you go that approach, then you don't even need to use hidden
components to begin with, the new class can assign its default values as
needed in its constructor, and expose properties for those you wish to
update at runtime.


Gambit


Julien Moorrees

unread,
Jan 14, 2004, 4:48:46 PM1/14/04
to
Remy Lebeau (TeamB) wrote:

> <snip>
>
> There is an easier way to copy properties from one instance to another
> without manually coding every single assignment. Have a look at using the
> VCL's native RTTI (runtime type information), via the functions declared in
> the TypInfo unit. For example:

Thanks for your answer, but this does not solve the Anchor problem (I
think). Do you have any information about that?

Remy Lebeau (TeamB)

unread,
Jan 14, 2004, 5:54:07 PM1/14/04
to
"Julien Moorrees" <n...@nims.nl> wrote in message
news:4005b91d$1...@newsgroups.borland.com...

> Thanks for your answer, but this does not solve the Anchor problem

It wasn't meant to address that issue.

> Do you have any information about that?

Try setting the Anchors property *after* you have set the positioning and
dimensions rather than beforehand.

Alternatively, as I have mentioned several times now, don't copy panels from
one to another to begin with. You are taking a very long approach to
something that can be handled much cleaner by deriving a new class.


Gambit


Julien Moorrees

unread,
Jan 14, 2004, 6:59:49 PM1/14/04
to
Remy Lebeau (TeamB) wrote:

I get the following Linker Error when trying this code:
[Linker Error] Unresolved external '__fastcall
Typinfo::GetPropList(Typinfo::TTypeInfo *,
System::Set<Typinfo::TTypeKind, 0, 17>, Typinfo::TPropInfo * *, bool)'
referenced from D:\COMPILE\PROJECTS\OMS\SKDISCUSS.OBJ

Is this function no more available in Windows XP?

Julien Moorrees

unread,
Jan 14, 2004, 6:52:45 PM1/14/04
to
Remy Lebeau (TeamB) wrote:

I get an Compiler error when using the code (see below)

>
> There is an easier way to copy properties from one instance to another
> without manually coding every single assignment. Have a look at using the
> VCL's native RTTI (runtime type information), via the functions declared in
> the TypInfo unit. For example:
>
> #include <typinfo.hpp>
>
> // there is a bug in BCB5 where tkProperties is not defined correctly
> #if( (__BORLANDC__ >= 0x0550) && (__BORLANDC__ < 0x0560) )
> #undef tkProperties
> #define tkProperties (Typinfo::TTypeKinds() << tkInteger << tkChar \
> << tkEnumeration << tkFloat << tkString << tkSet << tkClass \
> << tkWChar << tkLString << tkWString << tkVariant << tkArray \
> << tkRecord << tkInterface << tkInt64 << tkDynArray)
> #endif
>
> PTypeInfo pTypeInfo = (PTypeInfo) pnlReceiveFile->ClassInfo();
> TPropList PropList;
> int Count = GetPropList(pTypeInfo, tkProperties, (PPropList) &PropList);


At the last above line, the following error happens:

[C++ Error] skDiscuss.cpp(1603): E2015 Ambiguity between 'TTypeKind' and
'Typinfo::TTypeKind'


Wich tkProperties do I need to use, and how to pass them to the function?

Julien Moorrees

unread,
Jan 14, 2004, 6:56:15 PM1/14/04
to
Julien Moorrees wrote:

> Remy Lebeau (TeamB) wrote:
>
> I get an Compiler error when using the code (see below)
>
>>

>> #define tkProperties (Typinfo::TTypeKinds() << tkInteger <<
>> tkChar \
>> << tkEnumeration << tkFloat << tkString << tkSet << tkClass \
>> << tkWChar << tkLString << tkWString << tkVariant <<
>> tkArray \
>> << tkRecord << tkInterface << tkInt64 << tkDynArray)
>

> At the last above line, the following error happens:
>
> [C++ Error] skDiscuss.cpp(1603): E2015 Ambiguity between 'TTypeKind' and
> 'Typinfo::TTypeKind'


Fixed it, it looks like the wrong Typedef is still in BCB 6. So I
removed the #if from the compiler vars.

Julien Moorrees

unread,
Jan 14, 2004, 6:45:01 PM1/14/04
to
Remy Lebeau (TeamB) wrote:

>
> Try setting the Anchors property *after* you have set the positioning and
> dimensions rather than beforehand.

That was the trick (k)! P.s. does the PropList in you example give the
Anchors as Last?


> Alternatively, as I have mentioned several times now, don't copy panels from
> one to another to begin with. You are taking a very long approach to
> something that can be handled much cleaner by deriving a new class.
>

You're right but in my case this is not really nescesary.

Julien Moorrees

unread,
Jan 14, 2004, 7:13:30 PM1/14/04
to
Julien Moorrees wrote:


I added the following line to fix the linker error:
//Fix bug for GetProplist
#pragma alias
"@Typinfo@GetPropList$qqrp17Typinfo@TTypeInfo46System@%Set$t17Typinfo@TTypeKind$iuc$0$iuc$17%pp17Typinfo@TPropInfoo"
=
"@Typinfo@GetPropList$qqrp17Typinfo@TTypeInfo46System@%Set$t17Typinfo@TTypeKind$iuc$0$iuc$17%pa16380$p17Typinfo@TPropInfoo"


(all at one line!) don't know why it works.

Remy Lebeau (TeamB)

unread,
Jan 14, 2004, 7:52:14 PM1/14/04
to

"Julien Moorrees" <n...@nims.nl> wrote in message
news:4005d45b$1...@newsgroups.borland.com...

> does the PropList in you example give the Anchors as Last?

As far as I have ever seen, the properties are always returned in
alphabetical order.

> You're right but in my case this is not really nescesary.

Perhaps not necessary, but it would be a lot cleaner and more solid in
general.


Gambit


Julien Moorrees

unread,
Jan 14, 2004, 7:42:33 PM1/14/04
to
Julien Moorrees wrote:


There is a big problem with this solution, everytime I recompile the
project, the .OBJ file keeps locked and thus I have to restart c++
builder every time. I think this is not the correct way to fix this.

Remy Lebeau (TeamB)

unread,
Jan 14, 2004, 7:54:44 PM1/14/04
to

"Julien Moorrees" <n...@nims.nl> wrote in message
news:4005d7d3$1...@newsgroups.borland.com...

> Is this function no more available in Windows XP?

It has nothing to do with the OS platform at all. It is a VCL function, not
a Windows API function.


Gambit


Remy Lebeau (TeamB)

unread,
Jan 14, 2004, 7:58:36 PM1/14/04
to

"Julien Moorrees" <n...@nims.nl> wrote in message
news:4005d7d3$1...@newsgroups.borland.com...

> I get the following Linker Error when trying this code:

Normally, design-time code is not allowed to be compiled into runtime
projects. All the more reason to just make a descendant component instead,
you will save yourself a lot of headaches n the long run anyway you look at
it.


Gambit


0 new messages