为什么小弟我用双缓冲了,绘图还是有闪烁,用的GDI+

为什么我用双缓冲了,绘图还是有闪烁,用的GDI+
本帖最后由 wangwei244157887 于 2013-01-20 13:03:03 编辑
为什么小弟我用双缓冲了,绘图还是有闪烁,用的GDI+

想绘制上面的圆圈的旋转,在内存中,用bitmap绘制,然后绘制好了,一次性用BitBlp绘制,让圆圈旋转,可是发现旋转的时候,图形会闪烁,到底怎么样才能不闪烁呢?


procedure TForm1.Tmr_2Timer(Sender: TObject);
var
  aImg:TBitmap ;
  CirImage:TGPImage ;
  gpImg:TGPGraphics ;
  pbleft,pbtop:single ;
  RotateP:TGPPointF ;
  gpMatrix:TGPMatrix;
  gpRec:TGPRectF ;
begin
  rotateAngle :=rotateAngle -10;
  aImg:= TBitmap.Create ;
  aImg.Width :=140;
  aImg.Height:=140;
  CirImage :=TGPImage.Create(WideString(ExtractFilePath(ParamStr(0))+'Images\66.png'));
  gpImg:=TGPGraphics.Create(aImg.Canvas.Handle );
  RotateP.X :=20+60;
  RotateP.Y :=20+60;
  gpMatrix :=TGPMatrix.Create ;
  gpMatrix.RotateAt(rotateAngle,RotateP ) ;
  gpImg.SetTransform(gpMatrix );
  gpRec.X :=20;
  gpRec.Y :=20;
  gpRec.Width :=120;
  gpRec.Height :=120;
  gpImg.DrawImage(CirImage,gprec) ;
  Self.Refresh ;//强行刷新窗体,让原来画的图清除
  BitBlt(Self.Canvas.Handle  ,0,0,140,140,aImg.Canvas.Handle ,0,0,SRCAND) ;
  aImg.Free ;
  CirImage.Free ;
  gpImg.Free ;

end;

------解决方案--------------------
把事件写到paintbox里的Onpaint
定时器 传入参数和重画
  Self.Refresh ;//强行刷新窗体,让原来画的图清除   
这句不要
试试看。
------解决方案--------------------
同意6楼,OnTimer事件里只写 Form.Repaint;
而在FormOnPaint中用Canvas.Draw就行了.
------解决方案--------------------
你的InvalidateRect函数的最后一个参数是TRUE,就是要求擦除背景,只要有背景擦除一定会闪烁的,这个和你用不用多缓冲没关系,即使你不要求擦除背景,也难保delphi不会在哪一个函数里擦除背景,所以所有无效化或者会造成无效化的函数最好都不要用了。
其实最简单的办法就是重写WM_ERASEBKGND(上面的少了个GND,没记住呵呵),直接返回TRUE或者什么都不写(这只会影响到PAINTSTRUCT的一个参数,但都不会重绘背景),在WM_PAINT中进行缓冲区复制,这样就不会闪烁了。