Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#15

AW: Textlänge abschneiden

  Alt 17. Jun 2016, 21:26
Nur mal so nebenbei etwas allgemeingültiges heruntergetippt:
Delphi-Quellcode:
unit Unit2;

interface

uses
  System.SysUtils,
  System.StrUtils;

type
  TCharMeasureWidthDelegate = function( const C: Char ): Integer of object;

function ShortenText( const Text: string; const MaxLength: Integer; const CharMeasurement: TCharMeasureWidthDelegate; const ShortenSuffix: string = '...' ): string;

implementation

function ShortenText( const Text: string; const MaxLength: Integer; const CharMeasurement: TCharMeasureWidthDelegate; const ShortenSuffix: string = '...' ): string;
var
  lText : string;
  lChar : Char;
  lCharLength : Integer;
  lSuffixLength : Integer;
  lTextLength : Integer;
  lShortenedWithSuffix : string;
  lShortendWithSuffixFound: Boolean;
begin
  if not Assigned( CharMeasurement )
  then
    raise EArgumentNilException.Create( 'CharMeasurement' );
  if MaxLength < 0
  then
    raise EArgumentOutOfRangeException.Create( 'MaxLength' );

  lSuffixLength := 0;
  for lChar in ShortenSuffix do
    begin
      lSuffixLength := lSuffixLength + CharMeasurement( lChar );
    end;

  if lSuffixLength > MaxLength
  then
    raise EArgumentOutOfRangeException.Create( 'SuffixLength > MaxLength' );

  Result := '';
  lText := TrimRight( Text );
  lTextLength := 0;
  lShortendWithSuffixFound := False;

  for lChar in lText do
    begin
      lCharLength := CharMeasurement( lChar );

      if not lShortendWithSuffixFound and ( lTextLength + lCharLength + lSuffixLength > MaxLength )
      then
        begin
          lShortenedWithSuffix := Result + ShortenSuffix;
          lShortendWithSuffixFound := True;
        end;

      if lTextLength + lCharLength > MaxLength
      then
        begin
          Result := lShortenedWithSuffix;
          Exit;
        end;

      Result := Result + lChar;
      Inc( lTextLength, lCharLength );
    end;

end;

end.
Und ein Test mit einer PaintBox (ja, es ist wurscht womit man das verwendet)
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TForm1 = class( TForm )
    PaintBox1: TPaintBox;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel; // Width: 560; Font.Name: Courier New; Font.Size: 8
    procedure PaintBox1Paint( Sender: TObject );
    procedure Edit1Change( Sender: TObject );
  private
    function CalculateCharWith( const C: Char ): Integer;
    function CalculateFixedCharWidth( const C: Char ): Integer;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

{ TForm1 }

function TForm1.CalculateCharWith( const C: Char ): Integer;
begin
  Result := PaintBox1.Canvas.TextWidth( C );
end;

function TForm1.CalculateFixedCharWidth( const C: Char ): Integer;
begin
  Result := 1;
end;

procedure TForm1.Edit1Change( Sender: TObject );
begin
  PaintBox1.Invalidate;
  // Ist von der Breite so angelegt, dass mit Courier New 8 genau 80 Zeichen hineinpassen
  Label2.Caption := ShortenText( Edit1.Text, 80, CalculateFixedCharWidth );
end;

procedure TForm1.PaintBox1Paint( Sender: TObject );
var
  lDrawText: string;
begin
  lDrawText := ShortenText( Edit1.Text, PaintBox1.ClientWidth, CalculateCharWith );
  Label1.Caption := PaintBox1.ClientWidth.ToString( ) + ' / ' + PaintBox1.Canvas.TextWidth( lDrawText ).ToString( );
  PaintBox1.Canvas.TextOut( 0, 0, lDrawText );
end;

end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat