AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde
Thema durchsuchen
Ansicht
Themen-Optionen

Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

Ein Thema von freejay · begonnen am 14. Dez 2017 · letzter Beitrag vom 15. Dez 2017
Antwort Antwort
Seite 1 von 2  1 2      
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
272 Beiträge
 
Delphi 11 Alexandria
 
#1

Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 16:22
Hallo zusammen,

vielleicht muss ich das ja auch einfach nur so hinnehmen, aber vielleicht kann man es auch verstehen und vielleicht macht das auch für irgendwas Sinn:

Ich habe ein Fenster, in dem eine Prozedur (mittels eines ButtonClicks gestartet) über einen längeren Zeitraum läuft. Diese Prozedur ruft dabei regelmäßig Application.ProcessMessages auf, damit man das Fenster trotzdem schließen und damit den Prozess abbrechen kann. Dazu habe ich das Event OnClose des Formulars gefüllt und setze dort ein Flag, dass die lang laufende Prozedur prüft und gegebenenfalls abbricht.

So weit, so simpel.

ABER:

Das funktioniert nur, wenn man das Fenster mit Show aufgerufen hat!

Wenn man das Fenster mit ShowModal aufruft, dann wird - trotz Application.ProcessMessages - das OnClose-Event erst ausgelöst bzw. verarbeitet, wenn der laufende Prozess (das ButtonClick-Event) vollständig durchgelaufen ist!

Da rollen sich mir glatt die Fußnägel auf!

Kann mir das irgendwer begründen/erklären?

PS: Ich habe das mit einem frischen Projekt getestet, bei dem das vom Hauptformular geöffnete zweite Formular nur einen Button und folgenden Code hat:

Delphi-Quellcode:
procedure TfSubWindow.btDoSomethingClick(Sender: TObject);
var
  OldTime: TDateTime;
begin
  OldTime := now;

  while SecondsBetween(Now,OldTime) < 10 do
    Application.ProcessMessages;
end;

procedure TfSubWindow.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Beep;
end;
Das Beep wird erst nach dem END von btDoSomethingClick ausgeführt, falls das Formular mit ShowModal geöffnet wurde...
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 16:39
ShowModal wartet, bis dein ButtonClick fertig ist und schließt erst dann das Fenster, weil es erst nach Rückkehr den ModalResult auswerten kann, wenn der Code im ShowModal wieder ausgeführt wird.


Wer mit Application.ProcessMessages die Abarbeitung der Messages verschachtelt, der soll sich nicht wundern, wenn da etwas bissl anders arbeitet.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
272 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 16:47
Ich habe mir schon gedacht, dass irgendwer ProcessMessages ankritteln wird...

Aber wie könnte man denn das "ich will einen laufenden Prozess über einen Cancel-Button abbrechen lassen können" sonst lösen?

Um die Benutzung eines Cancel-Buttons zu erlauben, muss ich doch ProcessMessage verwenden, oder? Auch wenn ich den Prozess in einen anderen Thread stecke, muss ich doch auf das Ende des Threads mit ProcessMessages warten?

Und sobald ProcessMessages ins Spiel kommt, kann man halt auch den CloseButton drücken. Nur verhält sich der dann recht eigenwillig...
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
Wosi

Registriert seit: 29. Aug 2007
59 Beiträge
 
#4

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 17:05
- Lager die langläufige Routine in einen Thread aus
- Halte eine Referenz auf den Thread (Wichtig ist hierbei, dass FreeOnTerminate nicht gesetzt ist)
- Wenn Abbrechen geklickt wird, rufst du Thread.Terminate auf
- In dem Thread prüfst du regelmäßig ob Terminated gesetzt wurde
- Beim Schließen des Fensters rufst du Thread.Free auf. Damit wartest du automatisch bis der Thread auch wirklich fertig ist
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 17:08
Das ist eine Konstellation, auf die die VCL nicht direkt ausgelegt ist.

Schau mal, ob vielleicht OnCloseQuery vorher getriggert wird. Dann könntest Du dort ein Flag setzen und dies für einen vorzeitigen Abbruch der Schleife prüfen.
Ansonsten gibt es vielleicht eine Message, die man noch abfangen kann.
Aber so etwas kann dann auf späteren Delphi-Versionen oder auf verschiedenen Windows-Versionen und -Rechnern schon wieder ganz anders laufen.

Vielleicht kannst Du Dein SubFormular ja auch durch ein Panel ersetzen, das Du einfach in Dein Hauptformular einsetzt.


Grundsätzlich ist sicher sinnvoll, solche längeren Aufgaben in Threads auszulagern. Dazu muss man dann aber auch die konkreten Zuständigkeiten der einzelnen Formulare klären...
ProcessMessages ist immer mit Vorsicht zu genießen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
272 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 17:15
[/QUOTE]
- Lager die langläufige Routine in einen Thread aus
- Halte eine Referenz auf den Thread (Wichtig ist hierbei, dass FreeOnTerminate nicht gesetzt ist)
- Wenn Abbrechen geklickt wird, rufst du Thread.Terminate auf
- In dem Thread prüfst du regelmäßig ob Terminated gesetzt wurde
- Beim Schließen des Fensters rufst du Thread.Free auf. Damit wartest du automatisch bis der Thread auch wirklich fertig ist
Ok, und wie prüfe ich jetzt im Formular, ob der Thread fertig ist?
Damit ich z.B. Buttons wieder enablen/disablen kann?
Da fällt mir nur ein TimerEvent (nicht sehr elegant) ein oder eine CallbackProzedur, die der Thread anstößt. Hm...
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
Wosi

Registriert seit: 29. Aug 2007
59 Beiträge
 
#7

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 17:19
http://docwiki.embarcadero.com/Libra...ad.OnTerminate
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
272 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 17:21
Das ist eine Konstellation, auf die die VCL nicht direkt ausgelegt ist.

Schau mal, ob vielleicht OnCloseQuery vorher getriggert wird. Dann könntest Du dort ein Flag setzen und dies für einen vorzeitigen Abbruch der Schleife prüfen.
Ansonsten gibt es vielleicht eine Message, die man noch abfangen kann.
Aber so etwas kann dann auf späteren Delphi-Versionen oder auf verschiedenen Windows-Versionen und -Rechnern schon wieder ganz anders laufen.

Vielleicht kannst Du Dein SubFormular ja auch durch ein Panel ersetzen, das Du einfach in Dein Hauptformular einsetzt.


Grundsätzlich ist sicher sinnvoll, solche längeren Aufgaben in Threads auszulagern. Dazu muss man dann aber auch die konkreten Zuständigkeiten der einzelnen Formulare klären...
ProcessMessages ist immer mit Vorsicht zu genießen.
Nee, OnCloseQuery verhält sich leider genauso - das hatte ich schon ausprobiert. Ich hab das Problem ja auch nur, weil ich das Fenster modal öffnen muss, sonst geht das mit OnClose und OnCloseQuery alles problemlos.

Natürlich ist ProcessMessages irgendwie etwas Getrickse, aber ich finde, dass man in vielen (einfacheren) Fällen damit sehr gut (und problemlos) arbeiten kann, ohne einen großen Overhead für eine andere Lösung basteln zu müssen. Aber in diesem Fall geht's wohl nicht...
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
272 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 17:23
Jaaa, vielleicht sollte ich mir doch angewöhnen, sowas immer rein eventbasiert zu lösen. Und nicht mit lustigen "While ThreadNochLäuft ProcessMessages"-Schleifen...
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Verrückte Eventreihenfolge, wenn Fenster mit ShowModal geöffnet wurde

  Alt 14. Dez 2017, 22:29
Aber wie könnte man denn das "ich will einen laufenden Prozess über einen Cancel-Button abbrechen lassen können" sonst lösen?
Genauso wie bei Threads? (Thread.Terminate und IF-Self.Terminated im Thread)

Deine Schleife muß eben auch auf die Beendigung ragieren.
Delphi-Quellcode:
while (SecondsBetween(Now,OldTime) < 10) and (ModalResult = mrNone) do
  Application.ProcessMessages;
Und das gilt nicht nur für dein modales Fenster, sonden auch für die ganze Anwendung.
Delphi-Quellcode:
while (SecondsBetween(Now,OldTime) < 10) and (ModalResult = mrNone) and not Application.Terminated do
  Application.ProcessMessages;
OnClose und OnCloseQuery werden im DoClose aufgerufen.
Buttons mit ModalResult und TForm.Close setzen eben nur den Status "Liebes Fenster, du darfst dich beenden", aber das wird eben nur/erst im ShowModal ausgewertet, wenn man ihm auch die Möglichkeit dazu gibt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (14. Dez 2017 um 22:32 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 23:10 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