AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Eigene Komponente mit OnClose-Event

Ein Thema von Jasocul · begonnen am 1. Jun 2015 · letzter Beitrag vom 1. Jun 2015
Antwort Antwort
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.786 Beiträge
 
Delphi 12 Athens
 
#1

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 11:51
Zitat:
kann es zu merkwürdigen Nebeneffekten kommen.
Darum muß der auch im BeforeDestruction aufgerufen werden, denn die Form sendet erst an alle Komponenten das BeforeDestruction und danach nacheinander Free/Destroy aufgerufen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.378 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:01
Das mache ich ja jetzt auch:
Delphi-Quellcode:
procedure TMyComp.BeforeDestruction;
begin
  if Assigned(FOnDestroy) then
  begin
    FOnDestroy(Self);
  end;

  inherited;
end;
In der Form sieht es dann so aus:
Delphi-Quellcode:
procedure TfrmMain.MyCompDestroy(Sender: TObject);
begin
  ShowMessage('Meine Komponente OnDestroy');
end;
Das ShowMessage wird zwar durchlaufen, aber nicht ausgeführt.
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.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:06
Also ich weiß nicht, was da nicht funtionieren sollte, denn das funktioniert hier einwandfrei:

Die Komponente
Delphi-Quellcode:
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.
und die Form
Delphi-Quellcode:
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.
Solange die Anwendung selber nicht beendet wird, erscheint immer die Message.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.378 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:12
Solange die Anwendung selber nicht beendet wird, erscheint immer die Message.
Ah, da ist unser Missverständnis. Ich erzeuge die Instanz nicht zur Laufzeit. Dementsprechend zerstöre ich diese auch nicht selbst.
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:
MessageBox(Application.Handle, 'Komponente OnDestroy', 'TMyComp', 0); Also ist nur das Handle der MainForm ungültig. Das Handle der Anwendung ist aber noch nutzbar.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:19
Solange die Anwendung selber nicht beendet wird, erscheint immer die Message.
Ah, da ist unser Missverständnis. Ich erzeuge die Instanz nicht zur Laufzeit. Dementsprechend zerstöre ich diese auch nicht selbst.
Das ist doch völlig egal, wer wann was erzeugt und wann wer was freigibt.

Es gibt hier nur eine Regel, die man beachten muss
Delphi-Quellcode:
  if not( csDestroying in Application.ComponentState ) then
    ShowMessage( 'Ich bin dann mal weg!' );
oder auf deutsch:

Wenn die Anwendung selber den Status Zerstören hat, dann darf ich bestimmte Dinge nicht mehr machen (wie. z.B. ShowMessage aufrufen).
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.786 Beiträge
 
Delphi 12 Athens
 
#6

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:20
ShowMessage wird hier wohl über CreateDialogIndirect erstellt und das reagiert auf Application.Terminated und schießt sich sofort wieder, da es so eine VCL-TForm ist.
(altes Delphi oder altes Windows)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.378 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:28
@Sir Rufo, das ist mir schon klar. Ich bin halt davon ausgegangen, dass das BeforeDestruction ausgeführt, bevor irgendwas anderes tatsächlich zerstört wird. Dies ist aber offensichtlich eine falsche Annahme gewesen. Asche auf mein Haupt.
Als Nutzer einer Komponente würde es mich allerdings schon irritieren, dass ich erst prüfen muss, ob ich in der Anwendung überhaupt ein ShowMessage aufrufen darf, wenn das gewünschte Ereignis abgearbeitet wird.

@himitsu:
Es macht zumindest den Eindruck, dass es so abläuft.
Peter
  Mit Zitat antworten Zitat
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#8

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:37
Als Nutzer einer Komponente würde es mich allerdings schon irritieren, dass ich erst prüfen muss, ob ich in der Anwendung überhaupt ein ShowMessage aufrufen darf, wenn das gewünschte Ereignis abgearbeitet wird.
Musst Du ja nicht, Du schreibst ja selbst:

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
Wenn das Programm beendet wird, wird eine WM_QUIT-Nachricht losgelassen, die die Haupt-Nachrichtenschleife beendet. Danach ist halt kein normales Arbeiten mit Windows mehr möglich.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:46
@Jasocul

Was glaubst du wohl, wieviele Nutzer von Kettensägen überrascht geschaut haben, als sie den Ast abgesägt haben auf dem sie selber gerade saßen?

Egal was man hat (Kettensäge, Komponente, ...): Man kann es richtig oder falsch verwenden.

Und das oben geschilderte Verhalten ist kein Alleinstellungsmerkmal der Kettensäge.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.378 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Eigene Komponente mit OnClose-Event

  Alt 1. Jun 2015, 12:56
@Mikkey:
Ja, ich weiß das. Aber die Kollegen, die die Komponente nutzen, sehen ja nur, dass es ein Event gibt, das sie benutzen können. Was dahinter steckt, ist erstmal uninteressant. Wenn ich in so einem Event eine Nachricht ausgeben möchte, sollte das auch passieren.

@Sir Rufo:
Natürlich muss man aufpassen, dass das, was man benutzt, auch da ist. Aber bisher war es bei mir bisher nicht erforderlich, dass ich prüfen muss, ob die Anwendung noch "existiert", in der ich den Code ablaufen lasse.
Peter
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:13 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