Search code examples
delphibackgroundpopupfiremonkeydelphi-10-seattle

Firemonkey do stuff in background Form Delphi 10 Seattle


I've created a pop-up loadscreen Form that I want to show above any other form in a Firmonkey Multi device project. Now i've run into the problem that the loadscreen doesn't get updated with the things I do in the background Form. How can I solve this?

In the code below is an example of what i've tried:

procedure TForm1.Button1Click(Sender: TObject);
var
  loadScreen:TfrmLoadScreen;
begin
  loadScreen := TfrmLoadScreen.Create(nil);
  loadScreen.ShowModal(
    procedure(ModalResult: TModalResult)
    var
      i:Integer;
    begin
      for i := 0 to 200 do
      begin
        loadScreen.CurrentItem := i;
        loadScreen.TextMessage := 'Item:' + loadScreen.CurrentItem.ToString;
        Sleep(100);
      end;
      ModalResult := mrCancel;
    end);
end;

I guess I have to do some multi-threading, but I don't have any experience doing this! How should I do this for my loadscreen?

I've also tried the following, but the form doesn't get shown:

procedure TForm1.Button1Click(Sender: TObject);
var
  loadScreen:TfrmLoadScreen;
begin
  loadScreen := TfrmLoadScreen.Create(nil);
  loadScreen.OnShow := FormShowLoadScreen;
  loadScreen.Show;
end;

procedure TForm1.FormShowLoadScreen(Sender: TObject);
var
  i:Integer;
  loadScreen:TfrmLoadScreen;
begin
  loadScreen := TfrmLoadScreen(Sender);
  for i := 0 to 200 do
  begin
    loadScreen.CurrentItem := i;
    Sleep(100);
  end;
  loadScreen.Close; 
end;

Solution

  • In your first code block, the annonymous method is only called after loadscreen.modalresult is set to something other than 0. This never happens (that we can see)

    In your second block, you have 2 different loadscreen instances. They are not the same one. The FormShowLoadScreen handler is called after the firstly loadscreen.show, but it creates a 2nd loadscreen, with it's own displays. In fact, this might happen so fast, you wouldn't see it happen.

    You really need to learn more about Delphi multi-threading. To display a "progress" form, you will have to put it's processing (display updates) inside the synchronise event of a separate thread that is started just after the loadscreen form is shown.

    Actually... It's actually much easier in FMX to show an animation indicator before starting an annonymous thread, and then hide it again in the thread terminate block.

    See Marco Cantu's blog post here Background Operations on Delphi Android, with Threads and Timers