Einzelnen Beitrag anzeigen

mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#19

AW: ProgressBar für Perfektionisten

  Alt 31. Mai 2022, 22:46
Habe jetzt zwei Panels übereinandergelegt.
Das ist eine valide Methode seit den Anfangstagen von Delphi. Um die Funktionalität deiner ProgressBar vom Rest des Sourcecodes zu trennen, solltest du dir ruhig ein paar Minuten Zeit nehmen. Ein weiterer Vorteil wäre auch, dass ein besonders zum Aufhübschen talentierter Kollege sich voll austoben kann, ohne mit anderen Teilen in Berührung zu kommen. Die Technik ist weitläufig anwendbar, außerdem einfach und schnell umzusetzen.

Disclaimer: Das Beispiel ist ein Proof of Concept, der Sourcecode ist weder getestet noch optimiert.
Delphi-Quellcode:
type
  TProgressBarGUIHelper = class(TComponent)
  strict private
    FPaintBox: TPaintBox;
    FStepWidth: Double;
  private
    FPosition: Integer;
    FStepCount: Integer;
    procedure InitInternalControls;
    procedure RecalcStepWidth;
    procedure DoPaint(pmSender: TObject);
    procedure DoResize(pmSender: TObject);
  public
    constructor Create(pmOwner: TComponent; pmStepCount: Integer = 100); reintroduce;
    procedure StepReset(pmStartPosition: Integer = 0);
    procedure StepUp;
    procedure StepDown;
    property StepCount: Integer
      read FStepCount;
  end;

constructor TProgressBarGUIHelper.Create(pmOwner: TComponent; pmStepCount: Integer);
begin
  Assert(pmOwner is TPanel);
  inherited Create(pmOwner);
  FStepCount := pmStepCount;
  InitInternalControls;
  RecalcStepWidth;
end;

procedure TProgressBarGUIHelper.InitInternalControls;
begin
  with TPanel(Owner) do
  begin
    Caption := '';
    BevelKind := bkFlat;
    BevelOuter := bvNone;
    BevelInner := bvLowered;
    OnResize := DoResize;
  end;

  FPaintBox := TPaintBox.Create(Owner);
  FPaintBox.Parent := TPanel(Owner);
  FPaintBox.Align := alClient;
  FPaintBox.Color := clGreen;
  FPaintBox.OnPaint := DoPaint;
end;

procedure TProgressBarGUIHelper.RecalcStepWidth;
begin
  FStepWidth := FPaintBox.ClientWidth / FStepCount;
end;

procedure TProgressBarGUIHelper.DoPaint(pmSender: TObject);
var
  rect: TRect;
begin
  if FPosition = 0 then Exit; //=>

  with TPaintBox(pmSender) do
  begin
    if FPosition < FStepCount then
      rect.Create(0, 0, Trunc(FPosition * FStepWidth), ClientHeight)
    else
      rect.Create(ClientRect);

    Canvas.Rectangle(rect);
  end;
end;

procedure TProgressBarGUIHelper.DoResize(pmSender: TObject);
begin
  RecalcStepWidth;
end;

procedure TProgressBarGUIHelper.StepReset(pmStartPosition: Integer);
begin
  if pmStartPosition < 0 then
    FPosition := 0
  else if pmStartPosition > FStepCount then
    FPosition := FStepCount
  else
    FPosition := pmStartPosition;

  FPaintBox.Repaint;
end;

procedure TProgressBarGUIHelper.StepDown;
begin
  if FPosition > 0 then
  begin
    Dec(FPosition);
    FPaintBox.Repaint;
  end;
end;

procedure TProgressBarGUIHelper.StepUp;
begin
  if FPosition < FStepCount then
  begin
    Inc(FPosition);
    FPaintBox.Repaint;
  end;
end;
Im Formular lässt es sich dann so einsetzen:
Delphi-Quellcode:
TfrmMain = class(TForm)
  pnlProgressBar: TPanel;
private
  FProgressBarGUIHelper: TProgressBarGUIHelper;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FProgressBarGUIHelper := TProgressBarGUIHelper.Create(pnlProgressBar);
end;
...
FProgressBarGUIHelper.StepUp;
Bis bald...
Thomas

Geändert von mytbo (31. Mai 2022 um 23:07 Uhr) Grund: Ups, da war ein Paint zu viel
  Mit Zitat antworten Zitat