BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

One TMyComponent per project

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Development)
View previous topic :: View next topic  
Author Message
JD
Guest





PostPosted: Fri Jul 02, 2004 9:17 pm    Post subject: One TMyComponent per project Reply with quote




I'd like to be able to code the component's constructor to
automatically check if it's the only instance of it's class in
the project when it's dropped on the form. If it isn't, I want
it to say something and then delete itself. I'd also like to
force it to be dropped on the main form if possible.

~ JD

Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Fri Jul 02, 2004 10:57 pm    Post subject: Re: One TMyComponent per project Reply with quote




"JD" <nospam (AT) nospam (DOT) com> wrote


Quote:
I'd like to be able to code the component's constructor
to automatically check if it's the only instance of it's class
in the project when it's dropped on the form.

The easiest way to do that is with a global pointer that is assigned to the
first instance of your component. Then additional instances can check to
see if the pointer is already assigned or not. For example:

--- MyComponent.cpp ---

TMyComponent *Instance = NULL;

__fastcall TMyComponent::TMyComponent(TComponent *Owner)
: TMyBase(Owner)
{
if( Instance )
throw Exception("Only one instance can be created at a time!");
Instance = this;
}

__fastcall TMyComponent::~TMyComponent()
{
Instance = NULL;
}


Quote:
If it isn't, I want it to say something and then delete itself.

Simply throw an exception, as shown above. Everything else will be handled
for you.

Quote:
I'd also like to force it to be dropped on the main form if possible.

That, on the other hand, is a little harder to manage. In the constructor,
the only thing you have access to regarding the creator of the component
instance is the Owner parameter. When you drop a component onto a form, the
form is assigned as the Owner, so you could do the following:

__fastcall TMyComponent::TMyComponent(TComponent *Owner)
: TMyBase(Owner)
{
if( Instance )
throw Exception("Only one instance can be created at a time!");

if( Owner )
{
if( GetParentForm(Owner) != Application->MainForm )
throw Exception("Can only be placed on the MainForm!");
}

Instance = this;
}

The trouble comes when the component is being instantiated dynamically at
runtime. The calling code would be able to specify any Owner it wants to,
which may not be the MainForm at all. And you can't use the Parent property
to decide because the Parent has not been assigned yet while you are still
inside the constructor.


Gambit



Back to top
JD
Guest





PostPosted: Sat Jul 03, 2004 6:34 am    Post subject: Re: One TMyComponent per project Reply with quote




"Remy Lebeau (TeamB)" <gambit47.no.spam (AT) no (DOT) spam.yahoo.com> wrote:
Quote:
[...] Simply throw an exception, as shown above. Everything
else will be handled for you.

That's easy enough.

Quote:
I'd also like to force it to be dropped on the main form if possible.

[...] When you drop a component onto a form, the form is
assigned as the Owner, [...] The trouble comes when the
component is being instantiated dynamically at runtime.

Your sample gave me the idea that I could use dynamic_cast
to test the Owner as a TForm prior to testing if it's the main
form:

if( !dynamic_cast<TForm*>(Owner) )
{
// then we know for sure that it's being dynamically allocated
throw Exception("You must assign the MainForm as the Owner.");
}
if( GetParentForm(Owner) != Application->MainForm )
{
// can't tell if it's dynamically allocated
throw Exception("Can only be placed on the MainForm!");
}

Knowing if it's dynamically allocated or not is only important
in as much as providing an exact reason for throwing. I'll just
have to settle for a more generic message:

if( !dynamic_cast<TForm*>(Owner) || GetParentForm(Owner) != Application->MainForm )
{
throw Exception("The Owner must be the MainForm!");
}

Thanks.

~ JD


Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Sat Jul 03, 2004 8:31 am    Post subject: Re: One TMyComponent per project Reply with quote


"JD" <nospam (AT) nospam (DOT) com> wrote


Quote:
Your sample gave me the idea that I could use
dynamic_cast to test the Owner as a TForm prior
to testing if it's the main form:

The only problem with that code is that GetParentForm() does not validate
whether the specified component is NULL, or whether it is already a form.
It always looks at the component's Parent immediately. Thus, your code
logic should be more like the following instead:

TCustomForm *form = NULL;
if( Owner )
{
form = dynamic_cast<TCustomForm*>(Owner);
if( !form )
form = GetParentForm(Owner);
}

if( (!form) || (form != Application->MainForm) )
throw Exception("You must assign the MainForm as the Owner.");


Gambit



Back to top
JD
Guest





PostPosted: Sat Jul 03, 2004 10:05 am    Post subject: Re: One TMyComponent per project Reply with quote


"Remy Lebeau (TeamB)" <gambit47.no.spam (AT) no (DOT) spam.yahoo.com> wrote:
Quote:
[...] Thus, your code logic should be more like the
following instead:

I'm too tired right now to understand what was wrong with my
code. I'll have to look at it later but thanks for the sample.

~ JD


Back to top
Michael Harris
Guest





PostPosted: Sat Jul 03, 2004 12:53 pm    Post subject: Re: One TMyComponent per project Reply with quote

Hard code the component name property afterconstruction ?

"JD" <nospam (AT) nospam (DOT) com> wrote

Quote:

I'd like to be able to code the component's constructor to
automatically check if it's the only instance of it's class in
the project when it's dropped on the form. If it isn't, I want
it to say something and then delete itself. I'd also like to
force it to be dropped on the main form if possible.

~ JD




Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Sat Jul 03, 2004 9:33 pm    Post subject: Re: One TMyComponent per project Reply with quote


"JD" <nospam (AT) nospam (DOT) com> wrote


Quote:
I'm too tired right now to understand what
was wrong with my code.

Ignore it. My mistake, I misread how GetParentForm() works, and thought
that it does not check the specified Control itself to see if it is a form.
It actually does, so your earlier code is fine, although I would suggest
getting rid of dynamic_cast:

if( !Owner )
throw Exception("You must assign an Owner.");

if( GetParentForm(Owner) != Application->MainForm )
throw Exception("Can only be placed on the MainForm!");


Gambit



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Development) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.