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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
PeterLarsenCommented:
Try look at this subject in the helpfile : "TObject.Free".
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

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
MadshiCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.