AGB  ·  Datenschutz  ·  Impressum  







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

OnTimer und Programm beenden

Ein Thema von Bea · begonnen am 4. Okt 2007 · letzter Beitrag vom 5. Okt 2007
Antwort Antwort
Bea

Registriert seit: 23. Dez 2004
53 Beiträge
 
RAD-Studio 2009 Ent
 
#1

OnTimer und Programm beenden

  Alt 4. Okt 2007, 10:19
Hallo,
ich hab ein Programm, welches sich nach dem Start mit der Komponente CoolTrayIcon in den Tray minimiert.
Mit einem Linksklick auf das Icon zeige ich mein Programm am Bildschirm an.
Mit einem Rechtsklick auf das Icon wird ein Kontexmenü mit dem Button "Beenden" sichtbar
und beim Klick auf das "Beenden" soll das Programm auch richtig beendet werden.
Das klappt auch soweit erstmal.
Nun mein Problem:
Mein Programm enthält einen Timer, der z. B. alle 5 Sekunden eine Schleife ausführt.
Klicke ich nun rechts auf meinen Beenden-Button im Tray um das Programm zu beenden,
wird beim Debuggen das OnTimer-Ereignis auch nocheinmal durchlaufen und dann passiert gar nichts,
erst wenn ich ein zweites Mal darauf geklickt habe, wird mein Programm beendet.
Woran kann das liegen?
Wieso wird das OnTimer- Ereignis nochmals durchlaufen, obwohl ich im Beenden1Click den Timer1.Enabled:=False gesetzt habe?
Und wieso wird das Programm dann nicht gleich beendet?

Hier ein paar vereinfachte Quelltextausschnitte:
Delphi-Quellcode:
// ONTIMER-EREIGNIS
procedure TForm_Connector.Timer1Timer(Sender:TObject);
begin
 Timer1.Enabled:= False; // Timer erstmal ausschalten und die Verzeichnis abarbeiten
 if bBeenden=False then
 begin
   ...
  // hier wird nun verschiedenes Zeug abgearbeitet
  // z. B. alle Dateien eines Verzeichnisses in ein anderes Verzeichnis verschieben

  Timer1.Enabled:= True; // Timer nun wieder einschalten
 end;
end;

// BEENDEN-KLICK
procedure TForm_Connector.Beenden1Click(Sender:TObject);
begin
 Timer1.Enabled:=False;
 bBeenden:= true;
 ExplicitClose:= True; // Programm soll richtig beendet werden
 self.close;
end;

// PROGRAMM IN DEN TRAY MINIMIEREN
procedure TForm_Connector.Fensterschlieen1Click(Sender:TObject);
begin
 ExplicitClose:= False;
 // Programm soll nicht beendet werden, sondern nur wieder im Tray verschwinden
 self.close;
end;

// PROGRAMM IN DEN TRAY MINIMIEREN ODER BEENDEN
procedure TForm_Connector.FormCloseQuery(Sender:TObject;
 var CanClose:Boolean);
begin
 if ExplicitClose then
  begin
   CanClose:= True;
   exit;
  end;
 // Programm soll nur über das MenüItem "Beenden" oder über das TrayIcon "Beenden" beendet werden
 // beim schließen des Fensters über das Kreuz der Form soll das Programm weiter im Tray laufen und nicht beendet werden
 CanClose:= False;
 CoolTrayIcon1.HideMainForm;
end;
Besten Dank im Vorraus!
CU Bea
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: OnTimer und Programm beenden

  Alt 4. Okt 2007, 10:32
Man kann der VCL über Application.Terminate mitteilen, dass die Anwendung beendet werden soll.
Die Anwendung wird allerdings nicht sofort beendet, sondern kann noch weiterlaufen.
Mit if Application.Terminated then ... lässt sich an strategischen Stellen überprüfen,
ob man nicht eigentlich mit der Arbeit sofort aufhören sollte.
Delphi-Quellcode:
procedure TForm_Connector.Beenden1Click(Sender:TObject);
begin
  Timer1.Enabled:=False;
  bBeenden:= true;
  Application.Terminate; // <===
  close;
end;

// PROGRAMM IN DEN TRAY MINIMIEREN ODER BEENDEN
procedure TForm_Connector.FormCloseQuery(Sender:TObject;
var CanClose:Boolean);
begin
  CanClose := Application.Terminated; // <====
  if not CanClose then
// Programm soll nur über das MenüItem "Beenden" oder über das TrayIcon "Beenden" beendet werden
// beim schließen des Fensters über das Kreuz der Form soll das Programm weiter im Tray laufen und nicht beendet werden
    CoolTrayIcon1.HideMainForm;
end;

procedure TForm_Connector.Timer1Timer(Sender:TObject);
begin
  Timer1.Enabled:= False; // Timer erstmal ausschalten und die Verzeichnis abarbeiten
  if Application.Terminated then Exit; // <====
   ...
  // hier wird nun verschiedenes Zeug abgearbeitet
  // z. B. alle Dateien eines Verzeichnisses in ein anderes Verzeichnis verschieben

  Timer1.Enabled:= True; // Timer nun wieder einschalten
end;
Andreas
  Mit Zitat antworten Zitat
Bea

Registriert seit: 23. Dez 2004
53 Beiträge
 
RAD-Studio 2009 Ent
 
#3

Re: OnTimer und Programm beenden

  Alt 4. Okt 2007, 11:37
Vielen Dank für die schnelle Antwort.
Das klappt ja auch prima.
Kann ich mir aber sicher sein, dass eine begonnene Verarbeitung in einem umfangreicheren Schleifendurchlauf im OnTimer-Ereignis
auch erst vollständig abgearbeitet wird, eh sich das Programm wirklich beendet?
Ist das damit gegeben, dass ja immer zu Beginn des eintretenden OnTimer-Ereignisses
if Application.Terminated then Exit;
aufgerufen wird?

Danke Bea
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.544 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: OnTimer und Programm beenden

  Alt 4. Okt 2007, 12:02
Wenn Du erst einmal in die Abarbeitung hineinkommst, wird diese auch durchlaufen. Beim nächsten Timer-Ereignis wird ja erst wieder geprüft, ob das Programm geschlossen werden soll und dieses ggf. vor der erneuten Abarbeitung verlassen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

Re: OnTimer und Programm beenden

  Alt 4. Okt 2007, 12:06
Zitat von Bea:
Kann ich mir aber sicher sein, dass eine begonnene Verarbeitung in einem umfangreicheren Schleifendurchlauf im OnTimer-Ereignis
auch erst vollständig abgearbeitet wird, eh sich das Programm wirklich beendet?
Ist das damit gegeben, dass ja immer zu Beginn des eintretenden OnTimer-Ereignisses
if Application.Terminated then Exit;
aufgerufen wird?
Du kannst dann sicher sein, wenn du während der Arbeit im OnTimer-Eventhandler nicht Application.ProcessMessages aufrufst.
Sollte diese Arbeit länger dauern (Schleife) dann sollte man doch prüfen, ob man diese nicht vorzeitig beenden kann. (if Application.Terminated then Exit)
Wenn die Arbeit zu lange dauert (>= 1s) entsteht beim Benutzer das Gefühl, das Programm habe sich aufgehängt.
Andreas
  Mit Zitat antworten Zitat
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#6

Re: OnTimer und Programm beenden

  Alt 4. Okt 2007, 15:03
Zitat von Bea:
...
Und wieso wird das Programm dann nicht gleich beendet?
...
CU Bea
Hallo,

es gibt keinen direkten Sprung in den Exit-Code oder sowas, das würde wohl einiges durcheinanderbringen. Der Auftrag, das Programm möge sich beenden, wird wie andere Botschaften an die Message Loop angehängt, u.U. nach einer schon eingereihten Timermessage. So wird ordentlich ein Fenster der Anwendung nach dem anderen geschlossen, das kann ja etwas dauern.

Gruss Reinhard
  Mit Zitat antworten Zitat
Bea

Registriert seit: 23. Dez 2004
53 Beiträge
 
RAD-Studio 2009 Ent
 
#7

Re: OnTimer und Programm beenden

  Alt 5. Okt 2007, 07:38
Vielen Danke für eure Antworten.
Hab jetzt an verschiedenen Stellen (vor einer längeren Verarbeitung und danach)
if Application.Terminated then Exit;
eingebaut, da kann zwischendurch nichts schief gehen denk ich.
Bis jetzt klappt alles prima.
Also nochmals vielen Dank für die Hilfe!
Bea
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#8

Re: OnTimer und Programm beenden

  Alt 5. Okt 2007, 07:49
der richtige Ansatz wäre beim Beenden-Klick den Timer abzuschalten damit er beim debugge nicht doch nochmal anspringt. Und im OnTimer wäre das abschalten und spätere wieder anschalten auch sinnvoll falls die OnTimerRoutine zu lange benötigt damit sich die Events nicht aneinanderreihen und überhäufen:
Delphi-Quellcode:
procedure TClass.TimerProc(Sender: TObject);
begin
  Timer.Enabled := False;
  //DoAnything
  Timer.Enabled := not(Application.Terminated);
end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#9

Re: OnTimer und Programm beenden

  Alt 5. Okt 2007, 07:51
Hallo,

Zusatzfrage zu diesem Umfeld:
Ich glaube (ok sollte man in die Kirche gehen ) daß auch ein Update; ähnlich wirkt wie Application.ProcessMessages; . Also eventuell hier ebenfalls aufpassen bei Schleifen. (Bin mir aber nicht zu 100% sicher)
Peter Schaible
  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 02:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz