Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Abstrakter Fehler (https://www.delphipraxis.net/41088-abstrakter-fehler.html)

Martin W 25. Feb 2005 19:02


Abstrakter Fehler
 
Also ich hab folgendes Problem. Also ich hab eine anweundung mit 3 Formen. Die Formen haben die Namen:

- form_a
- form_b
- form_c

form_a wird beim Programmstart automatisch erzeugt, form_b und form_c nicht. (eingestellt in Projekt > Optionen).

Beim Klick auf einen Button auf form_a wird form_b erzeugt und angezeigt. Der Code lautet:

Delphi-Quellcode:
  with Tform_b.Create(form_a) do
    begin
      Show;
    end;

Auf Form_b ist auch wieder ein Button, der form_c erstellt und anzeigt, code ist wieder:

Delphi-Quellcode:
  with Tform_c.Create(form_a) do
    begin
      Show;
    end;

Im OnClose von form_b und form_c steht

Delphi-Quellcode:
self.free;
Wenn ich jetzt ein Fenster schließe klappt das auch prima, arbeitsspeicher wird freigegeben. ABER wenn ich ein Fenster (form_b oder form_c) mit

Delphi-Quellcode:
self.close;
schließe, kommt ne fehlermeldung, die lautet:

---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Fire_Supportabteilung.exe ist eine Exception der Klasse EAbstractError aufgetreten. Meldung: 'Abstrakter Fehler'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK Hilfe
---------------------------




Hinweise zur Fehleranalyse:

Hab mal versucht dass "self.free" aus OnClose auszuschneiden und direkt aufzurufen... es kam der selbe Fehler! Was soll ich tun???

Danke für antworten im vorraus =)

Gruß
Martin W.

mirage228 25. Feb 2005 19:07

Re: Abstrakter Fehler
 
Hi,

Du kannst Dir einmal das Delphi-Referenz durchsuchenOnClose Ereignis des Forms anschauen.

Alternativ kannst Du versuchen das Form Modal anzuzeigen.

PseudoCode
Delphi-Quellcode:
with TForm.Create(SomeOwner) do
try
  ShowModal();
finally
  Free;
end;
Du musst nur achten die ModalResult Eigenschaft bei deinem "Verlassen"-Button zu setzen, falls Du kein Schließen Kreuz auf Deinem Fenster anzeigen lässt.

mfG
mirage228

Martin W 25. Feb 2005 19:12

Re: Abstrakter Fehler
 
Modal ist keine Lösung... der Benutzer muss bei mir zwischen mehreren Formen hin- und her wechsel können.

Khabarakh 25. Feb 2005 19:30

Re: Abstrakter Fehler
 
Brauchst du die Fenster mehrmals? Wenn nicht, erstelle doch alle Forms beim Programmstart und verwende dann Delphi-Referenz durchsuchenHide und Delphi-Referenz durchsuchenShow. Dann hast du drei Variablen und keine AVs.
afair gibt es Krach, weil im Eventhandler der Form diesselbe freigegeben wird oder täusche ich mich da?

PS: Bin ich blind oder gibt es dein OH-Button nicht mher?

Martin W 25. Feb 2005 20:15

Re: Abstrakter Fehler
 
Ja, ich brauch die Fenster unbestimmt oft.. da ist ja das Problem!

teebee 25. Feb 2005 21:07

Re: Abstrakter Fehler
 
Im OnClose entweder Release verwenden statt Free oder Action auf caFree setzen.

Gruß, teebee

Hansa 25. Feb 2005 21:18

Re: Abstrakter Fehler
 
Dieser Fehler ist lästig. Er läßt sich aber nicht vermeiden. In deinem Programm steckt vermutlich eine als "abstract" deklarierte Methode drin. Also ist nur der Kopf der procedure deklariert und sonst nichts. Wird diese Prozedur nun nicht in abgeleiteten Classes als override und mit notfalls leerem procedure-Rumpf deklariert, dann kommt "abstrakter Fehler" ohne Adresse usw.

So kenne ich das. Es könnte aber auch was ganz anderes sein. :mrgreen:

Martin W 26. Feb 2005 09:23

Re: Abstrakter Fehler
 
Zitat:

Zitat von teebee
Im OnClose entweder Release verwenden statt Free oder Action auf caFree setzen.

Gruß, teebee

Wie meinst du das genau?


Zitat:

Zitat von Hansa
Dieser Fehler ist lästig. Er läßt sich aber nicht vermeiden. In deinem Programm steckt vermutlich eine als "abstract" deklarierte Methode drin. Also ist nur der Kopf der procedure deklariert und sonst nichts. Wird diese Prozedur nun nicht in abgeleiteten Classes als override und mit notfalls leerem procedure-Rumpf deklariert, dann kommt "abstrakter Fehler" ohne Adresse usw.

So kenne ich das. Es könnte aber auch was ganz anderes sein. :mrgreen:

Ich hab aber keine Prozedure mit "Abstract" oder sonst was versehen...

teebee 26. Feb 2005 10:02

Re: Abstrakter Fehler
 
Zitat:

Zitat von Martin W
Wie meinst du das genau?

Schau Dir in der Online-Hilfe mal die Parameter von OnClose an! "Action" ist genau für das vorgesehen, was Du vorhast. (Übrigens hat Dich mirage228 schon in der ersten Antwort darauf aufmerksam gemacht...)
Oder schau Dir die Methode Release von TCustomForm an! Es gibt übrigens eine F1-Taste...

Gruß, teebee

Hansa 26. Feb 2005 11:49

Re: Abstrakter Fehler
 
Zitat:

Zitat von Martin W
...Ich hab aber keine Prozedure mit "Abstract" oder sonst was versehen...

Du vielleicht nicht. Aber ist eventuell eine Fremdkomponente im Spiel ?

Robert_G 26. Feb 2005 11:58

Re: Abstrakter Fehler
 
Zitat:

Zitat von Hansa
Zitat:

Zitat von Martin W
...Ich hab aber keine Prozedure mit "Abstract" oder sonst was versehen...

Du vielleicht nicht. Aber ist eventuell eine Fremdkomponente im Spiel ?

Würde ich auch sagen.
Du kannst die meisten Antworten hier getrost als "Im Trüben fischen" abtun. ;)
Ab du nun Release, Free oder "Frag's Pferd was auch immer" aufrufst ist doch total Bohne. Du verwendest eine Instanz einer abstrakten Klasse. Und beim Ausführen einer nicht überschriebenen Methode knallt es eben. (Was vom Autor der Klasse sicher auch so gewollt ist ;) )
Da du immer noch nicht den Inhalt deines OnClose Handlers gezeigt hast würde ich auch im Trüben fischen.
Deshalb gibt's von mir nur eine Fehlerbeschreibung. Rücke etwas Code raus und man kann dir sicher helfen. ;)

Martin W 26. Feb 2005 16:02

Re: Abstrakter Fehler
 
So.. mal die gesamte Form wo es "knallt"


Delphi-Quellcode:
unit neues_produkt_unit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ComCtrls, jpeg, JvGIF, ExtCtrls;

type
  Tneues_produkt_form = class(TForm)
    Image1: TImage;
    Image3: TImage;
    Label1: TLabel;
    Label2: TLabel;
    Label23: TLabel;
    Image2: TImage;
    Image4: TImage;
    Label8: TLabel;
    Label7: TLabel;
    Image7: TImage;
    Image8: TImage;
    StatusBar1: TStatusBar;
    BitBtn1: TBitBtn;
    Edit1: TEdit;
    Edit2: TEdit;
    Label3: TLabel;
    Edit3: TEdit;
    Button1: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  neues_produkt_form: Tneues_produkt_form;

implementation

{$R *.dfm}

procedure Tneues_produkt_form.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  self.free;
end;

procedure Tneues_produkt_form.Button1Click(Sender: TObject);
begin
  self.close;
end;

end.

Beim Klick auf Button1 knallt es dann mit der oben gennanten Fehlermeldung.

mirage228 26. Feb 2005 16:11

Re: Abstrakter Fehler
 
Hi,

Das führt zwangsweise zu einem Abstraktem Fehler:
Delphi-Quellcode:
procedure Tneues_produkt_form.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  self.free;
end;
Besser ist dann das:
Delphi-Quellcode:
procedure Tneues_produkt_form.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action := caFree;
end;
Dann kannst Du auch Self.Close(); weglassen.

mfG
mirage228

Martin W 26. Feb 2005 16:16

Re: Abstrakter Fehler
 
Hey, das klappt ja echt prima... aber warum führt "self.free" zwangsweise zu einem abstrakten Fehler ?!?

Danke noch mal!!!!


Gruß
martin

teebee 26. Feb 2005 16:21

Re: Abstrakter Fehler
 
Das hättest Du früher haben können...

Warum ausgerechnet ein abstrakter Fehler auftritt weiss ich nicht (vielleicht hat ja jemand eine schlüssige Erklärung), aber prinzipiell ist es falsch, eine Komponente in einem eigenen Eventhandler freizugeben, damit zieht sie sich quasi selbst den Boden unter den Füßen weg.
Deshalb der Umweg über caFree in OnClose. In einem OnClick einer Form würdest Du Release aufrufen.

Gruß, teebee

Martin W 26. Feb 2005 16:30

Re: Abstrakter Fehler
 
Ok, dann trotzdem noch mal danke für alle Antworten *freu*

Gruß

sniper_w 26. Feb 2005 17:35

Re: Abstrakter Fehler
 
Zitat:

aber warum führt "self.free" zwangsweise zu einem abstrakten Fehler ?!?
Weil es ein Logik Fehler von dir war. Man sollte nie die Methode Free in einem Objekt aufrufen , damit es sich selbst "befreit". Eine Klasse wird immer von eine Andere "befreit" (oder von einem Thread), aber nicht in sich selbst.

So geht das:
Delphi-Quellcode:
var
  [b] Form1: TForm1; [/b]
  [b] Form2: TForm1; [/b]

procedure [b]TForm1[/b].Button1Click(Sender: TObject);
begin
 [b]Form2[/b].Free;
end;
Oder umgegehert.
Zwar wird es keine Exep. geben im Fall dass du so was schreibst:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
 self.Free; // Oder nur Free
end;
Aber MainThread bleibt immer noch da, wird nicht beendet, weil das ganze die Logik von VCL nicht folgt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:41 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