Question

What is the best solution to show that the application is doing something?

I tried showing a progress indicator, but it did not work.

UPDATE: -------------

A progress bar works fine, but isn't what I want.

I want to show a throbber, like what Web browsers use, so as long as something is being updated it keeps turning.

Cursor can also be in crHourGlass mode.

Was it helpful?

Solution

Try this:

AnimateUnit

unit AnimateUnit;

interface

uses
  Windows, Classes;

type
  TFrameProc = procedure(const theFrame: ShortInt) of object;

  TFrameThread = class(TThread)
  private
    { Private declarations }
    FFrameProc: TFrameProc;
    FFrameValue: ShortInt;
    procedure SynchedFrame();
  protected
    { Protected declarations }
    procedure Frame(const theFrame: ShortInt); virtual;
  public
    { Public declarations }
    constructor Create(theFrameProc: TFrameProc; CreateSuspended: Boolean = False); reintroduce; virtual;
  end;

  TAnimateThread = class(TFrameThread)
  private
    { Private declarations }
  protected
    { Protected declarations }
    procedure Execute(); override;
  public
    { Public declarations }
  end;

var
  AnimateThread: TAnimateThread;

implementation

{ TFrameThread }
constructor TFrameThread.Create(theFrameProc: TFrameProc; CreateSuspended: Boolean = False);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
  FFrameProc := theFrameProc;
end;

procedure TFrameThread.SynchedFrame();
begin
  if Assigned(FFrameProc) then FFrameProc(FFrameValue);
end;

procedure TFrameThread.Frame(const theFrame: ShortInt);
begin
  FFrameValue := theFrame;
  try
    Sleep(0);
  finally
    Synchronize(SynchedFrame);
  end;
end;

{ TAnimateThread }
procedure TAnimateThread.Execute();
var
  I: ShortInt;
begin
  while (not Self.Terminated) do
  begin
    Frame(0);
    for I := 1 to 8 do
    begin
      if (not Self.Terminated) then
      begin
        Sleep(120);
        Frame(I);
      end;
    end;
    Frame(0);
  end;
end;

end.

Unit1

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ImgList;

type
  TForm1 = class(TForm)
    ImageList1: TImageList;
    Image1: TImage;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure UpdateFrame(const theFrame: ShortInt);
  end;

var
  Form1: TForm1;

implementation

uses
  AnimateUnit;

{$R *.DFM}
procedure TForm1.UpdateFrame(const theFrame: ShortInt);
begin
  Image1.Picture.Bitmap.Handle := 0;
  try
    ImageList1.GetBitmap(theFrame, Image1.Picture.Bitmap);
  finally
    Image1.Update();
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  AnimateThread := TAnimateThread.Create(UpdateFrame);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  AnimateThread.Terminate();
end;

end.

The Images

image1 image2 image3 image4 image5 image6 image7 image8

animate1

OTHER TIPS

You are probably running your time consuming task in the main thread.

One option is to move it to a background thread which will allow your message queue to be serviced. You need it to be serviced in order for your progress bar, and indeed any UI, to work.

Answer to the updated question:

  • generate an animated gif e.g. here
  • add a GIF library to your environment (JEDI JVCL+JCL)
  • insert a TImage and load the generated gif
  • make it visible if you need it

A indicator is OK. You have to call Application.ProcessMessages after changing it.

"What is the best solution to show that that application is doing something?" - set mouse cursor to crHourGlass? or to create another form/frame/etc which attentions the user that the application is 'doing' something, and he needs to wait.

From your lengthy task, you can occasionally update a visual indicator, like a progress bar or anything else. However, you need to redraw the changes immediately by calling Update on the control that provides the feedback.

Don't use Application.ProcessMessages as this will introduce possible reentrancy issues.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top