Hallo, ich beende mein Programm mit Application.terminate. Dabei bleibt aber in der Taskleiste das Programm stehen. Was mache ich falsch ?
Announcement
Collapse
No announcement yet.
Programm beenden ?
Collapse
X
-
Hi,
das löst das Problem aber nicht!
Application.Terminate muss das Programm korrekt verlassen! Es darf dann auch nicht mehr in der Taskleiste stehen. Ich denke, dass das Problem an ganz anderer Stelle innerhalb des Programms liegt (leise Vermutung: benutzt Du irgendwelche ActiveX-Komponenten?).
Gruss
Ul
Comment
-
Hallo Rene,
Application.Terminate sollte man schon nach Möglichkeit vermeiden.
An der Stelle von wo dieses aufgerufen wird, wird nur noch die aktive Procedure/Function zu Ende abgearbeitet und dann das Programm verlassen.
Verwende eine vernünftige Procedure zum Beenden Deines Programmes, die Du von überall aufrufen kannst, dann hast Du auch keine Probleme mehr damit, daß noch irgendwas im Speicher zurückbleibt.
Michae
Comment
-
Hallo Michael,
wo hast Du diese Information her?
Aussage der Online-Hilfe:
Terminate calls the Windows API PostQuitMessage function to perform an orderly shutdown of the application. Terminate is not immediate.
Terminate is called automatically on a WM_QUIT message and when the main form closes.
Wenn das nicht so wäre, dass beim Beeenden das Programm auf laufende Routinen wartet, bräuchte man auch nicht das Property Terminated, um laufende Routinen eventuell zu beenden, wenn sich das Programm beenden will, aber nicht kann, da ja noch Routinen laufen.
Das Problem bei René ist die ActiveX-Komponente (Windows Mediaplayer), da funktioniert das mit dem geordneten Beenden des Programms des öfteren nicht.
Wie willst Du das über eine globale Prozedur abfangen?
Gruss
Ul
Comment
-
Hallo Ulrich,
ich weiss schon was in der Online-Hilfe von Delphi steht.
Es geht aber nicht um laufende Proceduren, sondern um z.B. FormClose-Ereignisse, die definitiv nicht mehr abgearbeitet werden.
Und wenn man sich jetzt mal vorstellt, daß eine Datenbankanwendung mitten im Betrieb so beendet wird ... Das dauert mit Sicherheit nicht lange, bis man eine inkonsistente Datenbank erhält.
Michae
Comment
-
Hallo Michael,
vielen Dank für die wertvolle Information, ich denke, das ist den meisten Leuten nicht bekannt. Dass eine OnClose-Prozedur nicht abgearbeitet wird, finde ich gar nicht so schlimm, ich habe beim Experimentieren aber festgestellt, dass auch eine OnDestroy-Routine nicht abgearbeitet wird! Und das ist sehr bedenklich.
Gruss
Ul
Comment
-
Hi
OnClose wird durch eine WM_CLOSE Message an ein Fensterhandle, ausgelösst. Wird im Gegensatz dazu ein Prozess mit WM_QUIT beendet werden KEINERLEI WM_CLOSE Messages erzeugt. In bestimmten Fällen versucht nun TApplication alle OnClose bzw. OnCloseQuery Ereignisse aufzurufen. Dies hängt von der Message WM_QUIT/ WM_QUERYENDSESSION/ WM_ENDSESSION ab.
Auf jeden Fall versucht die Application alle allozierten Formulare zu zerstören. D.h. egal auf welchem Wege die Anwendung beendet wird (ausser harter Ausstieg) sollten die Formulare trotzdem ein OnDestroy() bekommen. Nun, wird aber im vorhergehenden Verlauf der Terminierung eine Exception ausgelösst wird es häufig dazu führen das eben nicht ALLE Formulare korrekt freigegeben werden. Problembehaftet sind meistens Komponenten die sich in irgendeinerweise mit globalen Hooks/Events etc. beschäftigen. Z.b. TApplicationEvents.
<b>Fazit:</b>
<li>OnClose/OnCloseQuery sollten benutzt werden um ein Schließen eines Formulars auf Grund einer Benutzeraktion zu verhindern.
Notwendige Finalisierungen/Dealocations gehören nicht hierher
<li>OnDestroy sollte auf sicherer Art die Resourcen freigeben. Z.b. das Schließen einer Tabelle (Table.Close) sollte in einem try except block geschehen. Wichtig ist nur das OnDestroy ohne Exception beendet wird.
Gruß Hage
Comment
-
Hallo Hagen,
die Wahrheit liegt wohl irgendwie in der Mitte: Nach der Nachricht von Michael war ich erst nicht sehr schockiert, dass das OnClose-Event nicht abgearbeitet wird, da ich alle wichtigen Ende-Routinen (Speicherfreigaben usw.) sowieso im OnDestroy-Event abarbeite.
Beim Testen der Nachricht von Michael habe ich dann einfach eine Application mit 2 Forms definiert (beide automatisch erzeugt). In Form2 waren die Events OnClose und OnDestroy mit einem MessageDlg belegt. Ich habe dann vom MainForm aus über Show Form2 aufgerufen und MainForm mit Application.Terminate beendet. Kein MessageDlg!
Deshalb mein Entsetzen, dass OnDestroy nicht abgearbeitet wird, auch dann nicht wenn man es folgendermassen definiert:
if MessageDlg(...) = mrOK then
Irgendetwas...
was natürlich z.B. zum Speichern geänderter Daten besonders bei MDI-Anwendungen durchaus vorkommen könnte (gut, dass ich SDI-Applikationen schreibe).
Nach Deiner Nachricht habe ich das ganze noch einmal wiederholt und mit dem Debugger den Programmablauf überwacht: Du hast recht, das OnDestroy-Event wird abgearbeitet, es kommt aber kein Message-Dialog und damit auch kein Rückgabewert des Dialogs - die Abfrage ist für die Katz!
Wie ist das zu erklären?
Gruss
Ul
Comment
Comment