Areslane Ait Hamouda
Areslane Ait Hamouda

Reputation: 79

delphi button vanishes when it moves for second time

i m trying to make a button moving from (0.0) to (500.500) for that i used a loop and a thread sleep procedure like in the code above :

       unit Unit1;

       interface

       uses
       Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
       Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

       type
       TForm1 = class(TForm)
          TbuttonAction: TButton;
          procedure show(Sender: TObject);
        private
         { Déclarations privées }
        public
         { Déclarations publiques }
        end;

        var
         Form1: TForm1;

       implementation

        {$R *.dfm}

       procedure TForm1.show(Sender: TObject);
        var
          i: Integer;
        begin
          TbuttonAction.Caption:='my first action';

          for i := 0 to 500 do
            begin

                 TThread.Sleep(10);
                 TbuttonAction.Top:=i;
                 TbuttonAction.Left:=i;

                end;
               end;
           end.

for the first click the button moves from 0.0 to 500.500 but if i click another time (second or third time when button is on 500.500 ) the button vanish then appear after some time. please how to fix this ? i m starting delphi today but i m good experienced (3 years) with java.

Upvotes: 1

Views: 110

Answers (1)

David Heffernan
David Heffernan

Reputation: 612794

This is happening, presumably, because you are not pumping your message queue. Windows applications require the main UI thread to service its message queue in a timely fashion so that things like painting and input can be handle. You block the main thread with your busy loop.

Remove the loop and instead add a timer. Timers operate by messages generated by the message loop and so do not block the main UI thread.

Give the timer an appropriate interval, say 100ms. When you want to start animating set the Enabled property of the timer to True.

procedure TForm1.Show(Sender: TObject);
begin
  Button1.Left := 0;
  Button1.Top := 0;
  Timer1.Interval := 100;
  Timer1.Enabled := True;
end;

Implement the timer's OnTimer event like this:

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Pos: Integer;
begin
  Pos := Button1.Left + 10;
  Button1.Left := Pos;
  Button1.Top := Pos;
  if Pos >= 500 then
    Timer1.Enabled := False;
end;

I renamed your button. The T prefix is used for types and not for instances.

As a broad guideline, Sleep should never be called in the main thread of a UI program. I don't think there are many, if indeed, any exceptions to that. Sleeping stops the UI thread from servicing its message queue.

Upvotes: 2

Related Questions