...show a Progressbar in a statusbar?

Author: Alex Schlecht
Homepage: http://www.bombus.de

Category: VCL

{
  Including Components into a Statusbar

  The TStatusbar usually does not allow to place components on itself. But
  sometimes it would be very fine to add -for example- a TProgressBar on a
  Statusbar.

  This Article shows how to add components to a TStatusbar and how to fit it
  into one of the Statusbar-Panels.


  First apologize my bad english: I'm a programmer, not a translator ;-)

  There are (at least) two ways to add Components on your Statusbar:


  1. Create an own Statusbar-Object
  =================================

  Create your own Statusbar and allow to add components on it. This is
  possible in overriding the Create-Constructor:
}


uses
  
commctrl;
  
type
  
TMyStatusBar = class(TStatusBar)
  public
    constructor 
Create(AOwner: TComponent); override;
  end;

implementation

constructor 
TMyStatusBar.Create(AOwner: TComponent);
begin
  inherited 
Create(AOwner);
  ControlStyle := ControlStyle + [csAcceptsControls];
  //that's all !!
end;

{
  That's all! Now this component accept other components as "Children" and you
  can put them at design-time onto the statusbar!

  But I don't like this way very much because you have to use this new
  component. I prefer to use the "old" components and manipulating them a
  little bit. So lets have a look to my favourite way:


  2. "Adopt" the other component
  ==============================


  The simplest way to include components to a statusbar is to adopt the
  component! Place the TStatusbar on your Form, also place the Progressbar (or
  other component you wish to include on your Statusbar) on the form (!). Then
  do this in the "OnShow" Event of the Form:
}

     
Progressbar1.Parent := statusbar1;

     Progressbar1.Top := 1;

     Progressbar1.Left := 1;

{
  Now the Progressbar is "adopted" by the Statusbar.

  But unfortunatley it doesn't look very nice because the Progressbar is
  larger than the panel and the position is not correct. So we have to
  determine the exact position of the Progresbar by using the Statubar's
  border, width and height. (We have to add this code to the "OnShow" Event of
  the form, because in the "OnCreate" event still no Handles are avalible.)
}

procedure TForm1.FormShow(Sender: TObject);
var
  
r: TRect;
begin
  
Statusbar1.Perform(SB_GETRECT, 0, Integer(@R));
  //determine the size of panel 1

  //SB_GETRECT needs Unit commctrl
  // 0 = first Panel of Statusbar; 1 = the second and so on.

  
progressbar1.Parent := Statusbar1;  //adopt the Progressbar

  
progressbar1.Top    := r.Top;      //set size of
  
progressbar1.Left   := r.Left;      //Progressbar to
  
progressbar1.Width  := r.Right - r.Left; //fit with panel
  
progressbar1.Height := r.Bottom - r.Top;
end;

{
  Now the Progressbar fits exactly into the first panel of the statusbar! If
  you want to use the second or another panel, you only have to change the
  parameter of the "perform" command.

  Comments and improvements are welcome!!
  Alex.schlecht@skw.com
}


{
  =================== DEUTSCHE FASSUNG ==================================


   Wie man Componenten in eine Statusbar einbindet


  Normalerweise läßt eine Statusbar es nicht zu, daß auf ihr andere
  Componenten eingebunden werden. Nachfolgend wird ein Weg gezeigt, wie es
  trotzdem geht und wie man z.B. eine Progressbar genau in ein Panel einpaßt.

  Es gibt (mindestens) zwei Wege für unser Ziel:


  1. Eine eigene Statusbar-Komponente erstellen
  =============================================

  Um einer eigenen Statusbar-Komponente zu erlauben, andere Komponenten
  aufzunehmen muß lediglich der Create-Constructor überschrieben werden:
}

uses
  
commctrl;


type
  
TMyStatusBar = class(TStatusBar)
  public
    constructor 
Create(AOwner: TComponent); override;
  end;

implementation

constructor 
TMyStatusBar.Create(AOwner: TComponent);
begin
  inherited 
Create(AOwner);
  ControlStyle := ControlStyle + [csAcceptsControls];
end;


{
  Das ist alles! Jetzt akzeptiert die neue Komponente andere Elemente, die zur
  Entwurfszeit plaziert werden können.

  Aber mir gefällt diese Lösung am wenigsten, da man wieder eine Komponente
  mehr hat. Lieber manipuliere ich an vorhandenen Komponenten herum:


  2. Die Komponente adoptieren!
  =============================

  Der einfachste Weg, Komponenten auf eine Statusbar einzubinden ist es, diese
  Komponente von der Statusbar zur Laufzeit zu adoptieren! Dazu muß die
  einzubindende Komponente (z.B. Progressbar) auf dem Form (!), also neben der
  Statusbar plaziert werden. Im "OnShow"-Event des Forms schreibt man
  folgendes rein:
}

     
Progressbar1.Parent := statusbar1;

     Progressbar1.Top := 1;

     Progressbar1.Left := 1;

{
  Somit ist die Progressbar von der Statusbar adoptiert! Allerdings paßt nun
  die Größe der Progressbar und der Statusbar nicht überein.  Damit das Ganze
  gut aussieht, ersetzt man obigen Code durch nachfolgende Zeilen. Zu beachten
  ist, daß diesmal das "OnShow"-Event bemüht werden muß, da innerhalb von
  "OnCreate" noch keine Handles verfügbar sind.
}

procedure TForm1.FormShow(Sender: TObject);
var
  
r: TRect;
begin
  
Statusbar1.Perform(SB_GETRECT, 0, Integer(@R));
  //Größe des 1. Panels ermitteln

  //SB_GETRECT benötigt die Unit commctrl
  // 0 = erstes Panel der Statusbar; 1 = zweites Panel usw.

  
progressbar1.Parent := Statusbar1;  //Prog.Bar adoptieren
  
progressbar1.Top    := r.Top;      //Größe der
  
progressbar1.Left   := r.Left;      //Progressbar setzen
  
progressbar1.Width  := r.Right - r.Left; //und an Panel anpassen
  
progressbar1.Height := r.Bottom - r.Top;
end;


//Jetzt paßt die Progressbar genau in das Panel!



 

printed from
www.swissdelphicenter.ch
developers knowledge base