Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Flackern eines Label/TLabel verhindern (https://www.delphipraxis.net/186563-flackern-eines-label-tlabel-verhindern.html)

MisterIXI 12. Sep 2015 00:15

Flackern eines Label/TLabel verhindern
 
Hallo zusammen,

EDIT: zur kurzen Erläuterung: Das Programm ist eine art Stoppuhr, die auf Millisekunde genau anzeigt. Das Label wird durch einen Timer der es relativ oft updatet. Bis jetzt war der auf 64, weil ich da auch tipps gelesen hatte bezüglich der 60Hz aktualisierungs Rate, damit es weniger zwischen zwei frames geupdated wird.

Ich habe das Problem, das ein durch einen TTimer geupdatetes Label ab und zu flackert.
Ich weiß dass es schon viele Threads dazu im Internet gibt, und ich habe mich durch sehr viele durchgewälzt, aber keine Lösung hat wirklich gefruchtet... Das Problem ist: es scheint für jeden Rechner anders zu sein, daher kann ich auch nicht gut testen.

Kurze Zusammenfassung, was ich bis jetzt probiert habe:
- statt einem Label ein TLabel benutzen
- Form1.DoubleBuffered:=true;
- TLabel1.DoubleBuffered:=true;
- Form1.ParentBackground:=false;
- XPManifest entfernt
- Timer auf 64 ms gesetzt (annäherung and updaterate(?))
- Windows Aero aktiviert/deaktiviert

und bereits ein paar Kombinationen.

Es scheint ja keine allgemeine Lösung zu geben - zumindest habe ich in keinem Thread bis jetzt eine gefunden - deswegen frage ich vorallem nach Erklärung warum das passiert; ob es da ein paar Tipps gibt es zumindest zu minimieren...

Es ist grade schon relativ spät, und genauer erklären was es für ein Programm ist, oder Quelltext zeigen kann ich ja auf Nachfrage. Das Problem müsste an sich ja einfach sein nach zu vollziehen...


Bin im Moment relativ hilflos da ich auch nicht genauer weiß wie das ganze rendering des Programms funktioniert und es wäre echt super, wenn sich eine Lösung finden würde! Aber das Program funktioniert ja an sich und das flackern ist nicht allzu schlimm...


Vielen Dank im Vorraus
und Liebe Grüße

Sir Rufo 12. Sep 2015 00:48

AW: Flackern eines Label/TLabel verhindern
 
Was möchtest du denn da bauen? Ein Hochgeschwindigkeits-Label-Kino?

Wenn du ein wenig mehr Zen dort hineinbringst, dann reicht auch eine Aktualisierungrate von einer Sekunde. Das kann man dann auch noch halbwegs erkennen.

Rollo62 12. Sep 2015 08:11

AW: Flackern eines Label/TLabel verhindern
 
Was zeigst du denn überhaupt an ?
Ich würde auf jeden selber Fall prüfen und nur Änderungen schreiben,
und mich nicht dabei auf das Label verlassen.

Code:
if Label1.Text <> txtNeu then
begin
  Label1.Text := txtNeu;
  ...
  Label1.Repaint;
end
Kann das helfen die Changerate zu vermindern ?

Rollo

Sir Rufo 12. Sep 2015 08:38

AW: Flackern eines Label/TLabel verhindern
 
Zitat:

Zitat von Rollo62 (Beitrag 1315594)
Kann das helfen die Changerate zu vermindern ?

Nein, denn das hier passiert beim Setzen von Caption
Delphi-Quellcode:
procedure TControl.SetText(const Value: TCaption);
begin
  if GetText <> Value then // <- aha
{$IF DEFINED(CLR)}
  begin
    FText := Value;
    Perform(CM_TEXTCHANGED, 0, 0);
  end;
{$ELSE}
  SetTextBuf(PChar(Value));
{$ENDIF}
end;
Somit ist die Überprüfung einfach nur DoppelMoppel und reduziert nichts (bremst nur ein wenig)

MisterIXI 12. Sep 2015 09:12

AW: Flackern eines Label/TLabel verhindern
 
Zitat:

Zitat von Sir Rufo (Beitrag 1315587)
Was möchtest du denn da bauen? Ein Hochgeschwindigkeits-Label-Kino?

Wenn du ein wenig mehr Zen dort hineinbringst, dann reicht auch eine Aktualisierungrate von einer Sekunde. Das kann man dann auch noch halbwegs erkennen.

Also ich habe einen relativ genauen Zeitmesser programmiert, der halt ansonsten ziemlich unflüssig aussehen würde.
Aber selbst auf deutlich langsameren Raten tritt das flackern ab und zu auf...

Und ich kann absolut keine Muster in dem ganzen erkennen. :(


Ich könnte natürlich die aktualiesieren ausbremsen und den Timer, der momentan auch Berechnungen mit der Zeit ausführt aufteilen, aber das würde halt nicht mehr so schön aussehen.

Zacherl 12. Sep 2015 13:32

AW: Flackern eines Label/TLabel verhindern
 
Wie siehts aus, wenn du statt eines Labels die PaintBox verwendest und dann diesen Trick nutzt:
http://www.delphipraxis.net/1315249-post2.html

hathor 12. Sep 2015 15:13

AW: Flackern eines Label/TLabel verhindern
 
Bei mir XE7, WIN8.1 flackert nichts.
Vielleicht liegt es daran, dass neuere WIN-Versionen die Desktop-Grafik anders behandelt.

Timer.interval:= 50;
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label2.Caption:= FormatDateTime('hh:nn:ss.zzz', Now);
end;

einbeliebigername 12. Sep 2015 16:05

AW: Flackern eines Label/TLabel verhindern
 
Hallo MisterIXI,

ich hatte/habe das gleiche Problem. Bei mir ist es die Ausgabe eines Video-Timecodes (Aktualisierungsinterval 16,66... bis 41,66... ms). Statt TLabel besser TPanel oder TStaticText verwenden. Auf jedenfalls eine Klasse welche von TWinControl stammt. Grund alles was nur von TControl und nicht von TWinConrol stammt wird vom Parent gezeichnet. Dort lassen sich Flackereffekte nur schwer abstellen. Vermutlich wirst du dir eine eigene Klasse (wie ich) bauen müssen. Dabei auf WM_ERASEBKGND achten.

einbeliebigername.

MisterIXI 12. Sep 2015 23:41

AW: Flackern eines Label/TLabel verhindern
 
Zitat:

Zitat von Zacherl (Beitrag 1315613)
Wie siehts aus, wenn du statt eines Labels die PaintBox verwendest und dann diesen Trick nutzt:
http://www.delphipraxis.net/1315249-post2.html

Wenn ich das ganze richtig verstanden und implementiert habe, dann scheint das wohl auch nicht wirklich zu klappen... Es scheint ein kleines bisschen besser geworden zu sein, aber da bin ich mir auch nicht sicher :|


Zitat:

Zitat von einbeliebigername (Beitrag 1315618)
ich hatte/habe das gleiche Problem. Bei mir ist es die Ausgabe eines Video-Timecodes (Aktualisierungsinterval 16,66... bis 41,66... ms). Statt TLabel besser TPanel oder TStaticText verwenden. Auf jedenfalls eine Klasse welche von TWinControl stammt. Grund alles was nur von TControl und nicht von TWinConrol stammt wird vom Parent gezeichnet. Dort lassen sich Flackereffekte nur schwer abstellen. Vermutlich wirst du dir eine eigene Klasse (wie ich) bauen müssen. Dabei auf WM_ERASEBKGND achten.

Hört sich für mich ähnlich zu der Antwort von Zacher an. (Ich muss dazu sagen, dass ich davor noch nie wirklich mit Klassen im Programmieren zu tun hatte :< )

Effektiv habe ich zum testen ein Panel hinzugefügt, und ein PaintBox objekt reingesetzt. Den Timer entsprechend umgeschrieben und noch folgenden Code implementiert (vom Link der Lösung von Zacher):
Code:
type
  TPanel = class(ExtCtrls.TPanel)
    procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
    end;
  TForm1 = class(TForm)
Code:
 procedure TPanel.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin
  Message.Result := 0;
end;
wobei ich diesen Wert auch auf 1 gesetzt habe und es hat wohl ein bisschen besser funktioniert (?).

einbeliebigername 13. Sep 2015 19:42

AW: Flackern eines Label/TLabel verhindern
 
Zitat:

Zitat von MisterIXI (Beitrag 1315641)
Hört sich für mich ähnlich zu der Antwort von Zacher an. (Ich muss dazu sagen, dass ich davor noch nie wirklich mit Klassen im Programmieren zu tun hatte :< )

Da hast du mich nicht vollständig verstanden. Die Lösung von Zacher ist ein TControl auf ein TWinControl gelegt. Das TControl bekommt ständig neuen Text und animiert das TWinControl sich neuzuzeichnen.

Hast du mal TStaticText ausprobiert? Oder wenn du unter dem Label/PaintBox aktuell ein Panel hast, schmeiße das Label/die PaintBox weg und setzt die Caption vom Panel. Beim Panel (auch das Panel unter dem Anzeigeelement) mit FullRepaint und ParentBackground experimentieren.

Zitat:

Zitat von MisterIXI (Beitrag 1315641)
Effektiv habe ich zum testen ein Panel hinzugefügt, und ein PaintBox objekt reingesetzt. Den Timer entsprechend umgeschrieben und noch folgenden Code implementiert (vom Link der Lösung von Zacher):
Code:
type
  TPanel = class(ExtCtrls.TPanel)
    procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
    end;
  TForm1 = class(TForm)
Code:
 procedure TPanel.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin
  Message.Result := 0;
end;
wobei ich diesen Wert auch auf 1 gesetzt habe und es hat wohl ein bisschen besser funktioniert (?).

Zum Testen kannst du das so machen, aber besser ist es ein eigene Panel-Klasse zu bauen, diese zu registrieren und im Formulardesigner dann die zu nehmen. Es sollte aber laut meinem Verständnis der Windows-Doku http://msdn.microsoft.com/en-us/libr...55(VS.85).aspx
Delphi-Quellcode:
Message.Result := 1;
sein, damit Windows nicht selbst den Hintergrund löscht/zeichnet.

einbeliebigername.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:42 Uhr.
Seite 1 von 2  1 2      

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