Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2025-05

How to format a string to given length ?

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

John Landmesser

I know it is possible but i don't know the function name :

Example:

This_long_string_should_be_Shorten_to

This_long ... Shorten_to

Thanks !

Reply by email

David Copeland
to John Landmesser

Try SetLength.

John Landmesser wrote 10 lines
I know it is possible but i don't know the function name : Example: This_long_string_should_be_Shorten_to This_long ... Shorten_to Thanks !
David Copeland JSI Data Systems Limited 613-727-9353 www.jsidata.ca

Reply by email

Unknown author
to David Copeland
David Copeland wrote
Try SetLength.

SetLength sets the length of the whole string... it does not hide the middle portion of a long string and replace that portion with ellipsis as shown in the example given...

Show quoted text 10 lines
On 2025-05-13 06:10, John Landmesser via lazarus wrote: > I know it is possible but i don't know the function name : > > Example: > > This_long_string_should_be_Shorten_to > > This_long ... Shorten_to > > Thanks !
NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list where it belongs!*

Reply by email

Wayne Sherman
to John Landmesser: I know it is possible but i don't know the function name : Example:…
John Landmesser wrote 6 lines
I know it is possible but i don't know the function name : Example: This_long_string_should_be_Shorten_to This_long ... Shorten_to From ChatGPT O3:

1) Let the LCL draw truncated text for you
If you are drawing text yourself (e.g. inside OnPaint of a control), TTextStyle already has a flag that tells the canvas to clip and add an ellipsis automatically:

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  R : TRect;
  TS: TTextStyle;
begin
  R := PaintBox1.ClientRect;
  TS := PaintBox1.Canvas.TextStyle;
  TS.SingleLine  := True;
  TS.Layout      := tlCenter;    // optional
  TS.Alignment   := taLeftJustify;
  TS.EndEllipsis := True;        // ? magic here
  PaintBox1.Canvas.TextRect(R, R.Left, R.Top, LongText, TS);
end;

2) Shrinking a file?path (keep the drive & file name) For file names/paths there is a ready?made helper in FileCtrl:

uses FileCtrl;  // part of the LCL
Label1.Caption :=
  MinimizeName(LongPath, Canvas, MaxPixelWidth);

MinimizeName drops middle path segments and inserts "..." until the string fits in MaxPixelWidth pixels (measured with the supplied canvas).

3) Windows?only alternative

On Windows you can also rely on the OS text API:
uses LclIntf, LclType;
var Flags := DT_SINGLELINE or DT_END_ELLIPSIS;
DrawTextW(Canvas.Handle, PWideChar(LongText), -1, R, Flags);

DT_END_ELLIPSIS tells DrawText to clip and add ??? when the text doesn?t fit. Microsoft Learn
(Lazarus? LclIntf.DrawText is just a wrapper, so the call stays portable inside the Windows family.)

4) Use a function (not tested)
uses LazUtf8;
function EllipsizeUTF8(const S: string; MaxChars: Integer;
                       AddToMiddle: Boolean = False): string;
{ Shortens UTF?8 string *S* to at most *MaxChars* code?points.
  ? If *AddToMiddle* = False  ? ?This text is lo??
  ? If *AddToMiddle* = True   ? ?This?is long?               }
var
  Len, FrontPart, BackPart: Integer;
begin
  if (MaxChars <= 0) then        // nothing fits
    Exit('');                    // (could also raise)
  Len := UTF8Length(S);
  if Len <= MaxChars then        // already fits
    Exit(S);
  if not AddToMiddle then           // ?text??
    Result := UTF8Copy(S, 1, MaxChars - 1) + '?'
  else begin                     // ?tex?t?
    { keep first ?(MaxChars?1)/2? and last ?(MaxChars?1)/2? code?points }
    FrontPart := (MaxChars - 1) div 2;          // floor
    BackPart  := MaxChars - 1 - FrontPart;      // remainder
    Result :=
      UTF8Copy(S, 1, FrontPart) + '?' +
      UTF8Copy(S, Len - BackPart + 1, BackPart);
  end;
end;

Reply by email

John Landmesser
to Wayne Sherman

I think "MinimizeName" seems to be what i could not remember anymore, thanks Wayne and ChatGPT :-)

------------------------------------------------------------------------

"

Wayne Sherman wrote 77 lines
John Landmesser wrote: > I know it is possible but i don't know the function name : > Example: > This_long_string_should_be_Shorten_to > This_long ... Shorten_to From ChatGPT O3: 1) Let the LCL draw truncated text for you If you are drawing text yourself (e.g. inside OnPaint of a control), TTextStyle already has a flag that tells the canvas to clip and add an ellipsis automatically: procedure TForm1.PaintBox1Paint(Sender: TObject); var R : TRect; TS: TTextStyle; begin R := PaintBox1.ClientRect; TS := PaintBox1.Canvas.TextStyle; TS.SingleLine := True; TS.Layout := tlCenter; // optional TS.Alignment := taLeftJustify; TS.EndEllipsis := True; // ? magic here PaintBox1.Canvas.TextRect(R, R.Left, R.Top, LongText, TS); end; 2) Shrinking a file?path (keep the drive & file name) For file names/paths there is a ready?made helper in FileCtrl: uses FileCtrl; // part of the LCL Label1.Caption := MinimizeName(LongPath, Canvas, MaxPixelWidth); MinimizeName drops middle path segments and inserts "..." until the string fits in MaxPixelWidth pixels (measured with the supplied canvas). 3) Windows?only alternative On Windows you can also rely on the OS text API: uses LclIntf, LclType; var Flags := DT_SINGLELINE or DT_END_ELLIPSIS; DrawTextW(Canvas.Handle, PWideChar(LongText), -1, R, Flags); DT_END_ELLIPSIS tells DrawText to clip and add ??? when the text doesn?t fit. Microsoft Learn (Lazarus? LclIntf.DrawText is just a wrapper, so the call stays portable inside the Windows family.) 4) Use a function (not tested) uses LazUtf8; function EllipsizeUTF8(const S: string; MaxChars: Integer; AddToMiddle: Boolean = False): string; { Shortens UTF?8 string *S* to at most *MaxChars* code?points. ? If *AddToMiddle* = False ? ?This text is lo?? ? If *AddToMiddle* = True ? ?This?is long? } var Len, FrontPart, BackPart: Integer; begin if (MaxChars <= 0) then // nothing fits Exit(''); // (could also raise) Len := UTF8Length(S); if Len <= MaxChars then // already fits Exit(S); if not AddToMiddle then // ?text?? Result := UTF8Copy(S, 1, MaxChars - 1) + '?' else begin // ?tex?t? { keep first ?(MaxChars?1)/2? and last ?(MaxChars?1)/2? code?points } FrontPart := (MaxChars - 1) div 2; // floor BackPart := MaxChars - 1 - FrontPart; // remainder Result := UTF8Copy(S, 1, FrontPart) + '?' + UTF8Copy(S, Len - BackPart + 1, BackPart); end; end;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20250513/3df230c5/attachment-0001.htm>

Reply by email

John Landmesser
to Wayne Sherman: 1) Let the LCL draw truncated text for you If you are drawing text yourself (e.g. inside…

My solution was ... take from ChatGPT the function EllipsizeUTF8() , because MinimizeName is designed for path variables.

Wayne Sherman wrote 77 lines
John Landmesser wrote: > I know it is possible but i don't know the function name : > Example: > This_long_string_should_be_Shorten_to > This_long ... Shorten_to From ChatGPT O3: 1) Let the LCL draw truncated text for you If you are drawing text yourself (e.g. inside OnPaint of a control), TTextStyle already has a flag that tells the canvas to clip and add an ellipsis automatically: procedure TForm1.PaintBox1Paint(Sender: TObject); var R : TRect; TS: TTextStyle; begin R := PaintBox1.ClientRect; TS := PaintBox1.Canvas.TextStyle; TS.SingleLine := True; TS.Layout := tlCenter; // optional TS.Alignment := taLeftJustify; TS.EndEllipsis := True; // ? magic here PaintBox1.Canvas.TextRect(R, R.Left, R.Top, LongText, TS); end; 2) Shrinking a file?path (keep the drive & file name) For file names/paths there is a ready?made helper in FileCtrl: uses FileCtrl; // part of the LCL Label1.Caption := MinimizeName(LongPath, Canvas, MaxPixelWidth); MinimizeName drops middle path segments and inserts "..." until the string fits in MaxPixelWidth pixels (measured with the supplied canvas). 3) Windows?only alternative On Windows you can also rely on the OS text API: uses LclIntf, LclType; var Flags := DT_SINGLELINE or DT_END_ELLIPSIS; DrawTextW(Canvas.Handle, PWideChar(LongText), -1, R, Flags); DT_END_ELLIPSIS tells DrawText to clip and add ??? when the text doesn?t fit. Microsoft Learn (Lazarus? LclIntf.DrawText is just a wrapper, so the call stays portable inside the Windows family.) 4) Use a function (not tested) uses LazUtf8; function EllipsizeUTF8(const S: string; MaxChars: Integer; AddToMiddle: Boolean = False): string; { Shortens UTF?8 string *S* to at most *MaxChars* code?points. ? If *AddToMiddle* = False ? ?This text is lo?? ? If *AddToMiddle* = True ? ?This?is long? } var Len, FrontPart, BackPart: Integer; begin if (MaxChars <= 0) then // nothing fits Exit(''); // (could also raise) Len := UTF8Length(S); if Len <= MaxChars then // already fits Exit(S); if not AddToMiddle then // ?text?? Result := UTF8Copy(S, 1, MaxChars - 1) + '?' else begin // ?tex?t? { keep first ?(MaxChars?1)/2? and last ?(MaxChars?1)/2? code?points } FrontPart := (MaxChars - 1) div 2; // floor BackPart := MaxChars - 1 - FrontPart; // remainder Result := UTF8Copy(S, 1, FrontPart) + '?' + UTF8Copy(S, Len - BackPart + 1, BackPart); end; end;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20250514/9d463dc7/attachment.htm>

Reply by email