Delphi 2010 Control Flickering
Fui atualizando ou migrando nosso software do sistema operacional XP para poder compilar e executar no Windows 7. Nosso software está começando a mostrar problemas que não notamos no Windows XP. Atualmente, estou lidando com um controle definido pelo usuário que oscila em um TForm. Parece piscar de vez em quando nem sempre, mas quando pisca é muito perceptível. Eu configurei DoubleBuffered para a classe TForm e TTrendChart, mas não está ajudando.
Este é um controle definido pelo usuário do TCustomPanel. Ele deve exibir um gráfico de tendências ao vivo em um TFor
TTrendChart = class(TCustomPanel)
private
fCount:integer;
fColors:array[0..7] of TColor;
fNames:array[0..7] of string;
fMinText:string16;
fMaxText:string16;
fShowNames:Boolean;
fMaxTextWidth:integer;
data:TList;
Indexer:integer;
chartRect:TRect;
fWidth:integer;
fHeight:integer;
firstTime:Boolean;
function GetColors(Index:integer):TColor;
procedure SetColors(Index:integer; const value :TColor);
function GetNames(Index:integer):string;
procedure SetNames(Index:integer; const value: string);
procedure SetCount(const value : integer);
procedure rShowNames(const value : Boolean);
procedure SetMaxText(const value:string16);
procedure SetMinText(const value:string16);
procedure RecalcChartRect;
protected
procedure Resize; override;
procedure Paint; override;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure PlotPoints(p1,p2,p3,p4,p5,p6,p7,p8:real);
procedure ClearChart;
procedure Print;
property TrendColors[Index:integer]: TColor read GetColors write SetColors;
property TrendNames[index:integer]: string read GetNames write SetNames;
published
property TrendCount: Integer read fCount write SetCount default 8;
property ShowNames: Boolean read fShowNames write rShowNames default true;
property MaxText:string16 read fMaxText write SetMaxText;
property MinText:string16 read fMinText write SetMinText;
property Align;
property Alignment;
property BevelInner;
property BevelOuter;
property BevelWidth;
property DragCursor;
property DragMode;
property Enabled;
property Caption;
property Color;
property Ctl3D;
property Font;
property Locked;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnMouseDown;
property OnMouseUp;
property OnMouseMove;
property OnResize;
end;
Aqui como ele foi criado:
constructor TTrendChart.Create(AOwner:TComponent);
var
i:integer;
tp:TTrendPoints;
begin
inherited Create(AOwner);
Parent := TWinControl(AOwner);
fCount := 8;
fShowNames := true;
Caption := '';
fMaxText := '100';
fMinText := '0';
fMaxTextWidth := Canvas.TextWidth('Bar 0');
firstTime := true;
BevelInner := bvLowered;
data := TList.Create;
Indexer := 0;
RecalcChartRect;
DoubleBuffered:=true;
for i := 0 to 10 do
begin
tp := TTrendPoints.Create(0.0 + 0.1 * fWidth,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
data.Add(tp);
end;
for i := 0 to 7 do
begin
case i of
0: fColors[i] := clMaroon;
1: fColors[i] := clGreen;
2: fColors[i] := clOlive;
3: fColors[i] := clNavy;
4: fColors[i] := clPurple;
5: fColors[i] := clFuchsia;
6: fColors[i] := clLime;
7: fColors[i] := clBlue;
end;
fNames[i] := Format('Line %d',[i]);
end;
end;
Aqui está como é pintado no Formulário:
procedure TTrendChart.Paint;
var
oldColor:TColor;
dataPt:TTrendPoints;
i,j:integer;
curx:integer;
count,step:integer;
r:TRect;
begin
inherited Paint;
oldcolor := Canvas.Pen.Color;
Canvas.Brush.Color:=clWhite;
r.Left:=chartRect.Left-25;
r.Right:=chartRect.Right+11;
r.Top:=chartRect.Top-11;
r.Bottom:=chartRect.Bottom+22;
Canvas.FillRect(r);
if FirstTime then
begin
count := Indexer - 1;
end
else
count := data.Count - 2;
{ Draw minute lines }
Canvas.Pen.Color := clBtnShadow;
i := chartRect.left + 60;
while i < chartRect.Right do
begin
Canvas.Moveto(i, chartRect.top);
Canvas.LineTo(i, chartRect.bottom);
i := i + 60;
end;
{ Draw value lines }
step := (chartRect.bottom - chartRect.top) div 5;
if step > 0 then
begin
i := chartRect.bottom - step;
while i > (chartRect.top + step - 1) do
begin
Canvas.Moveto(chartRect.left,i);
Canvas.LineTo(chartRect.right,i);
i := i - step;
end;
end;
{ Draw Pens }
for j := 0 to fCount - 1 do
begin
Canvas.Pen.Color := fColors[j];
dataPt := TTrendPoints(data.Items[0]);
Canvas.MoveTo(chartRect.left,PinValue(round(chartRect.bottom - (fHeight * dataPt.pnts[j] / 100.0)),
chartRect.top,chartRect.bottom));
for i := 1 to count do
begin
dataPt := TTrendPoints(data.Items[i]);
if i <> Indexer then
begin
Canvas.LineTo(chartRect.left+i,PinValue(round(chartRect.bottom - (fHeight * dataPt.pnts[j] / 100.0)),
chartRect.top,chartRect.bottom));
end
else
begin
Canvas.MoveTo(chartRect.left+i,PinValue(round(chartRect.bottom - (fHeight * dataPt.pnts[j] / 100.0)),
chartRect.top,chartRect.bottom));
end;
end;
end;
r := chartRect;
InflateRect(r,1,1);
Canvas.Pen.Color := clBtnShadow;
Canvas.moveto(r.left,r.top);
Canvas.lineto(r.right,r.top);
Canvas.lineto(r.right,r.bottom);
Canvas.lineto(r.left,r.bottom);
Canvas.lineto(r.left,r.top);
{ draw index line }
// Canvas.Pen.Color := clWhite;
Canvas.Pen.Color := clBlack;
Canvas.MoveTo(chartRect.Left + Indexer,chartRect.top);
Canvas.LineTo(chartRect.left + Indexer, chartRect.bottom+1);
Canvas.Pen.Color := oldcolor;
Canvas.Font.COlor := clBlack;
Canvas.TextOut(chartRect.left-Canvas.TextWidth(string(fMinText))-2,chartRect.Bottom-8,string(fMinText));
Canvas.TextOut(chartRect.left-Canvas.TextWIdth(string(fMaxText))-2,chartRect.top-8,string(fMaxText));
if fShowNames then
begin
curx := 32;
for i := 0 to fCount - 1 do
begin
Canvas.Font.Color := fColors[i];
Canvas.TextOut(curx,chartRect.bottom+4,fNames[i]);
curx := curx + fMaxTextWidth + 16;
end;
end;
end;
Aqui está como se usaria:
TrendChart := TTrendChart.Create(form);
Qualquer ajuda será apreciada. Obrigado