![]() |
AW: Merkwürdige zitternde Reskalierung einer Form nach abschalten von Zeichnen auf NC
Mh Okay.
Danke fürs testen. Muss ich dann mal weiter gucken. |
AW: Merkwürdige zitternde Reskalierung einer Form nach abschalten von Zeichnen auf NC
So, ich hoffe es ist mir erlaubt diesen Thread einmal aus der Versenkung zu holen.
Ich habe das Problem mit dem Zittern nämlich lösen können, und möchte es gerne für die Nachwelt dokumentieren. Also nochmal kurz: Wenn mein selbsgezeichneter Fensterrahmen reskaliert wurde, laggte dieser etwas hinterher. Ich konnte mir da nie einen Reim drauf machen. Jetzt weiß ich woran es lag und wer schuld ist. Wer ist Schuld? Microsoft Was genau? DWM (Desktop Window Manager, stichwort Composition) Das zuckeln tritt unter Windows7-Systemen auf(nicht bei allen, unter anderem wohl auch Treiberabhängig), undzwar aus folgendem Grund: Nur weil etwas per GDI gezeichnet wird, landet es nicht auch unbedingt sofort im Backbuffer für den DWM. Das bedeutet, dass dieser mitunter 1-2Frame alte Daten verarbeitet. Der updated den Backbuffer nämlich nur, wenn auch genug Pixeldaten vorhanden sind. Also ist die Lösung, dem DWM das ganze einfach nochmals ins Gesicht zu hauen, als ob alle Pixel(oder sehr viele) neu/geändert wären. Wie bekomm ich das nun hin? Nicht ganz cpu-sparend, aber simpel: Ich erstelle für meine Form einen TDirect2DCanvas. Und bevor ich im NCPaint oder WMPaint etwas mach(en lasse), rufe ich BeginDraw und danach EndDraw auf. Dies sorgt dafür, dass die gesamte Formoberfläche rübergeschupst wird, und die Form rendert korrekt. Hiermal ein vergleichsvideo: ![]() Über folgenden Entwickler aus dem FL-STudio Team(ebenfalls in Delphi Woot woot^^) bin ich auf diesen Hack gekommen: ![]() Kurzfassung
Delphi-Quellcode:
Grüße
unit Styles.Forms;
interface uses Classes, Types, Windows, Messages, Forms, Graphics, Direct2D; type TForm = class(Forms.TForm) private FCanvas2D: TDirect2DCanvas; procedure PaintNC(var MSG: TWMNCPaint); message WM_NCPAINT; procedure WMPaint(var MSG: TWMPaint); message WM_PAINT; public constructor Create(AOwner: TComponent); override; end; implementation uses uxTheme, Styles, Math; { TForm } constructor TForm.Create(AOwner: TComponent); begin inherited; FCanvas2D := TDirect2DCanvas.Create(Handle); end; procedure TForm.PaintNC(var MSG: TWMNCPaint); begin FCanvas2D.BeginDraw(); //paint NonClient-Stuff here FCanvas2D.EndDraw; end; procedure TForm.WMPaint(var MSG: TWMPaint); begin FCanvas2D.BeginDraw(); //we need to fill it with our background color as a Direct2D surface is black by default FCanvas2D.Brush.Color := Color; FCanvas2D.FillRect(Rect(0, 0, Width, Height)); inherited; FCanvas2D.EndDraw; end; end. Memnarch |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:27 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