AGB  ·  Datenschutz  ·  Impressum  







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

Mehrfachen Schleifenaufruf verhindern

Ein Thema von sko1 · begonnen am 8. Feb 2018 · letzter Beitrag vom 9. Feb 2018
Antwort Antwort
Seite 1 von 2  1 2      
sko1

Registriert seit: 27. Jan 2017
577 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 12:12
Hallo,

ich dreh mich im Kreis und hoffe auf einen Denkanstoß:

Per WMCOPYDATA bekomme ich eine Message und diese ruft eine Procedure auf, in welcher eine Schleife abgearbeitet wird.
In dieser Schleife gibt es ein Application.Processmessages.

Wenn da aber nun wiederum eine solche Message einläuft, soll die bestehende Schleife abgebrochen und mit den Parametern der neuen Message wieder gestartet werden.

Irgendwie finde ich kein Konstrukt welches mir dies ermöglicht

Ciao
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.008 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 12:51
Application.ProcessMessages rausnehmen, herausfinden, warum das dort eingebaut wurde (in den meisten Fällen, um die UI vermutlich responsive zu halten) und es anders lösen.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.995 Beiträge
 
Delphi 12 Athens
 
#3

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 13:02
Application.ProcessMessages rausnehmen
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
sko1

Registriert seit: 27. Jan 2017
577 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 13:07
Da liegt das Problem:

Benutzer tippt in einer WPTools Tabelle...

Wenn er da z.B. im Preis tippt, wird eine Message ans Hauptprogramm generiert welches dann in einer Schleife wiederum Messages an die Tabelle sendet weil da dadurch z.B. Summenzellen geändert werden müssen.

Diese Textänderung beim Tippen wird (leider) nur durch Application.Processmessages sichtbar (oder wenn die Schleife abgearbeitet ist), es gibt in den WPTools nichts was die Anzeige neu erzwingt

Die erste Message startet also die Schleife und will 100 Zeilen auf "12,35" ändern
Während die Schleife läuft kommt eine weitere Message rein und die Schleife will 100 mal auf "34,56" ändern.

Logge ich die Messages mit sehe ich z.b.

"12,35"
"12,35"
...
"12,35"
"34,56"
"34,56"
"34,56"
... 100mal
"34,56"
"34,56"
und dann die restlichen
"12,35"
"12,35"
"12,35"
"12,35"

Wie kann ich das umgehen?
Ich denke schon an eine generische Liste der die Messages aus der Schleife übergeben werden und die dann z.B. mit Timer oder Thread abgearbeitet wird, aber während die Schleife diese Liste füllt hängt die Anzeige in der Tabelle oder die Liste wird mit Processmessages genau so gefüllt wie auch in der direkten Abarbeitung in der Schleife...

Ciao
Stefan
  Mit Zitat antworten Zitat
jziersch

Registriert seit: 9. Okt 2003
Ort: München
240 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 13:43
Hallo

Zitat:
Diese Textänderung beim Tippen wird (leider) nur durch Application.Processmessages sichtbar (oder wenn die Schleife abgearbeitet ist), es gibt in den WPTools nichts was die Anzeige neu erzwingt
Doch natürlich. Normalerweise passiert bei WPTools der Bildschirmaufbau erst in Paint, also in der nächsten Idle Phase, man kann aber sowohl das Text formatieren als auch die Bildschirmausgabe erzwingen. Dafür einfach Paint direkt aufrufen.

Kleiner Test:
Code:
  for i := 1 to 100 do
  begin
    WPRichText1.ActiveParagraph.Append(IntToStr(i));
    WPRichText1.ReformatAll;
    WPRichText1.Paint;
    Sleep(50);
  end;
Um das besagte Problem zu lösen würde ich den Event ChangeSelection und nicht OnChange, da erstere asynchron aufgerufen wird, also nicht unmittelbar nach der Eingabe. Dadurch wird dieser Event das Programm nicht so stark blockieren.

Anschliessend kann man in dem Event den Text analysieren und die Werte in der Tabelle auslesen.

Ich nehme an die Werte in der Tabelle werden anhand der ID der Zelle lokalisiert.

Anmerkung: WPTools 8 Bundle enthält Komponenten names "TWPTableProducer" bzw "TWPTableProducerDB" welche eine Tabelle im Text anhand der Daten in einem TDataset erzeugt. Auch hier wird -optional- das Dataset upgedated bei Änderungen im Text. Für kleinere Datenbestände kann man damit eine Tabelle im Text generieren, die sich sofort drucken lässt, oder auch bereichsweise kopieren für die Weiterverarbeitung, z.b. in MS Word.

Viel Erfolg
Julian
WPCubed GmbH
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 13:48
"34,56" abarbeiten, ein Flag setzen, dass es schon gemacht wurde und dadurch die Schleife mit "12,35" abbrechen.

Natürlich vor der Schleife das Flad zurücksetzen-
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
jziersch

Registriert seit: 9. Okt 2003
Ort: München
240 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 14:08
Die Tabelle, also der Editor, sollte keine Messages generieren wenn Programmcode, also der code welcher Summenzeilen berechnet, die Tabelle ändert.

Das geht mit einem

Code:
if not BinInBerechnung then
try
  BinInBerechnung := true;

  sei fleissig
finally
  BinInBerechnung := false;
end;
Die Messages mit PostMessage absetzen - sonst wird der code sofort abgearbeitet, was nicht unbedingt gut für die Performance ist. Auch hier kann man sich merken, dass man bereits die PostMessage abgesetzt hat um dies dann nicht nochmal zu machen.

WPTools macht das intern sehr oft - sie StartUpdate() in unit WPCtrMemo.
  Mit Zitat antworten Zitat
sko1

Registriert seit: 27. Jan 2017
577 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#8

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 8. Feb 2018, 14:26
Danke für die vielen Denkanstöße!

Die beiden Hinweise betreffend ChangeSelection und Paint sind erst mal die wichtigsten, wobei ich .Paint mit Sicherheit probiert habe, genau so wie .Refresh, allerdings im OnChange-Event!

Dass ChangeSelection gefeuert wird, wenn man tippt, war mir bisher nicht bewusst, man lernt halt nie aus

Dann mach ich mich mal ans Ändern...

Ciao
Stefan
  Mit Zitat antworten Zitat
sko1

Registriert seit: 27. Jan 2017
577 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#9

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 9. Feb 2018, 05:57
Zitat:
for i := 1 to 100 do
begin
WPRichText1.ActiveParagraph.Append(IntToStr(i));
WPRichText1.ReformatAll;
WPRichText1.Paint;
Sleep(50);
end;
Funktioniert, ändert aber nach langen Tests an meinem eigentlichen Problem nichts:
Im obigen Code kommen die Änderungen aus dem Code, bei mir wird das erste eingetippte Zeichen jetzt sofort angezeigt (.Paint, ich hatte immer .Repaint probiert!) aber dann kommen weitere getippte zeichen erst an wenn der Schleifencode abgearbeitet ist!

Hier werden also scheinbar die Messages der getippten Zeichen "verzögert" weitergereicht!

Ich denke hier wird eine TList mit den zu sendenden Messages und ein Thread der sich um das Versenden kümmert, die einzige saubere Lösung sein!

Darf ich in s´dem Zusammenhang einfach mal fragen (da keine Erfahrung) was bei PostMessage passiert außer dass es keine Rückmeldung gibt?
Können Messages verloren gehen oder sich die Reihenfolge des Eingangs beim Empfänger ändern?

Ciao
Stefan
  Mit Zitat antworten Zitat
jziersch

Registriert seit: 9. Okt 2003
Ort: München
240 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Mehrfachen Schleifenaufruf verhindern

  Alt 9. Feb 2018, 07:24
Hallo,

In meinem Test kommen bei dem Beispiel die Zeichen der Reihe nach. Evtl. gibt es da noch code in OnChange welcher daran was ändert.

Ich habe auch Paint in OnChange probiert, das geht auch.

Im Unterschied zu SendMessage, schreibt PostMessage die meldung in die Message loop und kehrt dann zurück. Ob die Meldung verarbeitet wird und wann, bekommt der Aufrufer nicht mit.

SendMessage ruft den MessageHandler sofort auf und kehrt zurück, wenn fertig.

>> Ich denke hier wird eine TList mit den zu sendenden Messages und ein Thread der sich um das Versenden kümmert, die einzige saubere Lösung sein!<<

Das hört sich kompliziert an. Letztendlich geht es doch darum die Tabelle nach einer Änderung auszulesen, die geänderten Werte in eine Datenbank zu schreiben und Summen zu bilden. Muss man dies denn für jeden Wert der sich ändert machen?

Ich meine es reicht dies zeitnah nach der Änderung zu machen, oder wenn der Anweder das Feld verlässt, CR drückt o.ä. Dann allerdings muss man alle Werte auslesen und die geänderten zurückschreiben. Nur die aktuelle Zelle zu überwachen erscheint mir keine gute Idee.

Wenn man nicht Werte in die Datenbank schreiben will, die nicht geändert wurden, kann man eine Liste mit Zellen (IDs) anlegen in OnChange welche bearbeitet werden. Immer wenn die Update Prozedur an der Reihe ist, kann sie diese Liste durchgehen und abarbeiten. Aus einem anderen Thread wird das nicht gehen, da von diesem kein Zugriff in WPTools möglich ist.

WPTools ist zwar threadsave, aber nur wenn es nicht für den Eingabe Modus erstellt wurde. Siehe Beispiele zur threadsave PDF erstellung.

Ich bin jetzt auf jeden Fall für ein paar Tage schlecht zu erreichen, der vorliegende Quellcode sollte aber einige Hilfestellungen bieten.

Grüsse,
Julian
WPCubed GmbH
  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 21: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