Delphi 11 - Windows 64 bits
I am trying to draw various things in a TPaintBox using TDirect2D. I need to constantly update what's drawn inside. Unfortunately, my TPaintBox is flickering when I'm modifying it.
I reproduced my problem in a small simpler project.
.dfm:
object FormMain: TFormMain
Left = 0
Top = 0
Caption = 'FormMain'
ClientHeight = 968
ClientWidth = 1470
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
TextHeight = 15
object PaintBox: TPaintBox
AlignWithMargins = True
Left = 20
Top = 20
Width = 1389
Height = 928
Margins.Left = 20
Margins.Top = 20
Margins.Right = 20
Margins.Bottom = 20
Align = alLeft
OnMouseMove = PaintBoxMouseMove
OnPaint = PaintBoxPaint
end
end
.pas:
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
type
TFormMain = class(TForm)
PaintBox: TPaintBox;
procedure PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure PaintBoxPaint(Sender: TObject);
private
{ Déclarations privées }
Index: Integer;
public
{ Déclarations publiques }
end;
var
FormMain: TFormMain;
implementation
uses
Vcl.Direct2D, Winapi.D2D1;
{$R *.dfm}
procedure TFormMain.PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
PaintBox.Invalidate();
end;
procedure TFormMain.PaintBoxPaint(Sender: TObject);
var
LCanvas: TDirect2DCanvas;
Poly: array of TPoint;
begin
LCanvas := TDirect2DCanvas.Create(PaintBox.Canvas, ClientRect);
LCanvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
LCanvas.BeginDraw;
try
{ Drawing goes here }
LCanvas.Pen.Color := clRed;
LCanvas.Brush.Color := clNone;
LCanvas.Pen.Width := 5;
SetLength(Poly, 4);
Poly[0] := Point(LCanvas.Pen.Width div 2 + Index, LCanvas.Pen.Width div 2 + Index);
Poly[1] := Point(PaintBox.Width - LCanvas.Pen.Width, LCanvas.Pen.Width div 2);
Poly[2] := Point(PaintBox.Width - LCanvas.Pen.Width, PaintBox.Height - LCanvas.Pen.Width);
Poly[3] := Point(LCanvas.Pen.Width div 2, PaintBox.Height - LCanvas.Pen.Width);
LCanvas.Polygon(Poly);
inc(Index);
LCanvas.MoveTo(10, 10);
LCanvas.LineTo(PaintBox.Width - 10 - LCanvas.Pen.Width, PaintBox.Height - 10 - LCanvas.Pen.Width);
finally
LCanvas.EndDraw;
LCanvas.Free;
end;
end;
end.
Putting the form's double buffered property to true stops the flickering. But if I put the TPaintBox inside a TPanel (whose double buffered property is also set to true), it starts flickering again, which makes me think there is another problem.
I have also tried putting my TPaintBox in a frame, and adding that frame to my form (either by interface, or dynamically, and neither worked).