Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi application beendet sich nicht (https://www.delphipraxis.net/27159-application-beendet-sich-nicht.html)

Borti 5. Aug 2004 09:41


application beendet sich nicht
 
Hallo!
ich hab grad das problem, dass sich mein Programm nichgt beendet. Mit dem folgendem Code gebe ich erstmal den speicher für meine Form1 frei und zeige gleich anschließend meine Form2 an.
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.Release;
  Form2.ShowModal;
end;
Wenn ich jedoch dann Form2.close aufrufe schließt sich zwar auch meine 2.Form, aber die application läuft für den Benutzer unsichtbar weiter. Erst mit application.terminate beendet sich auch die gesammte Anwendung. Aber warum?
Danke,
Borti

Jelly 5. Aug 2004 09:46

Re: application beendet sich nicht
 
Hallo,
Um eine Delphi Anwendung zu beenden, kannst du alternativ entweder
Delphi-Quellcode:
form1.close ;
verwenden, oder
Delphi-Quellcode:
application.terminate ;
.

Bei der ersten Variante muß form1 dein Hauptformular sein.

Gruß,

MaBuSE 5. Aug 2004 10:28

Re: application beendet sich nicht
 
Zitat:

Zitat von Borti
Hallo!
ich hab grad das problem, dass sich mein Programm nichgt beendet. Mit dem folgendem Code gebe ich erstmal den speicher für meine Form1 frei und zeige gleich anschließend meine Form2 an.
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.Release;
  Form2.ShowModal;
end;
Wenn ich jedoch dann Form2.close aufrufe schließt sich zwar auch meine 2.Form, aber die application läuft für den Benutzer unsichtbar weiter. Erst mit application.terminate beendet sich auch die gesammte Anwendung. Aber warum?

OH
Mit Release können Sie das Formular aus dem Speicher entfernen.

Release gibt das Formular erst frei, nachdem die Ausführung der Ereignisbehandlungsroutinen des Formulars und seiner untergeordneten Komponenten beendet ist. Die Methode stellt auch sicher, daß alle Botschaften in der Ereigniswarteschlange des Formulars vor dessen Freigabe bearbeitet werden. Jede Ereignisbehandlungsroutine für das Formular oder für dessen untergeordnete Objekte sollte Release anstelle von Free (Delphi) oder Delete (C++) benutzen. Ansonsten kann ein Speicherzugriffsfehler auftreten.

Hinweis: Release gibt die Steuerung sofort an die aufrufende Routine zurück und wartet nicht, bis das Formular freigegeben wird.


Also Release entfernt "nur" das Formular.

Das wird auch klar wenn man sich den Quelltext der VCL anschaut.
Delphi-Quellcode:
...
  TCustomForm = class(TScrollingWinControl)
  private
    ...
    procedure CMRelease(var Message: TMessage); message CM_RELEASE;
    ...
  public
    ...
    procedure Release;
    ...
  end;
...
procedure TCustomForm.CMRelease;
begin
  Free;
end;
...
procedure TCustomForm.Release;
begin
  PostMessage(Handle, CM_RELEASE, 0, 0);
end;
...
Wenn Du ein Formular schliessen willst, dann nimm Form1.Close;

OH
Beschreibung

Mit Close können Sie ein Formular schließen.

Versuche, ein Formular zu schließen, können mit dem Ereignis-Dispatcher CloseQuery oder der Ereignisbehandlungsroutine für OnCloseQuery abgebrochen werden.

Hinweis: Wenn Sie das Hauptformular der Anwendung schließen, wird das Programm beendet.


Im Quelltext der VCL findet sich die Lösung zu dem Geheimniss.

Delphi-Quellcode:
procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
    if CloseQuery then
    begin
      if FormStyle = fsMDIChild then
        if biMinimize in BorderIcons then
          CloseAction := caMinimize else
          CloseAction := caNone
      else
        CloseAction := caHide;
      DoClose(CloseAction);
      if CloseAction <> caNone then
        if Application.MainForm = Self then Application.Terminate  
        else if CloseAction = caHide then Hide
        else if CloseAction = caMinimize then WindowState := wsMinimized
        else Release;
    end;
end;
Man beachte:
Delphi-Quellcode:
if Application.MainForm = Self then Application.Terminate
Es wird also bei Form1.Close ein Application.Terminate aufgerufen.

In Deinem Programm kannst Du das so machen:

Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.Hide;
  Form2.ShowModal;
  Form1.Close;
end;
Damit ist Deine Frage beantwortet.

btw: Es gibt auch den Befehl Halt zum beenden einer Applikation :mrgreen: Den sollte man aber nicht verwenden... (siehe OH).

ps: Hurra, das ist mein 200. Beitrag (ohne K&T) ich bin nun "Advanced Member" :party:

Borti 6. Aug 2004 10:28

Re: application beendet sich nicht
 
Tut mir leid MaBuSE,
Die Form1 existiert trotzdem im Hintergrund weiter. Man kann sie zwar nicht sehen, durch Form1.Hide, aber wenn man diese Zeile weglässt bleibt die Form inaktiv im Hintergrund. Ich muss den Speicher für Form1 aber unbedingt freigeben bevor Form2 angezeigt wird.
Gruß,
Borti

Nuclear-Ping 6. Aug 2004 10:51

Re: application beendet sich nicht
 
Warum musst du unbedingt den Speicher von Form1 freigeben, bevor Form2 erscheint?

Wenn Form1 deine Hauptform ist und du diese freigibst beendest du damit dein Programm. Wurde ja schon öfter erwähnt. ;)

Grüße,
Mario

MaBuSE 6. Aug 2004 11:01

Re: application beendet sich nicht
 
Zitat:

Zitat von Borti
Tut mir leid MaBuSE,
Die Form1 existiert trotzdem im Hintergrund weiter. Man kann sie zwar nicht sehen, durch Form1.Hide, aber wenn man diese Zeile weglässt bleibt die Form inaktiv im Hintergrund. Ich muss den Speicher für Form1 aber unbedingt freigeben bevor Form2 angezeigt wird.
Gruß,
Borti

In diesem Fall mußt Du (wie Du ja selbst schon erkannt hast) ein Application.Terminate aufrufen.

Wenn Du das Form1 mit Form1.Realease freigegeben hast, kannst Du natürlich kein Form1.Close mehr ausführen, da Form1 ja nicht mehr existiert :-)

Aber Application.Terminate ist der sichere Weg.

Auf Application.MainForm kann leider nur lesend zugegriffen werden, sonst wäre ja folgendes möglich:
Delphi-Quellcode:
Application.MainForm := Form2; Form2.Show; Form1.Close;
Aber das geht ja nicht :-/

Bleiben also nur noch 3 Möglichkeiten übrig:

1. Eine eigene TmyApplication erzeugen:

In der Unit Forms ist TApplication definiert. Du könntest Dir eine eigene myForms schreiben, in der Du TmyApplication von TApplication ableitest.
In der TApplication.Run müsstest Du dann folgende Schleife um Deine Überprüfung ob alle Forms freigegeben sind ergänzen
Delphi-Quellcode:
procedure TApplication.Run;
begin
  FRunning := True;
  try
    ...
      repeat
        try
          HandleMessage;
        except
          HandleException(Self);
->       If KeineFormsMehrDa then Application.Terminate;
        end;
      until Terminated;
    end;
  finally
    FRunning := False;
  end;
end;
Das ist aber nicht ganz so einfach... Viel Spaß

2. Die Forms.pas von Delphi abändern

Tu Dir einen Gefallen und mach das nicht.
Falls doch, siehe 1.

3. Class Helper benutzen

In Delphi 8 (nur .net) und hoffentlich auch in Delphi 9 (auch win32) gibt es die sogenannten ClassHelper
Damit könnte man die Klasse TApplication von außen um diese Funktionalität ergänzen.


Andere Möglichkeiten sehe ich im Moment nicht.

MaBuSE 6. Aug 2004 11:04

Re: application beendet sich nicht
 
Zitat:

Zitat von Nuclear-Ping
Wenn Form1 deine Hauptform ist und du diese freigibst beendest du damit dein Programm. Wurde ja schon öfter erwähnt. ;)

Das stimmt nicht!
Das ist ja sein Problem!

Das Freigeben aleine (Form1.Release;) reicht nicht aus.
Nur ein Application.MainForm.Close; beendet auch die App.
(Application.Mainform = Form1)

Nuclear-Ping 6. Aug 2004 11:29

Re: application beendet sich nicht
 
Meinte auch mit Freigeben = Close.

Mir ist nur nicht klar, warum er das unbedingt so haben muss und was er damit bezweckt.

MaBuSE 6. Aug 2004 12:30

Re: application beendet sich nicht
 
Zitat:

Zitat von Nuclear-Ping
Mir ist nur nicht klar, warum er das unbedingt so haben muss und was er damit bezweckt.

Das weiß ich auch nicht.

Aber die Frage:
Zitat:

Zitat von Borti
Erst mit application.terminate beendet sich auch die gesammte Anwendung. Aber warum?

ist nun beantwortet. -> offene Frage bitte schliessen.
Danke


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