AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen FreePascal Text zur Anzeige kürzen mit Punkten hinten
Thema durchsuchen
Ansicht
Themen-Optionen

Text zur Anzeige kürzen mit Punkten hinten

Ein Thema von Guido Eisenbeis · begonnen am 28. Okt 2011 · letzter Beitrag vom 4. Nov 2011
Antwort Antwort
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Text zur Anzeige kürzen mit Punkte hinten

  Alt 31. Okt 2011, 04:27
Guck mal genau hin. Ich gebe den Text nicht auf einem Panel aus, sondern auf der Form selber, wo du aber auch gesagt hast, das würde nicht funktionieren.
Warum sollte ich da nicht genau hingesehen haben? Ich habs sogar genau hier rauskopiert, zwei neue Projekte erstellt (1x Delphi, 1x Lazarus), ein Paint-Ereignis für Form1 erstellt und deinen Code hinein kopiert. Nix zu sehen.

Guido.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.990 Beiträge
 
Delphi 12 Athens
 
#2

AW: Text zur Anzeige kürzen mit Punkte hinten

  Alt 31. Okt 2011, 06:22
Bis Windows XP sollte das funktionieren. Und ab Vista sollte der Text zumindest am Anfang auch sichtbar sein.

Durch die neuen Grafiktechniken von Vista und Windows 7 kann es sein, dass die Ressourcenoptimierung da einen Strich durch die Rechnung macht. Denn da wird WM_PAINT schlicht nicht mehr so oft an das Fenster geschickt. Dass der Text durch das DT_VCENTER aber an anderer Stelle neu gezeichnet werden müsste, weiß Windows nicht. Deshalb kann es passieren, dass der Text nicht zu sehen ist.

Dieses neue Verhalten führt zwar zu einer teilweise deutlich flüssigeren Oberfläche unter insbesondere Windows 7 gegenüber XP, aber eben auch manchmal zu Problemen, wenn man nicht auch auf das Resizen reagiert.

Lösung zum Testen:
Ersetze DT_VCENTER durch DT_TOP und schiebe das Fenster ganz nach oben links auf den Bildschirm.

Der eigentliche Fehler ist nämlich, dass das Window-Rect sich auf Bildschirmkoordinaten bezieht, DrawText hingegen auf Fenster-Koordinaten.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (31. Okt 2011 um 06:25 Uhr)
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Text zur Anzeige kürzen mit Punkte hinten

  Alt 31. Okt 2011, 11:05
Danke für die ausführliche Beschreibung. Werd ich heute abend testen.

O.T. Wie kann ich denn den Thread-Titel ändern? Der Bearbeiten-Button ist nicht mehr da (Zeitlimit). Hab nämlich erst jetzt gesehen, dass ich "Punkten" ohne "n" geschrieben habe. Wenn's nicht geht, bleibt's so.

Guido.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.990 Beiträge
 
Delphi 12 Athens
 
#4

AW: Text zur Anzeige kürzen mit Punkte hinten

  Alt 31. Okt 2011, 12:53
O.T. Wie kann ich denn den Thread-Titel ändern? Der Bearbeiten-Button ist nicht mehr da (Zeitlimit). Hab nämlich erst jetzt gesehen, dass ich "Punkten" ohne "n" geschrieben habe. Wenn's nicht geht, bleibt's so.
In diesem Forum kannst du den Thread dafür nur melden, damit es ein Moderator macht.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Text zur Anzeige kürzen mit Punkten hinten

  Alt 2. Nov 2011, 08:23
Den Thread-Titel wurde schon von einem netter Moderator geändert! Danke.

Lösung zum Testen:
Ersetze DT_VCENTER durch DT_TOP und schiebe das Fenster ganz nach oben links auf den Bildschirm.

Der eigentliche Fehler ist nämlich, dass das Window-Rect sich auf Bildschirmkoordinaten bezieht, DrawText hingegen auf Fenster-Koordinaten.
Das war's! Ich wundere mich nur, dass das Lucky nicht aufgefallen ist. Hast du (Lucky) deine Form ganz links oben platziert? Der Text müsste bei dir doch auch verschwinden, wenn die Form woanders ist, oder?

Somit sollte DrawText jetzt abgehandelt sein.


Mit DrawTextEx kann man eine Rückgabe als String erhalten. Siehe die letzte Variante, also die mit dem Handle (HDC), in Text kürzen (Ellipsis...) von himitsu.


----------------------------------- Nachtrag Anfang -----------------------------------

Habe gerade festgestellt, dass die Funktion von himitsu in Lazarus beim Kürzen von Umlauten ein "?" an der Stelle des Umlauts zeigt. Zum Testen habe ich den Code-Teil von himitsu hier als kompaktes Beispiel zusamengestellt.

Einfach ein TLabel (Label1) auf die Form setzen, AutoSize ausschalten, Label1 links und rechts bis knapp vor den Rand vergrößern. Dann ein FormCreate und ein FormResize erstellen und folgenden Code einfügen. Für ganz Bequeme häng ich ein Beispiel-Projekt an.

Wird die Form langsam verkleinert, bis gerade so das "ü" verschwindet, taucht an dessen Stelle ein "?" auf. Muss da irgendwas auf UniCode umgestellt, oder Lazarus neu kompiliert werden?

Delphi-Quellcode:
// "Classes" und "Windows" zu den uses hinzufügen.

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Label1.AutoSize muss zur Design-Zeit = False gestellt werden;

  Label1.Anchors := [akLeft, akRight, akTop];
end;

function GetEllipsisText(Handle: HDC; S: String; MaxWidth: Integer; MaxHeight: Integer = 0;
  PathEllipsis: Boolean = False; TextFormat: LongWord = 0): String;
var
  R: TRect;
begin
  Result := S;
  UniqueString(Result);
  if MaxHeight <= 0 then
    MaxHeight := 1000;
  R := Classes.Rect(1, 1, MaxWidth, MaxHeight);
  TextFormat := TextFormat or DT_CALCRECT or DT_MODIFYSTRING;
  if PathEllipsis then
    TextFormat := TextFormat or DT_PATH_ELLIPSIS;
  if TextFormat and (DT_END_ELLIPSIS or DT_PATH_ELLIPSIS) = 0 then
    TextFormat := TextFormat or DT_END_ELLIPSIS;
  DrawTextEx(Handle, PChar(Result), Length(Result), R, TextFormat, nil);
  SetLength(Result, StrLen(PChar(Result)));
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Label1.Caption := GetEllipsisText(
    Label1.Canvas.Handle, 'Beispiel-Text für FormResize.', Label1.Width);
end;
------------------------------------- Nachtrag Ende -------------------------------------


Meine Variante "SetShortenedTextWithDots" folgt alsbald. . . . Nachtrag: Das Umlautproblem tritt hier auch auf.

Guido.


Edit: Nachtrag und Beispiel-Projekt hinzugefügt.
Angehängte Dateien
Dateityp: zip Ellipsis-Code von himitsu - kompakt.zip (743,9 KB, 7x aufgerufen)

Geändert von Guido Eisenbeis ( 2. Nov 2011 um 11:00 Uhr) Grund: Nachtrag und Beispiel-Projekt hinzugefügt.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.990 Beiträge
 
Delphi 12 Athens
 
#6

AW: Text zur Anzeige kürzen mit Punkten hinten

  Alt 2. Nov 2011, 12:50
Das Problem mit dem Umlauten liegt jedenfalls an Lazarus, mit Delphi geht es problemlos. Da musst du wohl schauen was da intern passiert...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.401 Beiträge
 
Delphi 12 Athens
 
#7

AW: Text zur Anzeige kürzen mit Punkten hinten

  Alt 2. Nov 2011, 14:10
Also entweder 'nen WideString (gibt's den auch in Lazarus? ) und DrawTextExW verwenden, oder DrawTextExA mit AnsiString.

DrawTextExA könnte man zwar auch auf einen UTF-8-String loslassen, aber da könnte es passieren, daß er die Umlaute zerlegt, wenn er mitten drin die "..." einfügen will.

Eine UTF-8-Variante wird es von DrawTextEx wohl nicht geben? (Von Windows nicht, es sei denn man stellt UTF-8 als DefaultCodepage ein oder Lazarus konvertiert es nach Unicode)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Text zur Anzeige kürzen mit Punkten hinten

  Alt 2. Nov 2011, 15:03
Das Problem mit dem Umlauten liegt jedenfalls an Lazarus, mit Delphi geht es problemlos.
Klar, hab ich ja auch geschrieben: "... die Funktion von himitsu in Lazarus ..." . . Dennoch danke für die Bestätigung.


... Eine UTF-8-Variante wird es von DrawTextEx wohl nicht geben? (Von Windows nicht, es sei denn man stellt UTF-8 als DefaultCodepage ein oder Lazarus konvertiert es nach Unicode) ...
Ich hab jetzt einige Variationen mit WideString, Unicodestring, UTF8..., usw. probiert, hat sich aber nichts getan. Ich vermute auch viel eher, dass da in der IDE selbst eine Schalter ist, um das einzustellen. Ich hab schon einiges durchsucht (und probiert), aber das ist die sprichwörtliche "Naddel" im Heuhaufen. Wenn da ein Lazarus-Fachmann mitliest, wird er das wahrscheinlich als Kleinigkeit ansehen!?

Auf jeden Fall wird z. B. das "ü" intern ("Lokale Variablen"-Fenster) als "#195#188" angezeigt. Wird nun um ein Zeichen gekürzt, steht da noch "#195". Es wird also intern das "halbe ü" weggenommen, was im String als "?" dargestellt wird.

Guido.


Nachtrag:

OK, hab jetzt Folgedes herausgefunden:
Delphi-Quellcode:
function GetEllipsisText(Handle: HDC; S: String; MaxWidth: Integer; MaxHeight: Integer = 0;
  PathEllipsis: Boolean = False; TextFormat: LongWord = 0): String;
var
  R: TRect;
begin
  Result := UTF8ToAnsi(S); // <-- Konvertieren zu Ansi ...
  UniqueString(Result);
  if MaxHeight <= 0 then
    MaxHeight := 1000;
  R := Classes.Rect(1, 1, MaxWidth, MaxHeight);
  TextFormat := TextFormat or DT_CALCRECT or DT_MODIFYSTRING;
  if PathEllipsis then
    TextFormat := TextFormat or DT_PATH_ELLIPSIS;
  if TextFormat and (DT_END_ELLIPSIS or DT_PATH_ELLIPSIS) = 0 then
    TextFormat := TextFormat or DT_END_ELLIPSIS;
  DrawTextEx(Handle, PChar(Result), Length(Result), R, TextFormat, nil);
  SetLength(Result, StrLen(PChar(Result)));
  Result := AnsiToUTF8(Result); // <-- und zurück.
end;
Kann das jemand testen?

Guido.
Angehängte Dateien
Dateityp: zip Ellipsis-Code von himitsu - kompakt v2.zip (125,6 KB, 3x aufgerufen)

Geändert von Guido Eisenbeis ( 2. Nov 2011 um 16:15 Uhr) Grund: Nachtrag und Beispiel-Projekt hinzugefügt.
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Text zur Anzeige kürzen mit Punkten hinten

  Alt 4. Nov 2011, 10:13
Hier nun meine Variante.
Delphi-Quellcode:
// Routine zum Kürzen eines Textes und Anhängen von Punkten an den Text.
function SetShortenedTextWithDots(AFont: TFont; AText: String;
  AMaxWidth: Integer): string;
const
  Dots = ' ...';
var
  ShortTxt: String;
  Cnvs: TCanvas;
  RightSpace: Integer;
begin
  Cnvs := TCanvas.Create;
  try
    Cnvs.Font.Assign(AFont);
    Cnvs.Handle := GetDC(GetDesktopWindow);

    ShortTxt := AText;
    RightSpace := (Cnvs.TextWidth(Dots) * 2); // Platz schaffen für die Dots.

    // Text kürzen, bis er ins Control passt.
    while (AMaxWidth < (Cnvs.TextWidth(ShortTxt) + RightSpace)) do
    begin
      if Length(ShortTxt) < 2 then Break;
      ShortTxt := UTF8ToAnsi(ShortTxt); // Nur benötigt in Lazarus, wegen Umlauten.
      ShortTxt := LeftStr(ShortTxt, Length(ShortTxt) - 1);
      ShortTxt := AnsiToUtf8(ShortTxt); // Nur benötigt in Lazarus, wegen Umlauten.
    end;

    // Prüfen, ob der gekürzte oder der komplette Text angezeigt werden soll.
    if Length(ShortTxt) < Length(AText) then
      Result := ShortTxt + Dots
    else
      Result := AText;
  finally
    ReleaseDC(0, Cnvs.Handle);
    Cnvs.Free;
  end;
end;

Aufruf-Beispiel im FormResize:
Delphi-Quellcode:
// 1 TLabel, 1 TPanel und 1 TEdit auf die Form,
// bei Label1 AutoSize auf false setzen,
// bei Panel1 Alignment = taLeftJustify setzen,
// bei allen die Anchors = [akLeft, akRight, akTop] setzen,
// und alle seitlich vergrößern bis fast an den Form-Rand.
procedure TForm1.FormResize(Sender: TObject);
var
  Txt: String;
begin
  Txt := 'Beispiel-Text für FormResize';
  Label1.Caption := SetShortenedTextWithDots(Label1.Font, Txt, Label1.Width);
  Panel1.Caption := SetShortenedTextWithDots(Panel1.Font, Txt, Panel1.Width);
  Edit1.Text := SetShortenedTextWithDots(Edit1.Font, Txt, Edit1.Width);
end;
Das sollte in Delphi und in Lazarus funktionieren. Ich würde mich freuen, wenn ihr das testen würdet und über Anregungen. Falls Fehler drin sind, dürft ihr mir das auch sagen.

Guido.


Edit: Source-Codes zum Testen hinzugefügt.
Angehängte Dateien
Dateityp: zip Demo Source-Code - Lazarus.zip (126,6 KB, 4x aufgerufen)
Dateityp: zip Demo Source-Code - Delphi.zip (3,5 KB, 8x aufgerufen)

Geändert von Guido Eisenbeis ( 5. Nov 2011 um 02:38 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz