Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Befehlsverarbeitung unter Delphi (https://www.delphipraxis.net/130305-befehlsverarbeitung-unter-delphi.html)

stev-e87 6. Mär 2009 07:33


Befehlsverarbeitung unter Delphi
 
Guten Morgen allerseits,

ich bin mir in Bezug auf die Vorgehensweise von Delphi bei der Abarbeitung der Befehle nicht so ganz sicher. Erst der Code:

Delphi-Quellcode:
procedure TWnd_Main.tb_Load_ElementsClick(Sender: TObject);
begin
SBar.Panels[0].Text:='1. Anfordern der Bibliothek';
try
HTTP_Request('http://www.meinLink.tld','ico.xml');
SBar.Panels[0].Text:='2. Elemente laden';
Load_Elements;
finally
SBar.Panels[0].Text:='Fertig';
end;
end;
Meine Frage: Warum ändert er den Text der Statusbar erst, wenn finally eintritt? Es wird die Änderung nach Begin und die in der Mitte konsequent ausgelassen.
Hach ja, als VB Umsteiger möchte man sich wohl noch an so einige Schikane gewöhnen müssen :wink:

MfG

holliesoft 6. Mär 2009 07:41

Re: Befehlsverarbeitung unter Delphi
 
Hi,

Du solltest nach jeder Aktualisierung der Statusbar ein

Delphi-Quellcode:
Application.ProcessMessages;
einfügen, damit die Anwendung Zeit bekommt, um die Statusleiste neu zu zeichnen.

Gruß
Patrick

Chemiker 6. Mär 2009 07:44

Re: Befehlsverarbeitung unter Delphi
 
Hallo strv-e87,

Delphi-Quellcode:
try

Finally
Wird eigentlich benutzt um Fehler abzufangen.

Wenn im Block zwischen try und finally ein Fehler auftritt, wird auf jeden Fall die Anweisung nach finally ausgeführt.

Typischerweise benutzt man das um Speicher freizugeben, wenn ein Fehler aufgetreten ist.


Bis bald Chemiker

taaktaak 6. Mär 2009 07:46

Re: Befehlsverarbeitung unter Delphi
 
Moin,
diese Frage habe ich mir auch schon des öfteren gestellt. Das ProcessMessages ist zwar die Lösung, die gewünschte Anzeige zu erzwingen - allerdings ist hier die Frage, warum zwischenzeitlich keine Ausgabe erfolgt...

ChrisE 6. Mär 2009 08:02

Re: Befehlsverarbeitung unter Delphi
 
Zitat:

Zitat von taaktaak
...allerdings ist hier die Frage, warum zwischenzeitlich keine Ausgabe erfolgt...

Genau weil nach dem ändern des Textes noch sehr viel anderes gemacht wird. Das verhindert das "automatisches" Neuzeichnen des Statusbar. Es wird die gesamte Zeit dafür "verbraten" den Quelltext danach auszuführen. Da bleibt keine Zeit die Komponenten neu zu zeichnen.

Du kannst es auch ohne ProcessMessages machen durch Update / Repaint.

Gruß, Chris

hoika 6. Mär 2009 08:12

Re: Befehlsverarbeitung unter Delphi
 
Hallo,

unter VB hast du das gleiche Problem.
Dort heisst Application.ProcessMessages anders, nämlich DoEvents.
Viell. führt das VB ja selber durch.

Die Nachricht Paint hat eine sehr geringe Priorität,
deshalb wird erst mal alles andere gemacht.

Heiko

taaktaak 6. Mär 2009 08:15

Re: Befehlsverarbeitung unter Delphi
 
Aha, die niedrige Priorität - das leuchtet ein.
Danke für die Antwort :)

OlafSt 6. Mär 2009 08:18

Re: Befehlsverarbeitung unter Delphi
 
Eigentlich liegt der Hase noch ganz woanders begraben...

Tatsächlich zeichnet Delphi den Statusbar nicht sofort neu. Es stellt nur eine Nachricht in die Messageloop. Solange die nicht abgearbeitet wird, wird auch nichts neu gezeichnet.

Anstelle Application.ProcessMessages würde ich SBar.Update empfehlen.

ChrisE 6. Mär 2009 08:20

Re: Befehlsverarbeitung unter Delphi
 
Wobei ProcessMessages genau das macht was es auch sagt: Verarbeitung der Nachrichten.
Also auch der Nachricht zum Neuzeichnen des Statusbar. Das wird auch von der Anwendung automatisch ausgeführt wenn diese nichts zu tun hat. Aber der Quelltext sorgt dafür, dass dieser Zustand der "Langeweile" für das Programm eben nicht eintritt. Somit muss man das Programm manuell dazu zwingen :-)

Gruß, Chris

:-( roter Kasten von OlafSt. Du warst wohl schneller ;-)

taaktaak 6. Mär 2009 08:30

Re: Befehlsverarbeitung unter Delphi
 
Zitat:

Anstelle Application.ProcessMessages würde ich SBar.Update empfehlen
Weil damit gezielt die Anzeige der Statusbar gezeichnet wird und nicht etwaige andere wartenden Operationen ebenfalls?!

ChrisE 6. Mär 2009 08:39

Re: Befehlsverarbeitung unter Delphi
 
Zitat:

Zitat von taaktaak
Zitat:

Anstelle Application.ProcessMessages würde ich SBar.Update empfehlen
Weil damit gezielt die Anzeige der Statusbar gezeichnet wird und nicht etwaige andere wartenden Operationen ebenfalls?!

:thumb: Genau.
Hat aber auch genau diesen Nachteil. Wenn man nicht daran denkt, was noch so "abgearbeitet" werden muss, wird das eben auch nicht abgearbeitet z.B. Abbrechen-Button der geklickt wird oder so was ;-)

Gruß, Chris

Luckie 6. Mär 2009 08:53

Re: Befehlsverarbeitung unter Delphi
 
Ich denke, das das Problem wo anders liegt. Die Befehle/Funktionen werden natürlich nacheinander abgerabeitet. Das heißt, so lange der Request ausgeführt wird, passiert gar nichts. Da könnt ihr noch so oft Application.ProcessMessages aufrufen, wie ihr wollt. Dann wird der Text der Statusbar zwei mal hintereinander geändert und das geht so schnell, dass man die erste Änderung nicht sieht.

ChrisE 6. Mär 2009 08:59

Re: Befehlsverarbeitung unter Delphi
 
Zitat:

Zitat von Luckie
Ich denke, das das Problem wo anders liegt. Die Befehle/Funktionen werden natürlich nacheinander abgerabeitet. Das heißt, so lange der Request ausgeführt wird, passiert gar nichts. Da könnt ihr noch so oft Application.ProcessMessages aufrufen, wie ihr wollt. Dann wird der Text der Statusbar zwei mal hintereinander geändert und das geht so schnell, dass man die erste Änderung nicht sieht.

Also meinst du, dass der Request so schnell vorbei ist, dass man die Änderung gar nicht sieht, oder habe ich die jetzt falsch verstanden?
Denn ein Application.ProcessMessages direkt vor dem Aufruf des Request würde ja eben zunächst den Statusbar anpassen. Wenn der Request aber zu schnell vorbei ist und die zweite Änderung kommt - gepaart mit dem Application.ProcessMessages - sehe ich es nicht.

Hab ich das jetzt richtig verstanden?

Gruß, Chris

stev-e87 6. Mär 2009 09:02

Re: Befehlsverarbeitung unter Delphi
 
Danke für die vielen Antworten, nun hab ich auch einen gewissen Einblick in DelphiArchitektur ;)

PS.: Applaication.ProcessMessages funktioniert, werd das auch verwenden, falls noch andere Dinge anfallen werden. Die Änderungen der einzelnen Schritte sehe ich auf jeden Fall -> Verbindung aufbauen etc. dauert lange genug.

THX

Luckie 6. Mär 2009 09:11

Re: Befehlsverarbeitung unter Delphi
 
Zitat:

Zitat von ChrisE
Also meinst du, dass der Request so schnell vorbei ist, dass man die Änderung gar nicht sieht,

Nein, nicht der Request ist so schenll, sondern die Änderunge des Statusbartextes erfolgt so schnell. Obwohl, ich sehe gerade, da wird zwischen druch ja noch was ausgeführt. Jedenfalls kommt Windows nicht zum Ändern des Textes, weil die zeichennachrichten eine sehr geringe Priorität im System haben.

Will man so etwas sauber lösen, sollte man mit Threads arbeiten.

hazard999 6. Mär 2009 09:45

Re: Befehlsverarbeitung unter Delphi
 
Und wieder mal wird Application.ProcessMessages vorgeschlagen.

Ihr wisst aber schon das damit die MessageLoop abgearbeitet wird, oder?

Demnach wird auch jeder Timer und jedes User-Event verarbeitet (alles was halt in der MessageLoop ist).


Wozu gibt es Repaint, Refresh oder Invalidate?

Denkt mal drüber nach...

Luckie 6. Mär 2009 09:51

Re: Befehlsverarbeitung unter Delphi
 
Vielleicht will man da sja gerade, damit das Fenster noch reagiert?

hazard999 6. Mär 2009 10:07

Re: Befehlsverarbeitung unter Delphi
 
Gut.

Dann schlage ich folgendes Code-Schnipsel vor:

Delphi-Quellcode:
procedure ProcessSomeMessages;
var sMessage: string;
   mess: TMSG;
   Handled: boolean;
begin
   sMessage := '';

   while PeekMessage(mess, 0, 0, 0, Pm_Remove) do
   begin
      TranslateMessage(mess);
      case mess.message of
         WM_KEYDOWN: sMessage := sMessage + 'killed WM_KEYDOWN ';
         WM_KEYUP: sMessage := sMessage + 'killed WM_KEYUP ';
         WM_MOUSEMOVE: sMessage := sMessage + 'killed WM_MOUSEMOVE ';
         WM_LBUTTONDOWN: sMessage := sMessage + 'killed WM_LBUTTONDOWN ';
         WM_LBUTTONUP: sMessage := sMessage + 'killed WM_LBUTTONUP ';
         WM_RBUTTONDOWN: sMessage := sMessage + 'killed WM_RBUTTONDOWN ';
         WM_RBUTTONUP: sMessage := sMessage + 'killed WM_RBUTTONUP ';
         WM_MBUTTONDBLCLK: sMessage := sMessage + 'killed WM_MBUTTONDBLCLK ';
         WM_RBUTTONDBLCLK: sMessage := sMessage + 'killed WM_RBUTTONDBLCLK ';
         WM_LBUTTONDBLCLK: sMessage := sMessage + 'killed WM_LBUTTONDBLCLK ';
         WM_NCLBUTTONDOWN: sMessage := sMessage + 'killed WM_NCLBUTTONDOWN ';
         WM_TIMER: sMessage := sMessage + 'killed WM_TIMER ';
      else
         Handled := false;

         if Assigned(Application.OnMessage) then
            Application.OnMessage(mess, Handled);

         if not Handled then
            DispatchMessage(mess);
      end;
   end;
end;

weil tb_Load_ElementsClick mehrfach auszuführen weil irgendwer wie wild auf den Button drückt ist denke ich auch nicht das was er will...


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