![]() |
Mehrfachen Schleifenaufruf verhindern
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 |
AW: Mehrfachen Schleifenaufruf verhindern
Delphi-Quellcode:
rausnehmen, herausfinden, warum das dort eingebaut wurde (in den meisten Fällen, um die UI vermutlich responsive zu halten) und es anders lösen.
Application.ProcessMessages
|
AW: Mehrfachen Schleifenaufruf verhindern
Zitat:
|
AW: Mehrfachen Schleifenaufruf verhindern
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 |
AW: Mehrfachen Schleifenaufruf verhindern
Hallo
Zitat:
Kleiner Test:
Code:
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.
for i := 1 to 100 do
begin WPRichText1.ActiveParagraph.Append(IntToStr(i)); WPRichText1.ReformatAll; WPRichText1.Paint; Sleep(50); end; 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 " ![]() ![]() Viel Erfolg Julian ![]() |
AW: Mehrfachen Schleifenaufruf verhindern
"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- |
AW: Mehrfachen Schleifenaufruf verhindern
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:
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.
if not BinInBerechnung then
try BinInBerechnung := true; sei fleissig finally BinInBerechnung := false; end; WPTools macht das intern sehr oft - sie StartUpdate() in unit WPCtrMemo. |
AW: Mehrfachen Schleifenaufruf verhindern
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 |
AW: Mehrfachen Schleifenaufruf verhindern
Zitat:
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 |
AW: Mehrfachen Schleifenaufruf verhindern
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:22 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