![]() |
Eigene Komponente mit OnClose-Event
Ich stehe gerade auf dem Schlauch oder habe ein Brett vor dem Kopf. ganz wie ihr wollt.
Ich habe eine Komponente programmiert, die jetzt ein OnCreate- und ein OnDestroy-Ereignis bekommen soll. Die Komponente ist abgeleitet von TComponent. Das OnCreate funktioniert inzwischen, nachdem ich den üblichen Standard-Source in die protected Methode Loaded eingebaut (AfterConstruction war zu früh) habe:
Delphi-Quellcode:
Aber OnDestroy bereitet mir noch Probleme.
procedure TMyComp.Loaded;
begin inherited; if Assigned(FOnCreate) then begin FOnCreate(self); end; BeforeDestruction ist zu spät. Mache ich es mit Message-Handling, ist die Applikation offensichtlich schon nicht mehr verfügbar. Zumindest habe ich keinen Zugriff mehr. Ein einfaches ShowMessage wird schon nicht mehr angezeigt, obwohl fehlerfrei durch den Source gelaufen wird (Debugger). Google spuckt auch nichts Brauchbares aus (oder ich stelle die falsche Frage). Weiß jemand, wie es richtig geht und kann mir das verraten? |
AW: Eigene Komponente mit OnClose-Event
Ich habe es jetzt erstmal im BeforeDestruction eingebaut.
Damit sollte die Komponente zumindest die zur Zeit geplanten Routinen im OnDestroy abarbeiten können. Anwender-Benachrichtigungen mit ShowMessage gehen so allerdings leider nicht. |
AW: Eigene Komponente mit OnClose-Event
Bei einer Komponente ist BeforeDestruction das Früheste, was es gibt.
Ausnahme, wenn z.B. in der Form ein Code eingebaut wurde, welcher die Komponente rechtzeitig informiert. (leider gibt es kein TComponent.BeforeClose, zu dem TComponent.Loaded und TObject.BeforeDestruction) Bei Forms gibt es noch OnCloseQuery und OnClose, aber das wird natürlich nicht aufgerufen, wenn im Programm Form.Free azfgerufen wird, sondern nur beim Form.Close. |
AW: Eigene Komponente mit OnClose-Event
Danke himitsu.
Dann bin ich also doch nicht zu blöd, etwas entsprechendes zu finden. :-D |
AW: Eigene Komponente mit OnClose-Event
Man kann durchaus in so einem
Delphi-Quellcode:
Event mit ShowMessage arbeiten ... wenn man etwas beachtet:
OnDestroy
Delphi-Quellcode:
procedure TFooForm.MyComponentDestroy( Sender: TObject );
begin if not csDestroying in Application.ComponentState then ShowMessage( 'Bin dann mal weg!' ); end; |
AW: Eigene Komponente mit OnClose-Event
Nette Idee, funktioniert aber nicht. Ich habe es vorsichtshalber auch nochmal getestet. ShowMessage wird auf keinen Fall ausgeführt. :wink:
Eigentlich ist das Verhalten auch korrekt. Wenn die Form zerstört wird, bekommen alle Komponenten, deren Owner die Form ist, die Nachricht, sich zu zerstören. Wenn eine Komponente jetzt im eigenen Destroy einen Event-Handler bekommt, kann es zu merkwürdigen Nebeneffekten kommen. Allein der Zugriff auf andere Komponenten, die auf der Form liegen, kann zu unkontrollierbaren Zugriffsverletzungen führen. Klar kann man die Erstellungsfolge beeinflussen, aber eine Komponente sollte schon richtig gekapselt sein. Dieses Problem kann mich natürlich auch im BeforeDestruction treffen, aber es handelt sich um eine firmeninterne Komponente, die dann entsprechend dokumentiert ist. Das, was die Komponente in dem Ereignis machen soll, funktioniert problemlos. Nur eine Rückmeldung an den Anwender müssen wir gegebenenfalls anders lösen. Normalerweise ist die Rückmeldung aber nicht erforderlich. |
AW: Eigene Komponente mit OnClose-Event
Zitat:
|
AW: Eigene Komponente mit OnClose-Event
Das mache ich ja jetzt auch:
Delphi-Quellcode:
In der Form sieht es dann so aus:
procedure TMyComp.BeforeDestruction;
begin if Assigned(FOnDestroy) then begin FOnDestroy(Self); end; inherited; end;
Delphi-Quellcode:
Das ShowMessage wird zwar durchlaufen, aber nicht ausgeführt.
procedure TfrmMain.MyCompDestroy(Sender: TObject);
begin ShowMessage('Meine Komponente OnDestroy'); end; Wenn ich die Variante von Sir Rufo verwende, ist die Bedingung im If nicht erfüllt. Dementsprechend ist das Verhalten dann identisch, bis auf die zusätzliche Prüfung. |
AW: Eigene Komponente mit OnClose-Event
Also ich weiß nicht, was da nicht funtionieren sollte, denn das funktioniert hier einwandfrei:
Die Komponente
Delphi-Quellcode:
und die Form
unit MyComponent;
interface uses System.Classes; type TMyComponent = class( TComponent ) private FOnDestroy: TNotifyEvent; protected procedure NotifyOnDestroy; public procedure BeforeDestruction; override; published property OnDestroy: TNotifyEvent read FOnDestroy write FOnDestroy; end; implementation { TMyComponent } procedure TMyComponent.BeforeDestruction; begin NotifyOnDestroy( ); inherited; end; procedure TMyComponent.NotifyOnDestroy; begin if Assigned( FOnDestroy ) then FOnDestroy( Self ); end; end.
Delphi-Quellcode:
Solange die Anwendung selber nicht beendet wird, erscheint immer die Message.
unit Unit2;
interface uses MyComponent, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm2 = class( TForm ) Button1: TButton; Button2: TButton; procedure FormCreate( Sender: TObject ); procedure Button1Click( Sender: TObject ); procedure Button2Click( Sender: TObject ); procedure FormClose(Sender: TObject; var Action: TCloseAction); private FMyComponent: TMyComponent; procedure CreateMyComponent; procedure MyComponentDestroy( Sender: TObject ); public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.Button1Click( Sender: TObject ); begin FreeAndNil( FMyComponent ); end; procedure TForm2.Button2Click( Sender: TObject ); begin CreateMyComponent( ); end; procedure TForm2.CreateMyComponent; begin FreeAndNil( FMyComponent ); FMyComponent := TMyComponent.Create( Self ); FMyComponent.OnDestroy := MyComponentDestroy; end; procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; procedure TForm2.FormCreate( Sender: TObject ); begin CreateMyComponent( ); end; procedure TForm2.MyComponentDestroy( Sender: TObject ); begin if not( csDestroying in Application.ComponentState ) then ShowMessage( 'Ich bin dann mal weg!' ); end; end. |
AW: Eigene Komponente mit OnClose-Event
Zitat:
Die MainForm der Anwendung wird geschlossen und somit auch die Anwendung. Das Handle der MainForm ist dann im Event schon nicht mehr verfügbar. Was allerdings funktioniert ist folgendes:
Delphi-Quellcode:
Also ist nur das Handle der MainForm ungültig. Das Handle der Anwendung ist aber noch nutzbar.
MessageBox(Application.Handle, 'Komponente OnDestroy', 'TMyComp', 0);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz