Board index » cppbuilder » deleting TWinControl

deleting TWinControl


2004-02-03 06:43:00 PM
cppbuilder25
I want to delete a TWinControl by clicking on it. This control contains a
TImage and a TStaticText. The click event is received by the child controls
and to a method of TWinControl that i called MouseDown:
TImage->OnMouseDown = MouseDown
TStaticText->OnMouseDown = MouseDown
If I click the TStaticText I get no errors, instead clicking the TImage
cause a write memory error.
wath is the problem?
luca
 
 

Re:deleting TWinControl

Post your MouseDown event handler.
 

Re:deleting TWinControl

On Tue, 3 Feb 2004 11:43:00 +0100, luca casotti wrote:
Quote
TImage->OnMouseDown = MouseDown
TStaticText->OnMouseDown = MouseDown
Please post a small (<50 lines) program that shows the problem.
At the /very/ least, post the code where you make the assignments
--
Good luck,
liz
 

{smallsort}

Re:deleting TWinControl

THIS IS THE WINCONTROL
class TWin : public TWinControl
{
public: // User declarations
TStaticText *title;
TImage *image;
void __fastcall MouseDown(TObject* Sender, TMouseButton Button, TShiftState
Shift, int X, int Y);
__fastcall TWin(TComponent* Owner);
};
__fastcall TWin::TWin(TComponent* Owner)
: TWinControl(Owner)
{
title = new TStaticText(this);
title->Parent = this;
title->ParentFont = true;
title->OnMouseDown = MouseDown;
image = new TImage(this);
image->Parent = this;
image->Picture->LoadFromFile("test3.bmp");
// image->Picture->Bitmap->LoadFromResourceName((unsigned int)HInstance,
"MOD");
image->AutoSize = true;
image->OnMouseDown = MouseDown;
ParentFont = true;
AutoSize = true;
}
void __fastcall TWin::MouseDown(TObject* Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
DestroyHandle();
delete this;
}
THIS EVENT CREATE THE COMPONENT
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TWin *mod = new TWin(this);
mod->Parent = this;
mod->title->Caption = "myname";
mod->Visible = true;
mod->Left = 100;
mod->Top = 100;
}
CLICKING ON title DELETE THE CONTROL WITHOUT ERRORS
CLICKING ON image CAUSES THE FOLLOWING ERROR MESSAGE:
First chance exception at 0x77E9E8BB . Exception class EAccessViolation with
message 'Access violation at address 00000000. Read of address 00000000'.
Process Project1.exe (0x1E8)
 

Re:deleting TWinControl

try :
void __fastcall TWin::MouseDown(TObject* Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
Close();
}
 

Re:deleting TWinControl

I'd no time to test your code. I just took a look to it.
Quote
void __fastcall TWin::MouseDown(TObject* Sender, TMouseButton
Button,
TShiftState Shift, int X, int Y)
{
DestroyHandle();
delete this;
}
Some ideas:
1) don't use DestroyHandle();
2) I don't like "delete this" in an event handler: maybe that who
calls the handler doesn't expect the object to be deleted on return. I
expect that who sent the MouseDown will try to send a MouseUp!
3) Activate codeguard (Project/Options/CodeGuard and Tools/Codeguard
configuration
4) Write better c++ code. Who creates TWin? Did you think about the
fact that after your MouseDown the pointer to the TWin object is not
valid any more:
i.e:
TWin * mickey=new TWin(this);
after a MouseDown on mickey, mickey is destroyed by itself but mickey
is a dangling pointer.
A good programmer's strategy is that who creates an object also
deletes it. If you want the object disappear on MouseDown use Hide
instead of deleting it.
Hope this helps.
Eric
 

Re:deleting TWinControl

"luca casotti" < XXXX@XXXXX.COM >wrote in message
Quote
void __fastcall TWin::MouseDown(TObject* Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
DestroyHandle();
delete this;
}
I highly recommend that you *do not* have the component delete itself like
that.
With that said, it is doable though, but *do not* do it in the context of an
event handler. Post a message back to the component and then delete the
component when the message is received. That will help ensure that the
component is not actually being used by anything when it is freed. For
example:
class TWin : public TWinControl
{
private:
void __fastcall CMRelease(TMessage&);
void __fastcall MouseDown(TObject* Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
//...
public:
//...
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CM_RELEASE, TMessage, CMRelease)
END_MESSAGE_MAP(TWinControl)
//...
};
void __fastcall TWin::MouseDown(TObject* Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
PostMessage(Handle, CM_RELEASE, 0, 0);
}
void __fastcall TWin::CMRelease(TMessage&)
{
delete this;
}
Gambit
 

Re:deleting TWinControl

Posting a message is a way that I have thought but is more complex.
However, if i create the OnMouseDown in TWin i can delete the object without
errors.
the problem is that i want to put a bitmap in the control background:
I do not succeed to load TWin->Brush->Bitmap;
creating a new bitmap in TWin i can't pass the OnMouseDown event to
TWin::MouseDown.
luca
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >ha scritto nel
messaggio news:401fee42$ XXXX@XXXXX.COM ...
Quote

"luca casotti" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>void __fastcall TWin::MouseDown(TObject* Sender, TMouseButton Button,
>TShiftState Shift, int X, int Y)
>{
>DestroyHandle();
>delete this;
>}

I highly recommend that you *do not* have the component delete itself like
that.

With that said, it is doable though, but *do not* do it in the context of
an
event handler. Post a message back to the component and then delete the
component when the message is received. That will help ensure that the
component is not actually being used by anything when it is freed. For
example:

class TWin : public TWinControl
{
private:
void __fastcall CMRelease(TMessage&);
void __fastcall MouseDown(TObject* Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
//...
public:
//...
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CM_RELEASE, TMessage, CMRelease)
END_MESSAGE_MAP(TWinControl)
//...
};

void __fastcall TWin::MouseDown(TObject* Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
PostMessage(Handle, CM_RELEASE, 0, 0);
}

void __fastcall TWin::CMRelease(TMessage&)
{
delete this;
}


Gambit


 

Re:deleting TWinControl

"luca casotti" < XXXX@XXXXX.COM >wrote in message
Quote
Posting a message is a way that I have thought but is more complex.
Why?
Quote
However, if i create the OnMouseDown in TWin i can delete
the object without errors.
You are missing the point. *Do Not* free the component while you are still
inside an event handler. You have no guarantees that the component won't
still be accessed once the handler returns execution flow back into the VCL.
Quote
the problem is that i want to put a bitmap in the control
background: I do not succeed to load TWin->Brush->Bitmap;
Please elaborate.
Why not just derive TWin from TCustomControl instead of TWinControl and then
draw the bitmap in its Paint() method?
Quote
creating a new bitmap in TWin i can't pass the OnMouseDown
event to TWin::MouseDown.
What EXACTLY are you trying to accomplish?
Gambit
 

Re:deleting TWinControl

My goal is to create a graphic object with a Bitmap and some StaticText.
I tryied TCustomControl and it seems work fine, but how can I create the
mouse events like OnMouseDown, OnMouseUp, DblClick and link them to some
parent window method, so that I can delete the object outside of his event
handler?
luca
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >ha scritto nel
messaggio news:40214c71$ XXXX@XXXXX.COM ...
Quote

"luca casotti" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>Posting a message is a way that I have thought but is more complex.

Why?

>However, if i create the OnMouseDown in TWin i can delete
>the object without errors.

You are missing the point. *Do Not* free the component while you are
still
inside an event handler. You have no guarantees that the component won't
still be accessed once the handler returns execution flow back into the
VCL.

>the problem is that i want to put a bitmap in the control
>background: I do not succeed to load TWin->Brush->Bitmap;

Please elaborate.

Why not just derive TWin from TCustomControl instead of TWinControl and
then
draw the bitmap in its Paint() method?

>creating a new bitmap in TWin i can't pass the OnMouseDown
>event to TWin::MouseDown.

What EXACTLY are you trying to accomplish?


Gambit


 

Re:deleting TWinControl

"luca casotti" < XXXX@XXXXX.COM >wrote in message
Quote
My goal is to create a graphic object with a Bitmap and some StaticText.
That is easy enough to do.
Quote
how can I create the mouse events like OnMouseDown, OnMouseUp, DblClick
Those events already exist in TCustomControl. They are just declared as
protected, so you need to promote them to published so that you can access
them in your form:
class TWin : public TCustomControl
{
//...
__published:
__property OnDblClick;
__property OnMouseDown;
__property OnMouseUp;
};
Quote
and link them to some parent window method, so that I
can delete the object outside of his event handler?
Again, *do not* free the instance inside of the event handler itself . You
must delay the deletion until after the component is no longer being
accessed. Thus, you still need to use a posted message either way.
Gambit
 

Re:deleting TWinControl

Ok, I will use messages
thanks
luca