Link to home
Start Free TrialLog in
Avatar of Oli2
Oli2

asked on

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
Avatar of PeterLarsen
PeterLarsen

It is not possible to destroy a component in its own code.
You could activate a TTimer to do it for you.
Avatar of Oli2

ASKER

Hi, Peter!

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

Is there really no way ??

Regards, Oli
Try look at this subject in the helpfile : "TObject.Free".
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,
procedure TContentType.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if KEY = 13 then Sender.Free;
end;

works without problems....

?
Added at same time (zwarte).

Delphi 5.
Well, tried the same thing as zwarte and florisb, and did not receive any exceptions !!??!!
Dont understand this :)
:-)
Avatar of kretzschmar
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
Avatar of Oli2

ASKER

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
Avatar of Oli2

ASKER

Hi meikl,

you mean the "inherited" does it?
I'll check... be back in a minute...
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.
Avatar of Oli2

ASKER

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
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
Avatar of Oli2

ASKER

does anybody know, why my code above isn't working ?

Regards, Oli
Well Meikl, i dont see the difference :-)
Avatar of Oli2

ASKER

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
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
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
Avatar of Oli2

ASKER

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

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.
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
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
seems to be good solution, from the wide before me expert ;-)
Avatar of Oli2

ASKER

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!
"wide before me"...

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