德尔福2010控制闪烁 [英] Delphi 2010 Control Flickering
问题描述
我已经从XP操作系统升级或迁移我们的软件,以便能够在Windows 7下进行编译和运行。我们的软件开始显示Windows XP中没有注意到的问题。目前,我正在处理一个用户定义的控件在TForm上闪烁。
似乎每个闪烁,而不是总是,但当它闪烁它是非常明显的。我已经为TForm和TTrendChart类设置了DoubleBuffered,但没有帮助。
I have been upgrading or migrating our software from XP OS to be able to compile and run under Windows 7. Our software is starting to show issues that we didn't notice under Windows XP. Currently, I am dealing with a user defined control flickering on a TForm. It seems to flicker every now and then not always, but when it flickers it is very noticeable. I have set DoubleBuffered for the TForm and TTrendChart Class, but it is not helping.
这是一个用户自定义的TCustomPanel控件。它应该在TForm上显示一个Live Trendchart。
This a user-defined control of TCustomPanel. It is supposed to display a Live Trendchart on a TForm.
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;
这里是如何创建的:
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;
这是如何在表单上绘制的:
Here is how it is painted on the Form:
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;
以下是如何使用它:
TrendChart := TTrendChart.Create(form);
任何帮助将不胜感激。谢谢。
Any help will be appreciated. Thank you.
推荐答案
我相信你有这个闪烁,因为你没有画出一个离屏位图。如果您首先在位图中绘制所有内容,然后最终在单个步骤中显示位图,那么您的闪烁应该会消失。
I believe you have this flickering because you are not drawing to an off-screen bitmap. If you first paint everything in a bitmap and then finally display your bitmap in a single step, then you flickering should go away.
您需要创建一个专用位图: / p>
You need to create a private bitmap:
TTrendChart = class(TCustomPanel)
private
...
fBitmap: TBitmap;
...
end;
在构造函数中写:
constructor TTrendChart.Create(AOwner:TComponent);
begin
...
fBitmap := TBitmap.Create;
// and also make the ControlStyle opaque
ControlStyle := ControlStyle + [csOpaque];
...
end;
也不要忘记desctructor:
also don't forget the desctructor:
destructor TTrendChart.Destroy;
begin
...
FBitmap.Free;
inherited;
end;
最后在 paint
您可以找到 Canvas
,将其替换为 fBitmap.Canvas
:
and finally in the paint
method, everywhere you have find Canvas
, replace it with fBitmap.Canvas
:
procedure TTrendChart.Paint;
...
begin
inherited Paint;
...
// here replace all ocurrences of Canvas with bBitmap.Canvas
...
// finally copy the fBitmap cache to the component Canvas
Canvas.CopyRect(Rect(0, 0, Width, Height), fBitmap.Canvas, Rect(0, 0, Width, Height));
end;
这篇关于德尔福2010控制闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!