(Re-) Paint von Controls verhindern

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

(Re-) Paint von Controls verhindern

Beitrag von kupferstecher »

Hallo zusammen,

wie im Betreff geschrieben suche ich eine Möglichkeit für bestimmte graphische Komponenten ein neuzeichenen zu verhindern, d.h. zeitweise zu deaktivieren. Hintergrund ist der, dass die Komponenten vom Benutzer angepasst/eingestellt und abgespeichert werden können. Beim nächsten Öffnen werden die Eigenschaften nacheinander geladen, über Setter und Getter, die jeweils ein Neuzeichen auslösen. Das macht das Laden sehr langsam. Ich möchte also das Neuzeichen deaktivieren, alle Eigenschaften laden und dann automatisches Neuzeichen wieder aktivieren. Die meisten Eigenschaften "stecken" in Child-Komponenten, das Neuzeichen muss also auch für diese unterbunden werden.

Welche Möglichkeiten gibt es? Oder macht man das ganz anders?

Viele Grüße
kupferstecher

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: (Re-) Paint von Controls verhindern

Beitrag von Warf »

kupferstecher hat geschrieben:Hallo zusammen,

wie im Betreff geschrieben suche ich eine Möglichkeit für bestimmte graphische Komponenten ein neuzeichenen zu verhindern, d.h. zeitweise zu deaktivieren. Hintergrund ist der, dass die Komponenten vom Benutzer angepasst/eingestellt und abgespeichert werden können. Beim nächsten Öffnen werden die Eigenschaften nacheinander geladen, über Setter und Getter, die jeweils ein Neuzeichen auslösen. Das macht das Laden sehr langsam. Ich möchte also das Neuzeichen deaktivieren, alle Eigenschaften laden und dann automatisches Neuzeichen wieder aktivieren. Die meisten Eigenschaften "stecken" in Child-Komponenten, das Neuzeichen muss also auch für diese unterbunden werden.

Welche Möglichkeiten gibt es? Oder macht man das ganz anders?

Viele Grüße
kupferstecher


Das brauchst du nicht, repaint/invalidate, etc sorgen dafür das die repaint Message gequeued wird. Die wird nur abgearbeitet wenn die Form idled. Solang du also in einer eigenen Methode/Funktion bist wird eh nix neugezeichnet, und der einzige overhead ist das intern irgendwo win Boolean auf true gesetzt wird.

Es gibt einiges controls bei denen ist das anders (z.b. Listbox), die haben dann aber eine beginupdate und endupdate Methode die sich darum kümmert

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: (Re-) Paint von Controls verhindern

Beitrag von kupferstecher »

Hm, dann muss ich nochmal genauer schauen wo die vielen Repaints herkommen. Ich lass mir den Aufruf einiger Setter in der Konsole auflisten, außerdem wenn die Paint-Methode von CustomControls aufgerufen wird. Und das ist schon eine beträchtliche Liste an Neuzeichnungen.

Wenn in der Queue mehrere Invalidate für das gleiche Control auflaufen, werden die dann zu einem zusammengefasst, oder trotzdem komplett abgearbeitet?

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: (Re-) Paint von Controls verhindern

Beitrag von Warf »

kupferstecher hat geschrieben:Hm, dann muss ich nochmal genauer schauen wo die vielen Repaints herkommen. Ich lass mir den Aufruf einiger Setter in der Konsole auflisten, außerdem wenn die Paint-Methode von CustomControls aufgerufen wird. Und das ist schon eine beträchtliche Liste an Neuzeichnungen.

Wenn in der Queue mehrere Invalidate für das gleiche Control auflaufen, werden die dann zu einem zusammengefasst, oder trotzdem komplett abgearbeitet?


Du solltest niemals die paint Methode selbst aufrufen, sondern immer repaint oder invalidate verwenden, um genau sowas zu vermeiden. Unter anderen widgetsets wie Carbon unter OSX kannst du außerhalb des paint Events der Lcl (also wenn du die paint Funktion per Hand aufrufst) sogar gar nicht zeichnen.

Um das handeln der Events kümmert sich Windows (oder gtk, etc.) intern, da mach dir mal keine Gedanken, das ist schon recht effizient gebaut damit nix doppelt aufgerufen wird. Also egal ob du 5 mal invalidate oder 1 mal aufrufst, es wird nur einmal gezeichnet

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: (Re-) Paint von Controls verhindern

Beitrag von kupferstecher »

Paint ruf ich nicht selber auf, sondern die Paintmethode gibt eine Statusmeldung, dass sie gerufen wurde. Sonst bekomme ich ja nicht mit, wie oft neu gezeichnet wird.
Den Grund für das Repaint hab ich jetzt gefunden. Und zwar erstelle ich immer "Screenshots" von den Komponenten mit der PaintTo-Methode von TWinControl. Das verursacht sinnvollerweise ein sofortiges Neuzeichnen. Allerdings ist das Laden immernoch langsam, trotz deaktiviertem PaintTo. Liegt wohl an etwas anderem...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: (Re-) Paint von Controls verhindern

Beitrag von wp_xyz »

Verwendest du evtl Win10? Seit einem der letzten Win-Updates werden beim Öffnen eines Formulars Unmengen von WM_ENABLE Nachrichten abgesetzt, was zu Verzögerungen von bis zu einer halben Minuten führen kann, wenn das Formular viele Controls enthält. Im aktuellen Lazarus-Trunk ist das behoben.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: (Re-) Paint von Controls verhindern

Beitrag von kupferstecher »

Hallo wp,

ich verwende Win7, mit Lazarus 1.8.0.

Gibt es eine Möglichkeit alle gerufenen Procedures protokollieren zu lassen? Also nicht nur wie man zu einer Procedure gelangt ist (Aufrufstack), sondern welche Proceduren nacheinander abgearbeitet wurden.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: (Re-) Paint von Controls verhindern

Beitrag von wp_xyz »

http://wiki.lazarus.freepascal.org/LazLogger

Nimm LazLogger mit in die Uses-Liste auf und schreibe an den Anfang jeder Routine, die du protokollieren möchtest, ein "DebugLn(<Prozedurname>, evtl Parameter)". Entferne unter Windows in den Projekt-Optionen das Häkchen vor "Win32 GUI Application", um diese Meldungen in die Konsole zu schreiben, oder rufe das Programm mit den Parameter --debug-log=dateiname auf, um sie in die genannte Datei zu schreiben. Im Gegensatz zu WriteLn gibt es keinen Absturz wenn das Häkchen bei "Win32 GUI Application" gesetzt bleibt. Es ist allerdings ratsam, die DebugLn-Aufrufe mit einem $IFDEF LOGGING o.ä. zu umgeben, damit sie nur bei Bedarf eingebunden werden.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: (Re-) Paint von Controls verhindern

Beitrag von kupferstecher »

Ich habe gehofft es gibt da was Automatisches. Mir würden auch erstmal nur die zwischen zwei Ausführungspunkten gerufenen Units reichen. Ich könnte mir ein Tool, das den Debugger nutzt oder eine Art Präprozessor, der Logging-Code einfügt, vorstellen. Oder sogar ein offline Codeanalyseprogramm, das bspw zu einer gegebenen Prozedur alle darin Aufgerufenen Prozeduren und darunter aufgerufene auflistet. Aber kann gut sein, dass es sowas nicht gibt.
Mein Problem ist einfach, dass ich kein Überblick über die Abhängigkeiten und Nebenläufigkeiten mehr hab, es handelt sich um ein schon größeres Programm.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: (Re-) Paint von Controls verhindern

Beitrag von Socke »

kupferstecher hat geschrieben:eine Art Präprozessor, der Logging-Code einfügt, vorstellen.

FPProfiler macht genau das, wobei die Auswertungen ein wenig zu Wünschen übrig lässt.

Profiling unter Windows ist ein wenig haarig, weil es zumindest für die Lazarus-Toolchain kaum brauchbare Tools gibt. Unter Linux sieht das ganze anders aus.

Für mich neu gefunden habe ich gerade LazProfiler (Wiki-Seite existiert erst seit Nov. 2017); laut Beschreibung arbeitet es ähnlich wie FPProfiler.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: (Re-) Paint von Controls verhindern

Beitrag von kupferstecher »

Hallo Socke,

hört sich gut an, Danke!

Antworten