0

I have a Delphi project that consists of two forms namely MainForm and DialogForm. When I click on Button1, the DialogForm should appear and stay on top until a process complete (the process takes a few seconds to complete).

The DialogForm includes a Timage component. When I click on the Button1 to show the DialogForm, the Gif image appears but without animation. This happens only when the process starts (without the process the animation works). What is the reason for this and how to keep the animation until closing the DialogForm?

procedure TMainForm.Button1Click(Sender: TObject);
var
  gif: TGIFImage;
begin
  Enabled:=false;
  try
        DialogForm.Show;
        DialogForm.Refresh;

        // The process is:
         ...
        ipcAES1.Encrypt;//where ipcAES is part of the IPWorks Encrypt library
        RichEdit1.Text:=ipcAES1.OutputMessage;
    finally
        Enabled:= true;
        DialogForm.Close;
    end;

end;
//--------------------------------------- 
procedure TDialogForm.FormShow(Sender: TObject);
var
  gif: TGIFImage;
begin
  gif := TGIFImage.Create;
  gif.LoadFromFile('D:\preview.gif');
  gif.Animate := True;
    image1.Parent := Self;
    image1.Left := 0;
    image1.Top := 0;
    image1.width := 800;
    image1.height := 800;
    image1.Picture.Assign(gif);
    gif.Animate := True;
    gif.Free;  
end;
maroco sc
  • 1
  • 2
  • Welcome to StackOverflow! Just an idea: maybe TGifImage rely on Windows message processing to make animation. If your process don't call the message pump, then the animation is stopped. Try adding Application.ProcessMessages call as often as possible in your processing. This is just a test because there maybe drawback in calling ProcessMessages. We'll see if it works first. – fpiette Nov 07 '20 at 14:16
  • Also, please look at this question: https://stackoverflow.com/questions/9573572/how-to-use-animated-gif-in-a-delphi-form – fpiette Nov 07 '20 at 14:17
  • 2
    Is the proces is doing something not UI related, put in into a separate thread, so the UI can update (and animate the gif) while your proces is running in the background (note, you cannot use/interact with the UI/Form controle from the background thread). – R. Hoek Nov 07 '20 at 14:43
  • I have modified the code and the question, please check. – maroco sc Nov 07 '20 at 15:47
  • There is probably a timer involved to animate the GIF, so, as already stated in the previous comments, the main thread can't update it while it's busy. – Olivier Nov 08 '20 at 09:13

1 Answers1

1

As said by many in this thread, because the processing is done in the main thread, the UI is not updated during this process.

To make sure the UI is updated while the process is running, let a separate thread do the processing:

procedure TForm1.Button1Click(Sender: TObject);
var
  aProcessingThread: TThread;
begin
  // First read all data needed by the process from UI controls (or other non-threadsafe parts)
  <data> := ...;

  // Then create a new (anonymous) thread with the code you need to run your process
  aProcessingThread := TThread.CreateAnonymousThread(
    procedure
    begin
      // create the objects you need to do the processing
      ipcAES1 := Txxx.Create;
      try
        // Set the data
        ipcAES1.<data> := <data>;

        // Execute the proces:
        // ...
        ipcAES1.Encrypt;

      finally
        // When the process is done, use 'Synchronize' to interact with the UI
        // again, so you can add the processed data to the RichtEdit and so on...
        TThread.Synchronize(nil,
          procedure
          begin
            // Now you can interact again with the UI
            RichEdit1.Text := ipcAES1.OutputMessage;
            Enabled:= true;
            DialogForm.Close;
          end);
        ipcAES1.Free;
      end;
    end);

  // The thread is now created, but not started/running, so you can now show
  // the dialog and then start the thread, at which point the ButtonClick event
  // exists, but the progress dialog is shown and the thread is running.
  Enabled := False;
  DialogForm.Show;
  aProcessingThread.Start;
end;

Of course this only a basic example of how to use an (anonymous) thread to do some processing in the background. Please note you need to handle Exceptions inside the thread (try/except).

A small tip regarding the TGifImage loading: you can just call Picture.LoadfromFile to load the gif as long as you include Vcl.Imaging.GIFImg in the uses clause.

procedure TForm1.FormShow(Sender: TObject);
begin
  image1.Picture.LoadFromFile('D:\preview.gif');

  image1.Parent := Self;
  image1.Left := 0;
  image1.Top := 0;
  image1.width := Image1.Picture.Width;
  image1.height := Image1.Picture.Height;

  (image1.Picture.Graphic as TGIFImage).Animate := True;
end;
R. Hoek
  • 916
  • 8
  • 27
  • Thank you for your answer. However, the Gif animation stops a few seconds before closing the DialogForm and showing the result in the RichEdit component. Any suggestions will be appreciated. Also, in your code, "aProcessingThread.Start; end);" should be "aProcessingThread.Start; end;" – maroco sc Nov 09 '20 at 14:01
  • Try setting AnimateLoop to glContinuously. Btw I modified the code. – R. Hoek Nov 09 '20 at 18:30
  • Still same. The Gif animation stops a few seconds before closing the DialogForm and showing the result in the RichEdit component. – maroco sc Nov 10 '20 at 03:42
  • I would like to add something, I have changed this line " RichEdit1.Text := ipcAES1.OutputMessage;" to " RichEdit1.Text := 'Any String';", and the gif animation works. What is the possible reason for this? Is it due to the length of string? because the output of "ipcAES1.OutputMessage" is too long (depends on the length of encrypted string) – maroco sc Nov 10 '20 at 03:57
  • @marocosc I dint know how ipcAES1 workt, but it might be that the call to Outputmessage is also taking a long time. So Try putting that inside the thread to like ‘sOutput := ipcAES1.Outputmessage’ and set ‘RichEdit1.Textt := sOutput’ in the Synchronise part. – R. Hoek Nov 10 '20 at 06:30
  • But it’s also possible the line ‘RichtEdit1.Text := ...’ is taking a long time and then there’s nothing you can do, because that needs to be done in the UI thread. But to be sure, add some breakpoint to see which part is actually tacking a long time to process. – R. Hoek Nov 10 '20 at 06:39