Mirror

How to create a TStatusBar with resizable panels (Views: 100)


Problem/Question/Abstract:

How to create a TStatusBar with resizable panels

Answer:

In this demo the TStatusBar has three panels. Only panels 1 and 2 need to be adjustable and each has a set minimum width of 20. The StatusBar OnResize event is used to keep the panels in view, regardless of form resizing, except where the StatusBar width is less than 40.

{ ... }
private
{Private declarations}
StatusMouseDown: Boolean;
Split: Integer;
{ ... }

procedure TMainForm.FormCreate(Sender: TObject);
begin
  StatusMouseDown := false;
end;

procedure TMainForm.StatusBar1MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  StatusMouseDown := false;
end;

procedure TMainForm.StatusBar1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  S1, S2: Integer;
begin
  if Button = mbLeft then
  begin
    StatusMouseDown := true;
    Split := 0;
    S1 := StatusBar1.Panels[0].Width;
    S2 := StatusBar1.Panels[1].Width + S1;
    if ((X > S1 - 3) and (X < (S1 + 3))) then
      Split := 1
    else if ((X > S2 - 3) and (X < (S2 + 3))) then
      Split := 2;
  end;
end;

procedure TMainForm.StatusBar1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  S1, S2, S3: Integer;
  Split1, Split2: Boolean;
begin
  Split1 := false;
  Split2 := false;
  S1 := StatusBar1.Panels[0].Width;
  S2 := StatusBar1.Panels[1].Width + StatusBar1.Panels[0].Width;
  S3 := StatusBar1.Width;
  if ((X > S1 - 3) and (X < (S1 + 3))) then
    Split1 := true
  else if ((X > S2 - 3) and (X < (S2 + 3))) then
    Split2 := true;
  if (Split1 or Split2) then
    StatusBar1.Cursor := crHSplit
  else
    StatusBar1.Cursor := crDefault;
  if StatusMouseDown then
  begin
    if (Split = 1) then
    begin
      if (X < 20) then
        StatusBar1.Panels[0].Width := 20
      else if (X > (S3 - 40)) then
      begin
        StatusBar1.Panels[0].Width := S3 - 40;
        StatusBar1.Panels[1].Width := S3 - S1 - 20;
      end
      else if (X >= 20) and (X <= S3 - 20) then
      begin
        StatusBar1.Panels[0].Width := X;
        if ((X + StatusBar1.Panels[1].Width + 20) >= S3) then
          StatusBar1.Panels[1].Width := S3 - X - 20;
      end;
    end;
    if (Split = 2) then
    begin
      if (X < (S1 + 20)) then
        StatusBar1.Panels[1].Width := 20
      else if (X > (S3 - 20)) then
        StatusBar1.Panels[1].Width := S3 - S1 - 20
      else if (X >= S1 + 20) and (X <= S3 - 20) then
        StatusBar1.Panels[1].Width := X - S1;
    end;
  end;
end;

procedure TMainForm.StatusBar1Resize(Sender: TObject);
var
  S1, S2, S3: Integer;
begin
  S1 := StatusBar1.Panels[0].Width;
  S2 := StatusBar1.Panels[1].Width + StatusBar1.Panels[0].Width;
  S3 := StatusBar1.Width;
  if (S1 >= (S3 - 40)) then
  begin
    StatusBar1.Panels[0].Width := S3 - 40;
    StatusBar1.Panels[1].Width := 20;
  end
  else if (S2 >= (S3 - 20)) then
    StatusBar1.Panels[1].Width := S3 - S1 - 20;
end;

<< Back to main page