Search code examples
delphiruntimecontrolsfiremonkey

Why in Firemonkey when create controls at runtime are display when finish iteration?


I create over 100 rectangles at runtine in code below;

var
  RectT: TRectangle;
  MyThread: TThread;
  Layout1: TLayout;
begin
  MyThread := TThread.CreateAnonymousThread(procedure()
  begin
        TThread.Synchronize(nil, procedure()
        var
            z, i: integer;
        begin
            z := 0;
            for i := 0 to 99 do
            begin
                 RectT := TRectangle.Create(Self);
                 RectT.Name := 'Rectangle' + IntToStr(i);
                 RectT.Align := TAlignLayout.Top;
                 RectT.Margins.Top := 6;
                 RectT.Position.Y := z;
                 RectT.Height := 20;
                 RectT.Parent := Layout1;
                 if (i mod 10) = 0 then Layout1.UpdateEffects;
                 inc(z, 20);
            end;
        end);
  end);
  MyThread.FreeOnTerminate := True;
  MyThread.Start;

end;

Why didn't display the rectangle when is created and only are displayed when finish the iteration of all rectangles?.


Solution

  • First, you need to move the for loop in one thread and the creation of the rectangles in a Synchronize call, as Deltics has done. The difference is that you do not need the call to Repaint and you need to use the currentthread to pass the call for synchronization.

    Try this (in OnClick event of a Button):

    procedure TForm4.Button1Click(Sender: TObject);
    begin
      TThread.CreateAnonymousThread(procedure
      var
        I,z: Integer;
        Total: Integer;
      begin
        Total := 0;
        for I := 1 to 99 do
        begin
            TThread.Synchronize (TThread.CurrentThread,
              procedure
              var
                RectT: TRectangle;
              begin
                RectT := TRectangle.Create(Self);
                RectT.Name := 'Rectangle' + IntToStr(i);
                RectT.Align := TAlignLayout.Top;
                RectT.Margins.Top := 6;
                RectT.Position.Y := z;
                RectT.Height := 20;
                RectT.Parent := Layout1;
                Inc(z, 20);
              end);
        end;
      end).Start;
    end;