Delphi 2010 Control Flickering

99封情书 提交于 2019-12-04 07:06:53

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.

You need to create a private bitmap:

TTrendChart = class(TCustomPanel)
private
  ...
  fBitmap: TBitmap;
  ...
end;

in the constructor write:

constructor TTrendChart.Create(AOwner:TComponent);
begin
  ...
  fBitmap := TBitmap.Create;
  // and also make the ControlStyle opaque
  ControlStyle := ControlStyle + [csOpaque];
  ...
end;

also don't forget the destructor:

destructor TTrendChart.Destroy;
begin
  ...
  fBitmap.Free;
  inherited;
end;

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;
  • It looks like you don't use keyboard input for your control. Nor is it likely that you want to put other controls on this chart. And when you also could do without the OnEnter and OnExit events, then it is completely safe to inherit from the more lightweight TGraphicControl.

  • If you fill the entire bounding rect of the control with custom drawing, then you don't have to call inherited Paint within the overriden Paint routine.

  • If you dó want the possibility of keyboard focus, then you should certainly try to inherit from TCustomControl like Andreas Rejbrand mentioned.

  • If you want your control to (partly) look like a Panel, then keep it a TCustomPanel. But in that case, maybe the ParentBackground property is partly the cause of the flickering for that is handled in inherited Paint. Set it to False.

And as a general tip: to eliminate background refreshing prior to painting the canvas:

type 
  TTrendChart = class(TCustomPanel)
  private
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    ...

procedure TTrendChart.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  { Eat inherited }
  Message.Result := 1; // Erasing background is "handled"
end;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!