Destroying own Component

Hi, guys!

How to solve this:

procedure TMyEdit.meKeyDown ( Sender: ...);
begin
if KEY = 13 then Sender.Free;
end;

meaning: I want to destroy a Component in an OnKeyPress Event of the Component.

Regards, Oli
LVL 1
Oli2Asked:
Who is Participating?
 
MadshiConnect With a Mentor Commented:
Oli, do you have the VCL sources? Then look at how TForm.Release works internally. It sends a message to its own handle, then when receiving this message, it frees itself. Something like this:

type
  TMyEdit = class (TEdit)
  private
    procedure FreeMyself(var Message: TMessage); message WM_USER + 777;
  protected
    procedure KeyPress(var KEY: Char); override;
  end;

procedure TMyEdit.FreeMyself(var Message: TMessage);
begin
  Free;
end;

procedure TMyEdit.KeyPress(var KEY: Char);
begin
  if KEY = #27 then
    PostMessage(handle, WM_USER + 777, 0, 0);
  inherited;
end;

Regards, Madshi.
0
 
PeterLarsenCommented:
It is not possible to destroy a component in its own code.
You could activate a TTimer to do it for you.
0
 
Oli2Author Commented:
Hi, Peter!

I thought of using a timer to do this.
I wouldn't like it though.

Is there really no way ??

Regards, Oli
0
[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

 
PeterLarsenCommented:
Try look at this subject in the helpfile : "TObject.Free".
0
 
zwarteCommented:
hmmm, weird,
i did this :
placed an edit field on a form and defined :

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   showmessage(inttostr(key));
   if KEY = 13 then Sender.Free;

end;

which seemed to work just fine in Delphi 2

Tom,
0
 
florisbCommented:
procedure TContentType.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if KEY = 13 then Sender.Free;
end;

works without problems....

?
0
 
florisbCommented:
Added at same time (zwarte).

Delphi 5.
0
 
PeterLarsenCommented:
Well, tried the same thing as zwarte and florisb, and did not receive any exceptions !!??!!
Dont understand this :)
0
 
florisbCommented:
:-)
0
 
kretzschmarCommented:
hi oli2,

a little sample component

unit SelfFreeEdit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TSelfFreeEdit = class(tedit)
  private
    { Private declarations }
  protected
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure TSelfFreeEdit.KeyDown(var Key: Word; Shift: TShiftState);
Begin
  If Key = VK_RETURN then Free;
  inherited;
End;

procedure Register;
begin
  RegisterComponents('Samples', [TSelfFreeEdit]);
end;

end.

maybe that helps a bit

meikl
0
 
Oli2Author Commented:
It works with a TEdit.
It doesn't work with a

type TmyEdit = class ( TEdit );

So what do I have to add to my OWN Component to make it work?

Regards, Oli
0
 
Oli2Author Commented:
Hi meikl,

you mean the "inherited" does it?
I'll check... be back in a minute...
0
 
PeterLarsenCommented:
I dont think you should use this method (free the component in its own code) because the memory could have been reallocated to other components before it return from its free.
0
 
Oli2Author Commented:
type TmyEdit = class ( TEdit )
     protected
         procedure   KeyPress ( Sender: TObject; var KEY : Char ); override;
     public
         constructor Create ( AOwner : TComponent ); override;
         destructor  Destroy; override;
     end;


procedure TmyEdit.KeyPress ( Sender: TObject; var KEY : Char );
begin
    case KEY of
    #13 : begin
             KEY := #0;
             inherited;
          end;
    #27 : begin
             Sender.Free;
             inherited;
          end;
    inherited;
    end;
end;

I get an Error while compiling:
"Decleration of KeyPress differs from previous decleration"

What am I doing wrong?

Regards, Oli
0
 
kretzschmarCommented:
well, ok peter,

this may be safer

procedure TSelfFreeEdit.KeyDown(var Key: Word; Shift: TShiftState);
Begin
  If Key = VK_RETURN then
  begin
    owner.RemoveComponent(Self); //force notifiction to other components
    Free;                        //free self
  end;
  inherited;
End;

meikl
0
 
Oli2Author Commented:
does anybody know, why my code above isn't working ?

Regards, Oli
0
 
PeterLarsenCommented:
Well Meikl, i dont see the difference :-)
0
 
Oli2Author Commented:
okay, I found it: Sender : TObject was the one that wasn't supposed to be there.

I can compile it now, but I still get an Access Violation.

Regards, Oli
0
 
PeterLarsenCommented:
Oli2,

You need to declare this event as a property :

private
 procedure DoMyOnKeyPress( Sender: TObject; var KEY : Char );
publeshed
 property OnKeyPress write DoMyOnKeyPress;

.....

procedure TSomething.DoMyOnKeyPress( Sender: TObject; var KEY : Char );
begin
end;

I have not yet tried this sample, but do think this is the way to do it.

Peter
0
 
kretzschmarCommented:
to oli:
don't know, could be that in your source is additional a third keypress-line.

to peter:
the components, where this component may be linked to, will be notified about the remove(delete) of this component.

meikl
0
 
Oli2Author Commented:
meikl:

this is the code now:

type TmyEdit = class ( TEdit )
     protected
         procedure KeyPress ( var KEY : Char ); override;
     public
         constructor Create ( AOwner : TComponent ); override;
         destructor  Destroy; override;
     end;


procedure TmyEdit.KeyPress ( var KEY : Char );
begin
    if KEY = #27 then
    begin
        owner.RemoveComponent ( Self );
        Free;
    end;
    inherited;
end;


It compiles fine, but doesn't work.
I get an Access Violation.

Regards, Oli

0
 
PeterLarsenCommented:
Well, i still think that the problem is, that by calling free you are telling Delphi that D is allowed to use the memory to other things.
0
 
kretzschmarCommented:
to oli,

tested it, and works
the sample

unit SelfFreeEdit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TSelfFreeEdit = class(tedit)
  private
    { Private declarations }
  protected
//    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress ( var KEY : Char ); override;
  public
    { Public declarations }
  published
    { Published declarations }
  end;

procedure Register;

implementation
{
procedure TSelfFreeEdit.KeyDown(var Key: Word; Shift: TShiftState);
Begin
  If Key = VK_RETURN then
  begin
    owner.RemoveComponent(Self); //force notifiction to other components
    Free;                        //free self
  end;
  inherited;
End;
}
procedure TSelfFreeEdit.KeyPress ( var KEY : Char );
begin
  if KEY = #27 then
  begin
    owner.RemoveComponent ( Self );
    Free;
  end;
  inherited;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TSelfFreeEdit]);
end;

end.

meikl
0
 
kretzschmarCommented:
seems to be good solution, from the wide before me expert ;-)
0
 
Oli2Author Commented:
Hi Madshi!
You made my day!
It works fine!

I'll give you the points and post some 50 more to each Peter and meikl for trying to help me.

Thanks, guys!
0
 
MadshiCommented:
"wide before me"...

:-)  Only 20000 points. That's not so much...   (-:
0
All Courses

From novice to tech pro — start learning today.