AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Semi-Modalen Dialog erstellen

Ein Thema von BigAl · begonnen am 18. Okt 2021 · letzter Beitrag vom 18. Okt 2021
Antwort Antwort
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
504 Beiträge
 
Delphi 12 Athens
 
#1

Semi-Modalen Dialog erstellen

  Alt 18. Okt 2021, 06:50
Hallo zusammen,

ich benötige immer wieder einen Fortschrittsdialog wie "Aktion läuft, bitte warten" etc. Dafür habe ich ein Formular erstellt bei dem ich bei Bedarf einen Fortschrittsbalken einblenden oder einen Abbruch-Button anzeigen kann. Das ganze wird dann über einen managed record gewrappt, damit der Dialog einfach verwendet werden kann. Im einfachsten Fall einfach den Dialog als lokale Variable definieren und die Updates aufrufen. Beim verlassen des Gültigkeitsbereich wird dann automatisch aufgeräumt...

Bei den Updates (Fortschrittstext, Fortschrittsbalken) wird dann jeweils ein "Application.ProcessMessages" durchgeführt, damit z.B. der Abbruch-Button aktualisiert wird und auch Windows mitbekommt, dass die Anwendung noch am Leben ist. Hier kommt aber schon das Problem. Der Dialog sollte eigentlich den Rest der Applikation sperren, also Modal sein. Allerdings soll das Programm, welches den Dialog nutz weiter ausgeführt werden. ShowModal fällt also flach, da dann die Kontrolle an den Dialog geht und das aufrufende Programm dann warten muss bis der Dialog beendet ist.

Wie löst ihr sowas in VCL?

Alex
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.277 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Semi-Modalen Dialog erstellen

  Alt 18. Okt 2021, 06:57
Hallo,
benutze die Suchfunktion des Forums.

https://www.delphipraxis.net/79498-i...showmodal.html
Heiko

Geändert von hoika (18. Okt 2021 um 06:59 Uhr)
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
504 Beiträge
 
Delphi 12 Athens
 
#3

AW: Semi-Modalen Dialog erstellen

  Alt 18. Okt 2021, 07:25
Hast ja recht Habe aber entweder die falschen Suchparameter eingegeben oder war zu dämlich... Damit dieser Thread aber nicht ganz nutzlos bleibt hier die Lösung die ich mir jetzt zusammengesucht habe:

TfrmProgress:
Delphi-Quellcode:
  TfrmProgress = class(TForm)
  private
    FWindowList: Pointer;
  protected
    procedure DoShow; override;
    procedure DoHide; override;
  end;
Und dann implementiert wie folgt:
Delphi-Quellcode:
procedure TfrmProgress.DoShow;
// Make the dialog "semi modal".
begin
  FWindowList := DisableTaskWindows(Application.Handle);
  inherited;
end;

procedure TfrmProgress.DoHide;
// Ensure the application gets back the control...
begin
  inherited;
  if Assigned(FWindowList) then
  begin
    EnableTaskWindows(FWindowList);
    FWindowList := nil;
  end;
end;
Funktioniert hervorragend. Genau was ich wollte.
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)

Geändert von BigAl (18. Okt 2021 um 07:28 Uhr)
  Mit Zitat antworten Zitat
BerndS

Registriert seit: 8. Mär 2006
Ort: Jüterbog
492 Beiträge
 
Delphi 12 Athens
 
#4

AW: Semi-Modalen Dialog erstellen

  Alt 18. Okt 2021, 07:42
Ich habe das bei mir so gelöst, dass ich einen modalen Dialog anzeige, während die Arbeit in einen Thread gemacht wird.
Der Thread wird dem Dialog übergeben um über den Abbrechen- Schalter den Thread terminieren zu können.
Gestartet wird den Thread im OnShow.
Der Thread selber schließt den Dialog über OnTerminate.

Der Thread selber führt im Execute eine Klassenmethode aus.
Der Vorteil ist, dass die Anwendung nicht blockiert, wenn es mal etwas länger dauert.
Gerade wenn die nicht klar ist, wie schnell z.B. eine Antwort von einem Server kommt oder es zu einem Timeout kommen kann, ist das von Vorteil.

Das ist sicher etwas aufwendiger als dir vorherige Lösung, zumal hier auch eine eigene Fehlerbehandlung gemacht werden muss.
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
504 Beiträge
 
Delphi 12 Athens
 
#5

AW: Semi-Modalen Dialog erstellen

  Alt 18. Okt 2021, 07:48
Hallo Bernd,

Du hast natürlich recht. Solch eine Lösung habe ich auch, aber die ist immer mit mehr Aufwand verbunden. Diese nutze ich ich eigentlich immer nur dann, wenn ich vom übergeordneten Programm kein zyklisches Update sicherstellen kann. Das ist aber sehr selten der Fall, deshalb die zweite Lösung. Hat halt den Vorteil, dass das ganze - speziell mit dem managed record - sehr einfach in der Handhabung ist:

Delphi-Quellcode:
var
  Progress: TProgress;
begin
  for var I := 0 to 1000 do
  begin
    Progress.UpdateProgress(Format('Progress: %.1f', [I / 10]), I / 1000);
    if Progress.Canceled then
      Break;
    Sleep(10);
  end;
end;
Und das könnte man noch weiter optimieren wenn man z.B. das "UpdateProgress" als Funktion macht, welche den Status von "Canceled" zurück gibt... Die managed records waren für mich wirklich ein riesiger Sprung nach vorne und lassen mich C++ doch etwas weniger vermissen .
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
BerndS

Registriert seit: 8. Mär 2006
Ort: Jüterbog
492 Beiträge
 
Delphi 12 Athens
 
#6

AW: Semi-Modalen Dialog erstellen

  Alt 18. Okt 2021, 08:07
Hallo Alex,
ich habe das auch nicht überall konsequent so gemacht.
Durch das gelegenliche aufrufen von Application.ProcessMessages wirk dann die Animation von TProgessbar etwas hackelig.
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
504 Beiträge
 
Delphi 12 Athens
 
#7

AW: Semi-Modalen Dialog erstellen

  Alt 18. Okt 2021, 08:19
Das mit dem "hakelig" hängt von der Anwendung ab, bzw. wie oft man es aufruft. Aber es lässt sich halt sehr gut der tatsächlich Fortschritt anzeigen, da man absolut synchron zu der Verarbeitung ist. Üblicherweise sind die Update-Raten bei mir auch sehr hoch. Da wirke ich dann normalerweise damit entgegen, dass ich nur alle 250ms oder so eine tatsächliche Aktualisierung durchführe. Ansonsten verbraucht der Dialog selbst wieder zu viel Rechenzeit.

Eine Idee wäre natürlich nur das "ProcessMessages" intern Thread-gesteuert zu machen. Dann wäre der Dialog immer gut bedienbar, auch wenn mal eine Sekunde kein Update vom Hauptprogramm kommt. Modal ist er ja jetzt, was keine unerwünschten Nebeneffekte mehr zulassen sollte. Auch sollte man das nicht zu oft machen (s.o.), da "ProcessMessages" tweilweise doch relativ viel Rechenzeit in Anspruch nimmt. Allerdings ist das "Cancel" bei mir eh nur für Ausnahmesituationen, welche hoffentlich nie benötigt werden...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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