Program InfoWindow;
(*  This is an example of a modeless object used to display status information
    during the execution of an application.  The object tStatusText represents
    a status line that is updated dynamically during processing.  This example
    has only one line of text, but by instantiating multiple instances of
    tStatusText, it would be possible to have more that one line.  This exampe
    is based on a suggestion by Ted Husted  *)

Uses App, objects,views,Dialogs,crt;
Type
  mApp = object(tApplication)
    Constructor Init;               {just to put up a desktop}
  End;

 pstatustext=^tstatustext;          {pointer to an object}
 tstatustext=object(tstatictext)    {object that contains the status line}
  procedure newtext(n: Integer);    {that will be updated during processing}
 end;

 {-- tInfoBox is the actual window that will contains the status line that
     will be updated during processing.  It is initialzed and controlled
     by the tStatusBox object. --}

 pInfoBox = ^tInfoBox;
 tInfoBox = object(tWindow)
   constructor Init(wTitle: string; wMsg: String;nx,ny,mx,my: Integer);
 end;

 {-- tStatusBox controls the updating of the infoBox status line --}
 pStatusBox = ^tStatusBox;
 tStatusBox = object(tInfoBox)
   statusLine: pStatusText;
   constructor Init(wTitle: string;promptLine: string;nx,ny,mx,my: Integer);
   destructor  Done; virtual;
   Procedure changeStatusLine(newStat: integer);
 End;

Var
  InfoBox: pInfoBox;
  statusBox: pStatusBox;
  m: mApp;

CONSTRUCTOR tStatusBox.Init(wTitle: string;
                            promptLine: string;
                            nx,ny,mx,my: Integer);
var
  r: tRect;
begin
  tInfoBox.Init(wTitle,PromptLine,nx,ny,mx,my);  {initializes the infoBox object}
  r.Assign(23,2,31,3);
  statusLine := new(pStatusText,Init(r,' '));     {initializes the statusLine object}
  insert(statusLine);                             {and inserts it into infoBox}
end;

PROCEDURE tStatusBox.ChangeStatusLine;
Begin
  statusLine^.newText(newStat);             {changes the value of the statusLine}
end;

Destructor tStatusBox.Done;
Begin
  dispose(statusLine,Done);     {disposes of allocated memory}
  tInfoBox.Done;
end;

procedure tstatustext.newtext(n: Integer);
var
  s: string;

begin
 str(n,s);          {strings the passed integer value}
 if (text <> nil) then   {Checks to see if the instance variable text exists}
   disposeStr(text);     {if it does, it is disposed of. This is VERY IMPORTANT!}
 text:=newstr(s);        {Allocates memory for the text instance variable}
 drawView;               {redraws the status line}
end;

CONSTRUCTOR tInfoBox.Init;
{-- Initializes an information window --}
var
  r: tRect;
  control: pView;

begin
  r.Assign(nx,ny,mx,my);
  tWindow.Init(r,wTitle,0);
  options := Options or ofCentered;
  palette := wpGrayWindow;
  flags := $00;
  r.assign(2,2,35,3);
  Control := new(pStaticText,Init(r,wMsg));
  insert(control);
End;

PROCEDURE showStatusBox(wTitle,prompt: string);
{-- Instantiates statusBox and inserts it into the deskTop --}
Begin
  statusBox := new(pStatusBox,Init(wTitle,prompt,0,0,41,6));
  desktop^.Insert(statusBox);
end;

PROCEDURE ChangeStatusBox(newNum: Integer);
Begin
  StatusBox^.ChangeStatusLine(newNum);
End;

PROCEDURE removeStatusBox;
Begin
  dispose(StatusBox,Done);
end;

Constructor mApp.Init;
Var
  count: Integer;

Begin
  tapplication.Init;
   showStatusBox('Processing Deletions','Processing Record:');
   for count := 1 to 5000 do begin
     ChangeStatusBox(count);
     delay(1);
   End;
   RemoveStatusBox;
End;

Begin
  m.Init;
  m.Done;
End.