在德尔福进行双缓冲

时间:2012-12-06 17:24:21

标签: delphi

使用Delphi XE2我想在delphi应用程序中移动一些按钮。

我写了这段代码:

procedure TForm1.DoSomething;
var x : integer;
begin    
   for x := 200 downto 139 do begin
       // move two buttons
      Button1.Top := x;
      Button3.Top := x;
       // skip some repaints to reduce flickering
      if (x mod 7 = 1) then begin
          Form1.Repaint;
      Sleep(50);
   end;
end;

不幸的是,在运行此程序时,它仍然会显着闪烁。

这是我的问题: 有没有办法让动画流畅(没有任何闪烁)?

修改 要使动画更流畅,请在睡眠时将50更改为更小的值(50)并删除此行:

if(x mod 7 = 1) then begin

2 个答案:

答案 0 :(得分:3)

Form1.DoubleBuffered设为True。您可以在代码中执行此操作,但我认为该属性是在XE2中发布的,因此您也可以在Object Inspector中设置它。

答案 1 :(得分:2)

我发现最好决定你想要移动多长时间,而不是使用Sleep程序。这对于不同速度的计算机更好地调整,并且还将针对移动的不同距离进行调整。如果您希望在屏幕上移动需要1秒钟,则需要在重新绘制之间移动较小的步长,而仅需要0.5秒才能在屏幕上移动。

我不记得原因,但我们还添加了重新绘制父代的代码。当我们的物体在屏幕上移动时,我认为我们遇到了鬼影的问题。

这是我们正在使用的代码。这是一个可以在屏幕上移动和移出屏幕的组件。

procedure TMyObject.ShiftRight;
var
  TicksStart: int64;
  StartLeftValue: integer;
  EndLeftValue: integer;
  NewLeftValue: integer;
  LeftValueDif: integer;
  RemainingTicks: int64;

begin
  StartLeftValue := Self.Left;
  EndLeftValue := Self.Left + Self.Width;
  LeftValueDif := EndLeftValue - StartLeftValue;

  TicksStart := GetTickCount();
  RemainingTicks := FadeTime;  // Fade Time is a constants that dermines how long the 
                               // slide off the screen should take

  while RemainingTicks > 0 do
  begin
    NewLeftValue := (LeftValueDif * (FadeTime - RemainingTicks)) div FadeTime;
    Self.Left := Max(StartLeftValue, NewLeftValue);
    Self.Parent.Repaint;
    Self.Repaint;

    RemainingTicks := FadeTime - int64(GetTickCount - TicksStart);
  end;

  if Self.Left < EndLeftValue then
    Self.Left := EndLeftValue;

  Self.Parent.Repaint;    
  Self.Repaint;
end;