![]() |
Problem mit Invalidate
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Ihrs
Ich habe ein kleines Problem, das mit einer Zeichenroutine zu tun hat. Das ganze hat mit der Spectrum-Anzeige meines Players zu tun: ![]() Die Anzeige bleibt einfach irgendwann stehen (friert ein), wenn ich wie folgt vorgehe:
Delphi-Quellcode:
Wenn ich das ganze aber so mache, dann funktioniert alles Prima. Der einzige Nachteil ist, das die CPU Last ziemlich steigt (was man bei älteren CPU's merkt).
...
procedure TMainForm.MainTimerEvent(Sender: TObject); begin Spectrum.Draw; end; ... type TSpectrum = class (TPanel) ... end; ... procedure TSpectrum.Draw; begin // mach was: Zeichne in Buffer ... BitBlt(self.Canvas.Handle, 0, 0, FBuffer.Width, FBuffer.Height, FBuffer.Canvas.Handle, 0, 0, SRCCOPY); end; ...
Delphi-Quellcode:
Weiss, denn einer Rat? Wird bei dem Invalidate noch irgendetwas anderes gemacht?
...
procedure TMainForm.MainTimerEvent(Sender: TObject); begin Spectrum.Invalidate; end; ... type TSpectrum = class (TPanel) ... end; ... procedure TSpectrum.Paint; begin Draw; end; procedure TSpectrum.Draw; begin // mach was: Zeichne in Buffer ... BitBlt(self.Canvas.Handle, 0, 0, FBuffer.Width, FBuffer.Height, FBuffer.Canvas.Handle, 0, 0, SRCCOPY); end; ... Danke MFG |
Re: Problem mit Invalidate
Invalidate vermerkt nur das Neuzeichnen, fasst mehrere als "dreckig" markierte Bereiche zusammen und löst dann irgendwann ein neuzeichnen aus. Folgende Tipps:
1. Der Canvas deiner Form hat eine Eigenschaft ClipRect, welches den zu aktualisierenden Bereich enthält. Der Bereich ausserhalb dieses Rechtecks braucht nicht gezeichnet zu werden, alle Zeichenoperationen werden unterdrückt bzw. sind umsonst. Daher passe dein BitBlt() an: 1a. Du kannst im Paint überhaupt mal schauen, ob du den Bereich des BitBlt() überhaupt zeichnen musst 1b. Passe BitBlt() so an, dass er nur noch den wirklich nötigen Teil malt.
Delphi-Quellcode:
2. Wenn du was neuzeichnen willst, dann markiere nicht immer die gesamte Form als "dreckig" mit Invalidate, sondern nur den Bereich, der wirklich neu gezeichnet werden muss (z.B. nur der Balken der sich geändert hat). Dazu nutze InvalidateRect()
Var
lSectionRect, lDrawRect: TRect; Begin lDrawRect := Rect(0, 0, FBuffer.Width, FBuffer.Height); If IntersectRect(Canvas.ClipRect, lDrawRect, lSectionRect) Then Begin BitBlt(Canvas.Handle, lSectionRect.Left, lSectionRect.Top, lSectionRect.Right - lSectionRect.Left, lSectionRect.Bottom - lSectionRect.Top, FBuffer.Canvas.Handle, lSectionRect.Left, lSectionRect.Top, SRCCOPY); End; End; /EDIT: Du kannst ruhig mehrere InvalidateRect() Aufrufe machen - Windows fügt diese dreckigen Bereiche zusammen und optimiert die Malbereiche im Paint auch dahingehend. Das ist auch ein Vorteil zur Optimierung, da man so schon einige Paint Aufrufe sparen kann. |
Re: Problem mit Invalidate
So, jetzt hab ichs durch langes austesten eine Lösung gefunden!!! Eigentlich ziemlich einfach (die CPU Auslastung ist auch bei meinem Rechner auf durchschnittlich schnucklige 4% gesunken).
Guckst du hier:
Delphi-Quellcode:
MFG
...
procedure TMainForm.MainTimerEvent(Sender: TObject); begin Spectrum.Draw; end; ... type TSpectrum = class (TPanel) ... end; ... procedure TSpectrum.Draw; begin // mach was: Zeichne in Buffer ... self.Canvas.Brush.Style:= bsClear; // <-------- diese Zeile ROCKT!!!!!!!!! BitBlt(self.Canvas.Handle, 0, 0, FBuffer.Width, FBuffer.Height, FBuffer.Canvas.Handle, 0, 0, SRCCOPY); end; ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:36 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