That is because the TProgressBarInStatusBar.CreateIn() code provided earlier is not taking the Left position of the specified TStatusPanel into account, only its Width and Height. So it is positioning the TProgressBar in the wrong place for any TStatusPanel other than the 1st one.
Unfortunately, neither TStatusBar nor TStatusPanel provide a property or method to get the Left position of a TStatusPanel, so you will have to retrieve it manually, either by:
- looping through the TStatusBar.Panels collection:
function GetLeftOfStatusPanel(APanel: TStatusPanel); Integer;
var
I: Integer;
Coll: TStatusPanels;
begin
Result := 0;
Coll := APanel.Collection as TStatusPanels;
for I := 0 to APanel.Index-1 do
Inc(Result, Coll[I].Width);
end;
- or by asking the OS directly:
uses
..., Winapi.CommCtrl;
function GetLeftOfStatusPanel(APanel: TStatusPanel); Integer;
var
R: TRect;
begin
SendMessage((APanel.Collection.Owner as TStatusBar).Handle, SB_GETRECT, APanel.Index, LPARAM(@R));
Result := R.Left;
end;
In which case, since CreateIn() wants the TProgressBar to fill the full rectangle of the TStatusPanel anyway, I would just ask the OS for the rectangle and use it as-is, eg:
uses
..., Winapi.CommCtrl;
class procedure TProgressBarInStatusBar.CreateIn(const inStatusBarPanel: TStatusPanel;
var outProgressBar: TProgressBar; var outLabel: TLabel);
var
statusbar: TStatusBar;
R: TRect;
Begin
statusbar := inStatusBarPanel.Collection.Owner As TStatusBar;
SendMessage(statusbar.Handle, SB_GETRECT, inStatusBarPanel.Index, LPARAM(@R));
outProgressBar := TProgressBar.Create(statusbar);
outProgressBar.Parent := statusbar;
outProgressBar.Top := R.top;
outProgressBar.Left := R.left;
outProgressBar.Width := R.Width;
outProgressBar.Height := R.Height;
outLabel := TLabel.Create(outProgressBar);
outLabel.Parent := outProgressBar;
outLabel.Align := alClient;
outLabel.AutoSize := False;
outLabel.Alignment := taCenter;
end;