开发者

Delphi throbber

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

I tried showing a progress indi开发者_如何学Ccator, 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.


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

Delphi throbber

Delphi throbber

Delphi throbber

Delphi throbber

Delphi throbber

Delphi throbber

Delphi throbber

Delphi throbber

Delphi throbber


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜