Board index » cppbuilder » Theoretical question

Theoretical question


2003-07-26 04:10:14 PM
cppbuilder56
Hi !
I often hear that I should not use FormCreate & FormClose because they are
an old stuff from Delphi.
I have to use Constructor & Destructor. Can you explain me what exactly
Constructor & Destructor means ?
THANK YOU A LOT,
Moore
 
 

Re:Theoretical question

"D.Moore" < XXXX@XXXXX.COM >wrote:
Quote
[...] I have to use Constructor & Destructor. Can you
explain me what exactly Constructor & Destructor means ?
They are functions that execute when the object is constructed
and destroyed. They're identical in name except that a
destructor also includes the tilde ( ~ ) in it's name.
When you begin a new project or add a new form to the project,
the only thing in the unit's cpp file is some includes and the
Constructor.
All of the code in the Constructor will execute as part of
building the object; allocating memory and initializing data
and variables. Think of it as the OnCreate event for C++
because that's exactly what it is.
The Destructor is the OnDestroy event for C++ but it differs
from the constructor in that you have to define it and add it
to the unit's header. The following example uses both the
Constructor and Destructor to subclass the Form's default
WinProc:
//------- unit.h ----------------------------------------------
//------- add under private: // User declarations
void __fastcall NewWindowProc( TMessage& );
TWndMethod OldWindowProc;
//------- add under public: // User declarations
__fastcall TForm1::~TForm1();
//------- unit.cpp --------------------------------------------
//------- the constructor
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//save the address of the old window proc
OldWindowProc = WindowProc;
//subclass the window proc
WindowProc = NewWindowProc;
}
//-------- the destructor -------------------------------------
__fastcall TForm1::~TForm1()
{
//restore the old window proc
WindowProc = OldWindowProc;
}
//-------------------------------------------------------------
void __fastcall TForm1::NewWindowProc( TMessage &Message )
{
// check for the message(s) that you want to handle
if( Message.Msg == WM_COPYDATA )
{
// do your stuff
// say that you handled the message
Message.Result = true;
}
//if not a message you're looking for pass the
//message off to the old window proc for processing
else OldWindowProc( Message );
}
You might be wondering why I kept using 'object' instead
of 'Form'. The reason is that the form is an object as is an
Edit or a ComboBox or any other component - all of which have
constructors and destructors.
~ JD
 

Re:Theoretical question

I believe I am starting to understand it, however, I would live if I tell
you I am fully got the point.
In general it means :
1., OnCreate event should not be used at all, but __fastcall
TForm1::TForm1(TComponent* Owner) can be used instead.
2., OnClose event can be used freerly.
Sorry if I seem to be an idiot, just this matter a bit new for me.
Thanks a lot in advance,
Moore
"JD" < XXXX@XXXXX.COM >wrote in message
Quote

"D.Moore" < XXXX@XXXXX.COM >wrote:
>[...] I have to use Constructor & Destructor. Can you
>explain me what exactly Constructor & Destructor means ?

They are functions that execute when the object is constructed
and destroyed. They're identical in name except that a
destructor also includes the tilde ( ~ ) in it's name.

When you begin a new project or add a new form to the project,
the only thing in the unit's cpp file is some includes and the
Constructor.

All of the code in the Constructor will execute as part of
building the object; allocating memory and initializing data
and variables. Think of it as the OnCreate event for C++
because that's exactly what it is.

The Destructor is the OnDestroy event for C++ but it differs
from the constructor in that you have to define it and add it
to the unit's header. The following example uses both the
Constructor and Destructor to subclass the Form's default
WinProc:


//------- unit.h ----------------------------------------------
//------- add under private: // User declarations
void __fastcall NewWindowProc( TMessage& );
TWndMethod OldWindowProc;
//------- add under public: // User declarations
__fastcall TForm1::~TForm1();


//------- unit.cpp --------------------------------------------
//------- the constructor
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//save the address of the old window proc
OldWindowProc = WindowProc;

//subclass the window proc
WindowProc = NewWindowProc;
}
//-------- the destructor -------------------------------------
__fastcall TForm1::~TForm1()
{
//restore the old window proc
WindowProc = OldWindowProc;
}
//-------------------------------------------------------------
void __fastcall TForm1::NewWindowProc( TMessage &Message )
{
// check for the message(s) that you want to handle
if( Message.Msg == WM_COPYDATA )
{
// do your stuff

// say that you handled the message
Message.Result = true;
}

//if not a message you're looking for pass the
//message off to the old window proc for processing
else OldWindowProc( Message );
}

You might be wondering why I kept using 'object' instead
of 'Form'. The reason is that the form is an object as is an
Edit or a ComboBox or any other component - all of which have
constructors and destructors.

~ JD

 

{smallsort}

Re:Theoretical question

"D.Moore" < XXXX@XXXXX.COM >wrote:
Quote
OnCreate event should not be used at all,
Never ever ever !!! And that goes for OnDestroy too !!
Quote
but __fastcall TForm1::TForm1(TComponent* Owner) can be used
instead.
That is where you would put the 'OnCreate' code - yes.
However, you need to be aware that the Constructor exists in
every form.
Quote
OnClose event can be used freerly.
Correct.
~ JD
 

Re:Theoretical question

"D.Moore" < XXXX@XXXXX.COM >wrote in message
Quote
I often hear that I should not use FormCreate &
FormClose because they are an old stuff from Delphi.
It is not just a matter of being from Delphi, but really is a matter that
Delphi objects have a different creation order than C++ and thus can
introduce behavior that violates C++ rules although they are perfectly valid
operations under Delphi.
Gambit
 

Re:Theoretical question

THANK YOU ! I happy to see you back !!!!!!!!!!!!!!!!
Moore
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"D.Moore" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>I often hear that I should not use FormCreate &
>FormClose because they are an old stuff from Delphi.

It is not just a matter of being from Delphi, but really is a matter that
Delphi objects have a different creation order than C++ and thus can
introduce behavior that violates C++ rules although they are perfectly
valid
operations under Delphi.


Gambit


 

Re:Theoretical question

IT depends....FormCreate() can be used for when you need to perform some
NON-UI related object initialization that needs to be performed PRIOR to
FormActivate. I will agree with everyone on the FormDestroy, however.
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"D.Moore" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>I often hear that I should not use FormCreate &
>FormClose because they are an old stuff from Delphi.

It is not just a matter of being from Delphi, but really is a matter that
Delphi objects have a different creation order than C++ and thus can
introduce behavior that violates C++ rules although they are perfectly
valid
operations under Delphi.


Gambit


 

Re:Theoretical question

"Marcelo R. Lopez, Jr." < XXXX@XXXXX.COM >writes:
Quote
IT depends....FormCreate() can be used for when you need to perform some
NON-UI related object initialization that needs to be performed PRIOR to
FormActivate. I will agree with everyone on the FormDestroy, however.
A constructor is the correct way to initialize objects in C++. If you
have 'work' that needs to be done when the object is created, the
constructor is the place to put it.
FormCreate, when called by the OnCreate event, can run BEFORE the
object is constructed. Even if it doesn't crash, it's undefined
behavior. It's foolish to use under *any* situation, IMHO, even for
non-GUI initializations.
If it doesn't access the "this" pointer, then there is no point in
putting that code in one of the form's member function in the first
place--it's unrelated to the form! If it does touch the "this"
pointer, then it's accessing a pointer to an unconstructed object,
which is undefined behavior, but can crash, corrupt, or have
surprising results. Regardless if it touches the "this" pointer or
not, if it runs before the constructor, you have already forfeited any
guarantee whatsoever about the behavior of your program for the
remainder of the program's life. You simply cannot expect it to work,
and if it does give the appearence of working, it's still wrong. (And
if you believe it works because it has symptoms of "working", then the
Siren's call has lured you into harm's way.)
In short, there is (IMHO) *NO* valid situatation--ever--where
FormCreate should be used in C++ VCL objects.
--
Chris(TeamB);
 

Re:Theoretical question

"Marcelo R. Lopez, Jr." < XXXX@XXXXX.COM >wrote in message
Quote
IT depends....FormCreate() can be used for when you
need to perform some NON-UI related object initialization
that needs to be performed PRIOR to FormActivate.
I agree with Chris. The simple fact that the OnCreate event can be
triggered **before** the constructor, which is an illegal operation in C++,
should be deterant enough to never use the OnCreate event under C++. The
same applies to the OnDestroy event, which can be triggered **after** the
destructor, another illegal operation in C++.
Gambit
 

Re:Theoretical question

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Marcelo R. Lopez, Jr." < XXXX@XXXXX.COM >wrote in message
news:3f2ffc3f$ XXXX@XXXXX.COM ...
>IT depends....FormCreate() can be used for when you
>need to perform some NON-UI related object initialization
>that needs to be performed PRIOR to FormActivate.

I agree with Chris. The simple fact that the OnCreate event can be
triggered **before** the constructor, which is an illegal operation in
C++,
should be deterant enough to never use the OnCreate event under C++. The
same applies to the OnDestroy event, which can be triggered **after** the
destructor, another illegal operation in C++.
I have only one createform and that's the one automatically generated for
the main form. I've tried getting rid of this but it seemed to muck things
up.
Is there any recommended way to do this?
 

Re:Theoretical question

"Liz Albin" < XXXX@XXXXX.COM >wrote in message
Quote
On Wed, 6 Aug 2003 12:38:36 -0400, Duane Hebert wrote:

>
>I have only one createform and that's the one automatically generated
for
>the main form. I've tried getting rid of this but it seemed to muck
things
>up.

don't "get rid of it" just don't put code in it.
That's what I've been doing. I tried this:
try
{
Application->Initialize();
Application->Title = "Nitrex Control";
//Application->CreateForm(__classid(TControlForm),
&ControlForm);
std::auto_ptr<TControlForm>ControlForm(new
TControlForm(Application));
//Application->Run();
ControlForm->ShowModal();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
And it seems to work but I didn't have time to test it very much.
 

Re:Theoretical question

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
Quote
I have only one createform and that's the
one automatically generated for the main form.
We are not referring to Application->CreateForm(). We are referring to the
TForm::OnCreate event. Very different things.
Quote
I've tried getting rid of this but it seemed to muck things up.
Do not get rid of the Application->CreateForm() for the MainForm. The VCL
requires it.
Gambit
 

Re:Theoretical question

On Wed, 6 Aug 2003 12:52:36 -0400, Duane Hebert wrote:
Quote
//Application->CreateForm(__classid(TControlForm),
&ControlForm);
std::auto_ptr<TControlForm>ControlForm(new
TControlForm(Application));
Er, no, actually what I meant was don't put code into
TControlForm::FormCreate(), but instead use your constructor.
TApplication::CreateForm is a different story,
from the online help:
void __fastcall CreateForm(System::TMetaClass* InstanceClass, void
*Reference);
CreateForm creates a new form of the type specified by the FormClass
parameter and assigns it to the variable given by the Reference
parameter. The owner of the new form is the Application object.
--
liz
 

Re:Theoretical question

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
"Duane Hebert" < XXXX@XXXXX.COM >writes:

>
>That's what I've been doing. I tried this:
>
>try
>{
>Application->Initialize();
>Application->Title = "Nitrex Control";
>//Application->CreateForm(__classid(TControlForm),

This is CreateForm, the function. That's not the problem. :)

The problem is FormCreate, an event handler that becomes a member
function of your form when you double-click on it, which is attached
to the OnCreate event for that form. THAT is what should not be used.

There's nothing to worry about how the code in "main" is generated,
it's fine.
Thanks. I don't use OnCreate or OnDestroy at all. I don't think they
should be
available in the first place.
 

Re:Theoretical question

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
Quote
I was able to get it to work with creating the main form
as an auto_ptr
That will not work. Application->CreateForm() is required for the MainForm
otherwise Application->Run() will not work correctly.
Gambit