0

I'm moving a TMemo object left and right in my GUI application. The problem is, is that the letters in my TMemo are flickering as soon as the movement starts.

I've looked this up, and, apparently, setting the DoubleBuffering property of my main form should've helped me, but it didn't. So I tried setting that property to true on all objects that were moving, but flickering was still present.

Are there any ways to achieve flicker-free animations of GUI components in Lazarus? I'm a novice in Lazarus, so I'm kind of blindly googling for solutions right now. I would really appreciate some help.

To provide further context, here's how I animate my TMemo: I've got a TTimer with an interval value of 10, and its OnTimer event moves my TMemo left and right contiguously. To make the movement slightly smoother, I added a simple cosine interpolation function.

In the end here's the code:

procedure TServerSideForm.ControlPanelHideTimerTimer(Sender: TObject);
begin
  if (hideAnimVal < 1) then
  begin
    hideAnimVal := hideAnimVal + 0.025;
  end
  else
  begin
    MemoHideTimer.Enabled:=false;
  end;


  // hideStart - starting position of my TMemo, hideEnd - end position of my TMemo
  hideCurr := Round(CosineInterpolation(hideStart, hideEnd, hideAnimVal));

  Memo.Left:=hideCurr;
end; 

Cosine interpolation:

function CosineInterpolation(Val1, Val2, Angle: Double): Double;
var
  Percent: Double;
begin
  Percent := (1-Cos(Angle*PI))/2;
  Result := (Val1 * (1 - Percent) + Val2 * Percent);
end;
Michael
  • 548
  • 6
  • 23

1 Answers1

0

I would try to move an image instead:

var
  Memo1dc: hdc;
  Cnv: TCanvas;
  Rct: TRect;

implementation

procedure TForm1.MemoHideTimerTimer(Sender: TObject);
begin
  if Memo1.Visible then
  begin
    Memo1dc := GetDC(Memo1.Handle);
    Cnv.Handle := Memo1dc;
    Rct.Height := Memo1.Height;
    Rct.Width := Memo1.Width;
    Image1.Left := Memo1.Left;
    Image1.Top := Memo1.Top;
    Image1.Width := Memo1.Width;
    Image1.Height := Memo1.Height;
    Image1.Canvas.CopyRect(Rct, Cnv, Rct);
    Memo1.Visible := False;
    Image1.Visible := True;
  end;
  if (hideAnimVal < 1) then
  begin
    hideAnimVal := hideAnimVal + 0.025;
  end
  else
  begin
    MemoHideTimer.Enabled := False;
  end;

  // hideStart - starting position of my TMemo, hideEnd - end position of my TMemo
  hideCurr := Round(CosineInterpolation(hideStart, hideEnd, hideAnimVal));
  Image1.Left := hideCurr;
  if MemoHideTimer.Enabled = False then
  begin
    Memo1.Left := Image1.Left;
    Memo1.Visible := True;
    Image1.Visible := False;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Cnv := TCanvas.Create;
end; 
asd-tm
  • 3,381
  • 2
  • 24
  • 41