6

ステータス バーに 3 つのパネルがあり、一番左がアプリが動作しているファイルの名前だとします。

それは私c:\my.logc:\a\very\deeply\nested\sub-directory\extremely_long_file_name_indeed.log

新しいファイルをロードするときに、3 つのステータス バー パネルのサイズを簡単に調整する方法はありますか? (FOSS VCL コンポーネントでさえあるかもしれませんが、見つけられませんでした)?

4

1 に答える 1

13

これは、実際には、削除された回答の TLama の最初のバージョンに似ています。

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    procedure FormResize(Sender: TObject);
  private
    procedure SetLeftPanelWidth;
  ..

uses
  filectrl, commctrl;

...

procedure TForm1.SetLeftPanelWidth;
var
  Borders: array[0..2] of Integer;
  PanelWidth, MaxWidth: Integer;
begin
  // calculate a little indent on both sides of the text (credit @TLama)
  SendMessage(StatusBar1.Handle, SB_GETBORDERS, 0, LPARAM(@Borders));

  StatusBar1.Canvas.Font := StatusBar1.Font;
  PanelWidth := StatusBar1.Canvas.TextWidth(StatusBar1.Panels[0].Text)
      + 2 * Borders[1] + 2;

  // Per Ken's comment, specify a maximum width, otherwise the panel can overgrow
  MaxWidth := StatusBar1.Width div 4 * 3; // arbitrary requirement
  if PanelWidth > MaxWidth then begin
    StatusBar1.Panels[0].Text := MinimizeName(TFileName(StatusBar1.Panels[0].Text),
        StatusBar1.Canvas, MaxWidth);
    // recalculate
    PanelWidth := StatusBar1.Canvas.TextWidth(StatusBar1.Panels[0].Text) +
        2 * Borders[1] + 2;
  end;
  StatusBar1.Panels[0].Width := PanelWidth;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  // have to set the text again since original filename might have been minimized
  StatusBar1.Panels[0].Text := ...;
  SetLeftPanelWidth;
end;


上記は、パスが最大幅に収まらない場合にパスを短縮しますが、元のファイル名はユーザーには表示されません。ステータス バー パネルのネイティブ ヒント サポートを使用できるようにするには、パネルの幅をテキストが収まるよりも短くする必要があります。

そのため、別の方法として、以下はファイル名の末尾部分が最大幅よりも長い場合に切り捨て、マウスでホバーするとツールチップを表示します:

type
  TStatusBar = class(comctrls.TStatusBar)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    procedure FormResize(Sender: TObject);
  private
    procedure SetLeftPanelWidth;
  ..


procedure TStatusBar.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or SBT_TOOLTIPS;
end;

procedure TForm1.SetLeftPanelWidth;
var
  Borders: array[0..2] of Integer;
  PanelWidth, MaxWidth: Integer;
begin
  SendMessage(StatusBar1.Handle, SB_GETBORDERS, 0, LPARAM(@Borders));

  StatusBar1.Canvas.Font := StatusBar1.Font;
  PanelWidth := StatusBar1.Canvas.TextWidth(StatusBar1.Panels[0].Text)
      + 2 * Borders[1] + 2;

  MaxWidth := StatusBar1.Width div 4 * 3; // arbitrary requirement
  if PanelWidth > MaxWidth then begin
    SendMessage(StatusBar1.Handle, SB_SETTIPTEXT, 0,
        NativeInt(PChar(StatusBar1.Panels[0].Text)));
    PanelWidth := MaxWidth;
  end else
    SendMessage(StatusBar1.Handle, SB_SETTIPTEXT, 0, 0);

  StatusBar1.Panels[0].Width := PanelWidth;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  SetLeftPanelWidth;
end;
于 2012-08-25T03:06:22.420 に答える