Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Merkwürdige zitternde Reskalierung einer Form nach abschalten von Zeichnen auf NC (https://www.delphipraxis.net/174662-merkwuerdige-zitternde-reskalierung-einer-form-nach-abschalten-von-zeichnen-auf-nc.html)

Memnarch 5. Mai 2013 15:11

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.

Memnarch 13. Feb 2014 19:32

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:
http://www.youtube.com/watch?v=vyQYidyRS_c

Über folgenden Entwickler aus dem FL-STudio Team(ebenfalls in Delphi Woot woot^^) bin ich auf diesen Hack gekommen:
http://stackoverflow.com/questions/1...-in-win7-8-gdi

Kurzfassung
Delphi-Quellcode:
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.
Grüße
Memnarch


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:27 Uhr.
Seite 2 von 2     12   

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