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

Constructor versus FormCreate

400 views
Skip to first unread message

Ken Paul

unread,
Jan 30, 2001, 11:31:27 PM1/30/01
to
Ok, I've read all the newsgroups about not relying on FormCreate for form
and property initialization. If someone can, please explain exactly what
FormCreate is for??? If I cannot rely upon exactly when this closure is
called, what can I rely upon it for? Note that I have several (some rather
large) projects that have been brought up from BCB1 to BCB3, and now to
BCB5. This OldCreateOrder business is a bit unbelievable, and I can only
shake my head in wonder at what it could all possibly be for... What
happened to cause the creation of such an idiotic thing?

I went through each of my dfm's by hand and added the 'OldCreateOrder =
False' entries, but, in BCB5, *any time* I save a form where the dfm has
been modified (including simply moving the form to a different location on
screen within the IDE), the saved dfm no longer contains my 'OldCreateOrder
= False' entries. After about the third (not to mention the twenty third)
time this happens, and I have to go manually fix the dfm yet again, it wears
a bit thin... I have tried right clicking the properties tab and viewing
legacy properties to change OldCreateOrder to false directly from the object
inspector, but the setting doesn't stick and I still have to go correct the
form by hand (i.e. convert the form to text, add the 'OldCreateOrder =
False' entry, then convert the form back to a dfm.)

To answer a specific question, when, exactly, is my vtable initialized?
Also, what, if anything, comes between my constructor call, FormCreate, and
FormShow? If my vtable is not yet initialized until after the ctor returns,
and FormCreate can be called at any time (usually before the ctor finishes
its initialization), then how can I get a one-time initialization of my form
based upon it's most derived state (without introducing some 'initialized'
boolean...) Is there any place that I can reliably have access to a virtual
function before FormShow is called?

Hope this all makes sense...

Thanks,
Ken


Matt Lee

unread,
Jan 30, 2001, 11:48:43 PM1/30/01
to
When using Visual form inheritance, the OldCreateOrder property in any
inherited forms gets set to true when the form is saved. One work around is
to overload the Loaded method of the base class and set the property to
false after calling the inherited method. This has worked for me, but i
never use the OldCreate property anymore anyway.

Matt

AlisdairM

unread,
Jan 31, 2001, 5:52:11 AM1/31/01
to
Remember the VCL was written for a different language, the Object Pascal
used by Delphi. In this environment the OnCreate event makes more
sense, and doesn't cause the constructor problems faced in BCB.

It is best to think of OnCreate/OnDestroy as 'legacy/Delphi only' events
because they can cause subtle bugs. When handled correctly,
understanding the issues of the firing order, they can be used. But why
would you choose to rely on a fragile, error-prone system that future
maintainers (including yourself!) may not understand when the code is
revisitted?

As there is a much simpler alternative (always use the ctor/dtor) I find
this a 'no-brainer', just do it. I'm not interested in picking through
the subtleties and details of a bug I never plan on fixing!

The OnShow is a little more annoying, as I use this frequently. The
issue only arises here is the 'Visible' property is set to true at
design time, as only then will 'Show' be called before construction. As
I always call show myself, I don't have a problem with this but it is
important to be aware of the problem. I find it a lot less subtle than
the OnCreate issue though and so can live with it.


AlisdairM

Leo Siefert

unread,
Jan 31, 2001, 9:36:38 AM1/31/01
to
Ken Paul wrote:
>
> if someone can, please explain exactly what FormCreate is for???

IMO, nothing. Anything that you think would go here should be in the
constructor. Pretend that FormCreate is really "BugInsert."

> What happened to cause the creation of such an idiotic thing?

VCL was written in OP for Delphi, where I've been told the FormCreate
method actually works.



> Also, what, if anything, comes between my constructor call,
> FormCreate, and FormShow?

FormShow is also unsuitable for initialization, and it can also run
prior to your constructor code. Also note that FormShow can be called
more than once during the life of the form, wich could be disaster if
you initialize anything here.

> Is there any place that I can reliably have access to a virtual
> function before FormShow is called?

I don't think so, but I don't really think that this is an issue. You
can call virtual methods from your constructor, though this may not be
prior to the first time your FormShow code runs, it will be prior to the
actual display of the form.

- Leo

Chris Uzdavinis (TeamB)

unread,
Jan 31, 2001, 12:48:27 PM1/31/01
to
"Ken Paul" <k...@payroll.com> writes:

> Ok, I've read all the newsgroups about not relying on FormCreate for form
> and property initialization. If someone can, please explain exactly what
> FormCreate is for??? If I cannot rely upon exactly when this closure is
> called, what can I rely upon it for? Note that I have several (some rather
> large) projects that have been brought up from BCB1 to BCB3, and now to
> BCB5. This OldCreateOrder business is a bit unbelievable, and I can only
> shake my head in wonder at what it could all possibly be for... What
> happened to cause the creation of such an idiotic thing?

My opinion is that the OnCreate event is a good thing for Delphi, and
since Delphi and BCB share the VCL it is inevitably exposed in the BCB
code as well.

However, my personal belief, based on my own design rules and safety
constraints, force me to conclude that the OnCreate event is not fit
for using ever in the C++ world. Some people will always continue to
use it, but if I had my way it wouldn't exist. (But I'm also very
restrictive on what I allow into my code, the pickier the better
IMHO.)

Anyway, even if it works for you, consider moving the code into the
constructor if that can be done appropriately. You'll be glad you
did, and then you can forget the OldCreateOrder nonsense.

--
Chris (TeamB);

Ken Paul

unread,
Jan 31, 2001, 1:25:50 PM1/31/01
to
Thanks Matt,

You're the second person to suggest this approach, and it seems the best
solution to my problem that I've seen so far. I am rather amazed that there
is not a better way to do this...

Now, if you will excuse me, I have to go and write a *lot* of Loaded fn's...

Ken

"Matt Lee" <nos...@nospam.com> wrote in message news:3a77992a$1_2@dnews...

Ken Paul

unread,
Jan 31, 2001, 2:34:42 PM1/31/01
to
"Chris Uzdavinis (TeamB)" <ch...@atdesk.com> wrote in message
news:j6u26fh...@explicit.atdesk.com...

> My opinion is that the OnCreate event is a good thing for Delphi, and
> since Delphi and BCB share the VCL it is inevitably exposed in the BCB
> code as well.

Yeah, I actually agree with you here -- I tend to be a bit BCB-centric
(especially when I rant...)


> However, my personal belief, based on my own design rules and safety
> constraints, force me to conclude that the OnCreate event is not fit
> for using ever in the C++ world. Some people will always continue to
> use it, but if I had my way it wouldn't exist. (But I'm also very
> restrictive on what I allow into my code, the pickier the better
> IMHO.)

Agreed.

> Anyway, even if it works for you, consider moving the code into the
> constructor if that can be done appropriately. You'll be glad you
> did, and then you can forget the OldCreateOrder nonsense.

Good advice, thanks.

Ken


Ken Paul

unread,
Jan 31, 2001, 2:45:06 PM1/31/01
to

"AlisdairM" <alisdair.meredith@NO_SPAM_PLEASE.benettonformula.com> wrote in
message news:3A77EE5B.EA7F1CFE@NO_SPAM_PLEASE.benettonformula.com...

> The OnShow is a little more annoying, as I use this frequently. The
> issue only arises here is the 'Visible' property is set to true at
> design time, as only then will 'Show' be called before construction. As
> I always call show myself, I don't have a problem with this but it is
> important to be aware of the problem. I find it a lot less subtle than
> the OnCreate issue though and so can live with it.

Thanks for the reply, but am I reading this correctly? Are you saying that
OnShow, too, can be called prior to the ctor finishing the class'
initialization? That makes no sense to me -- how can the form be told to
show prior to its underlying object's full initialization? Please say it
isn't so...


Ken Paul

unread,
Jan 31, 2001, 3:57:46 PM1/31/01
to

"Leo Siefert" <lsie...@senate.state.mi.us> wrote in message
news:3A7822F6...@senate.state.mi.us...

> Ken Paul wrote:
> > Also, what, if anything, comes between my constructor call,
> > FormCreate, and FormShow?
>
> FormShow is also unsuitable for initialization, and it can also run
> prior to your constructor code. Also note that FormShow can be called
> more than once during the life of the form, wich could be disaster if
> you initialize anything here.

You are saying directly something that Alisdair mentioned in his response. I
will repeat my question from there: How can the form be told to show prior
to its underlying object's full initialization? Am I going nuts? This makes
absolutely no sense to me. None. If this is true, my confidence in VCL is
entirely shaken.

> > Is there any place that I can reliably have access to a virtual
> > function before FormShow is called?
>
> I don't think so, but I don't really think that this is an issue. You
> can call virtual methods from your constructor, though this may not be
> prior to the first time your FormShow code runs, it will be prior to the
> actual display of the form.

Unless something has changed, a class' vtable is not fully initialized until
the ctor returns. You can call a virtual function, but you will not get the
most-derived version of that function, but the local version belonging to
the class being constructed... I was hoping there was some way to initialize
a VCL class outside the ctor so that I had a viable vtable (and thus a
functional virtual hierarchy) to work with.

Ken


Sebastian Moleski (SurakWare)

unread,
Jan 31, 2001, 4:08:16 PM1/31/01
to
"Ken Paul" <k...@payroll.com>:

Sorry to say, but this is the case. In Delphi, a constructor can call a
virtual method overridden by a descendant. Consider the following source
code:

#include <iostream>

class X {
public:
X() { foo(); }
virtual void foo() { std::cout << "X::foo" << std::endl; }
};

class Y : public X {
public:
Y() : X() {}
virtual void foo() { std::cout << Y::foo" << std::endl; }
};

int main() {
X x;
}

This code will print X::foo in C++, but (when correctly translated to Object
Pascal), will print "Y::foo".

sm


Chris Uzdavinis (TeamB)

unread,
Jan 31, 2001, 5:01:59 PM1/31/01
to
"Ken Paul" <k...@payroll.com> writes:

> Unless something has changed, a class' vtable is not fully initialized until
> the ctor returns. You can call a virtual function, but you will not get the
> most-derived version of that function, but the local version belonging to
> the class being constructed... I was hoping there was some way to initialize
> a VCL class outside the ctor so that I had a viable vtable (and thus a
> functional virtual hierarchy) to work with.

This is one of the warts that happens to merged-language object
models. Some things just don't quite fit, but are there anyway. Some
things are broken but are not prevented. Some limitations are
introduced, and some new capabilities exist.

Yet another good reason to strictly separate the application logic
from its user interface layer. I let the VCL do its thing, and I do
as little in the VCL-world as possible. Once the data is entered,
it's converted into my internal format, and as far as my application
cares, there is no gui whatsoever, just an abstract interface that
represents the user IO. (This interface happens to be implemented in
terms of the VCL, but that's irrelevant to the code that uses the
interface.)

--
Chris (TeamB);

Ken Paul

unread,
Jan 31, 2001, 5:48:23 PM1/31/01
to

"Chris Uzdavinis (TeamB)" <ch...@atdesk.com> wrote in message
news:j6hf2fg...@explicit.atdesk.com...

> This is one of the warts that happens to merged-language object
> models. Some things just don't quite fit, but are there anyway. Some
> things are broken but are not prevented. Some limitations are
> introduced, and some new capabilities exist.

I have been remiss... These are things I should have known for some time
now. It never occurred to me that BCB would work this way, but I should have
taken the time to learn the details. Having said that, this information also
should be in bold, 20pt type in the help file, readme and manuals. This is
crazy...

Thanks, Chris, for taking the time to explain.

Ken


Chris Uzdavinis (TeamB)

unread,
Jan 31, 2001, 6:39:17 PM1/31/01
to
"Ken Paul" <k...@payroll.com> writes:

> I have been remiss... These are things I should have known for some time
> now. It never occurred to me that BCB would work this way, but I should have
> taken the time to learn the details. Having said that, this information also
> should be in bold, 20pt type in the help file, readme and manuals. This is
> crazy...
>
> Thanks, Chris, for taking the time to explain.

The worst part, IMHO, is if you double click on a form it takes you to
FormCreate. Doh! Thus, not even everyone at Borland seems to be in
agreement that this event should not be used. This is probably due in
part to the strong Delphi culture at Borland (and somebody probably
didn't realize the ramifications.)

But I've submitted a feature request for the IDE to change the
behavior such that double clicking on a form brings you to the
constructor instead of FormCreate.

--
Chris (TeamB);

AlisdairM

unread,
Feb 2, 2001, 8:33:49 AM2/2/01
to
Ken Paul wrote:

> Thanks for the reply, but am I reading this correctly? Are you saying that
> OnShow, too, can be called prior to the ctor finishing the class'
> initialization? That makes no sense to me -- how can the form be told to
> show prior to its underlying object's full initialization? Please say it
> isn't so...

Sorry I'm a couple of days replying, but just to add to all the other
comments...

When you create an instance of a form, a datamodule or most anything
else that uses the Delphi streaming mechanism all the properties will be
streamed as part of the VCL-base class behaviour. So when you invoke
the base-class constructor in the initializer list, that all happens
then.

The implication is that any properties that get set may also invoke
their associated events. The classic example is the Visible property of
a form invoking the OnShow method if set to true. For this reason, I
always set the design-time property to false. I'm sure there are other
examples too, so being aware of the cause will help you identify when
you hit them.

As mentioned before, this is the problem of trying to share an Object
Pascal library in a C++ environment. Some of the language conventions
appear plain odd, and can cause problems unforeseen in the original
environment.

For the flip side, try explaining the 'OldCreateOrder' property to a
Delphi developer...


AlisdairM

Leo Siefert

unread,
Feb 2, 2001, 10:05:52 AM2/2/01
to
Ken Paul wrote:
>
> How can the form be told to show prior to its
> underlying object's full initialization?

I am far from an expert on the internals of VCL - I've never even tried
to learn to read OP code and I get totally confused if I try to think
about the differences in construction sequences between OP and C++ and
their possible consequences on my programs - but I have some practical
experience in _using_ VCL in my programs. I'm not certain that FormShow
actually does show the form - I believe it is an event handler that is
called in response to a WM_SHOW message, so what it does is prepare for
the form to be shown. If you call ShowWindow(), then FormShow is
called, but it can also be called like any other function, and is often
called before code in the contructor is executed.

> Unless something has changed, a class' vtable is not fully initialized
> until the ctor returns. You can call a virtual function, but you will
> not get the most-derived version of that function,

Don't know all of the details, but remember that much of this is done in
OP, so it's different from straight C++. Personally I believe this to
be a _huge_ mistake on the part of Borland - I think Builder would be
able to grab a significant if not majority of the VC++ market if it had
a pure C++ VCL and a more stable IDE/project manager.

> I was hoping there was some way to initialize a VCL class outside
> the ctor so that I had a viable vtable (and thus a
> functional virtual hierarchy) to work with.

I'm not really sure what you are trying to do (in a practical sense)
here, but I would suggest that you put aside your theoretical musings
and just try initializing what you need initialized in the constructor.
What I have found is that that usually works. For many years, I've
programmed using OWL, and much of the initialization needed to be put
into the SetupWindow() method which reliably ran after the constructor.
When I first used VCL I assumed that the FormCreate() method would
provide the same services. I soon realized that this did not work, but
that if I shoved all of the code I felt belonged in FormCreate() into
the constructor all worked as intended.

- Leo

Aleksejs Bozinskis

unread,
Aug 21, 2019, 6:32:10 AM8/21/19
to
On Wednesday, January 31, 2001 at 6:31:27 AM UTC+2, Ken Paul wrote:

> but, in BCB5, *any time* I save a form where the dfm has
> been modified (including simply moving the form to a different location on
> screen within the IDE), the saved dfm no longer contains my 'OldCreateOrder = False' entries.

You don't need 'OldCreateOrder = False' entries, because it is default value and BCB doesn't save default values in DFMs.
0 new messages