Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   String Umbruch (https://www.delphipraxis.net/206388-string-umbruch.html)

venice2 16. Dez 2020 14:23

String Umbruch
 
Ich habe eine ListView OwnerDraw erstellt. (siehe Anhang)
Und schicke dieser einen String der so aussieht.

Delphi-Quellcode:
    LVZattoo.SetItemText(LVZattoo.Handle, (i - 1), 1, ChlRec.title
      + #13#10 + 'Genre: ' + FZat.gEpg[i - 1].g + #13#10 + 'Sendung: '
      + FZat.gEpg[i - 1].t + #13#10 + 'Laufzeit: ', 8);
Eine ListView ist ja eigentlich nicht dafür ausgelegt einen String innerhalb der Zeile umzubrechen.

Mein Problem ist nun das sich dadurch die Scrollbar verändert obwohl der String (Sichtbar) eigentlich gar nicht hinausragt.
Wie kann ich dem ListView nun mitteilen das ein Umbruch stattgefunden hat?

ein #0 anhängen bringt nichts.

stahli 16. Dez 2020 14:44

AW: String Umbruch
 
Ich habe so etwas ähnliches mit Frames umgesetzt.

- alle Frames in die aktuelle Scrollbox-Breite zeichnen und dabei die benötigte Breite ermitteln
- maximal benötigte Breite ebenfalls merken
- wenn maximal benötigte Breite nicht mit realer Breite übereinstimmt, dann die Liste neu durchgehen und die Breite aller Frames neu setzen
- dabei wird auch berücksichtigt, wenn die Einblendung der vertikalen Scrollbar (ja/nein) sich bei der Aktualisierung ändert

Ich befürchte, dass Du keine ganz einfache Lösung finden wirst (es sei denn, es gibt schon eine Listview, die das passend umsetzt).

venice2 16. Dez 2020 14:48

AW: String Umbruch
 
Zitat:

Zitat von stahli (Beitrag 1479269)
Ich habe so etwas ähnliches mit Frames umgesetzt.

- alle Frames in die aktuelle Scrollbox-Breite zeichnen und dabei die benötigte Breite ermitteln
- maximal benötigte Breite ebenfalls merken
- wenn maximal benötigte Breite nicht mit realer Breite übereinstimmt, dann die Liste neu durchgehen und die Breite aller Frames neu setzen
- dabei wird auch berücksichtigt, wenn die Einblendung der vertikalen Scrollbar (ja/nein) sich bei der Aktualisierung ändert

Ich befürchte, dass Du keine ganz einfache Lösung finden wirst (es sei denn, es gibt schon eine Listview, die das passend umsetzt).

Hmmm. überlege ob ich den String nicht einfach als Array übergebe. Nur bringt das was

Ich dachte eigentlich wenn man einen NULL terminierten String anhängt also #0 müsste die Liste das erkennen das der String hier beendet wird.
Tut sie aber nicht.

Moombas 16. Dez 2020 14:53

AW: String Umbruch
 
Kannst du nicht einfach die waagerechte Scrollbar abschalten bzw. spricht da etwas dagegen?

venice2 16. Dez 2020 15:02

AW: String Umbruch
 
Zitat:

Zitat von Moombas (Beitrag 1479271)
Kannst du nicht einfach die waagerechte Scrollbar abschalten bzw. spricht da etwas dagegen?

Ja wenn der Text länger ist dann muss ich scrollen.
Ich weis ja nicht welcher String mir da geliefert wird.
Die Sendungstitel könnte ja sehr lang sein ;)

Delphi.Narium 16. Dez 2020 16:57

AW: String Umbruch
 
Alternativvorschlag:
Delphi-Quellcode:
const
  ciTextBreiteInBuchstaben = 25;
...
 LVZattoo.SetItemText(LVZattoo.Handle, (i - 1), 1,
    SysUtils.WrapText(ChlRec.title,ciTextBreiteInBuchstaben) + #13#10 
  + 'Genre: ' + FZat.gEpg[i - 1].g + #13#10 
  + 'Sendung: ' + FZat.gEpg[i - 1].t + #13#10 
  + 'Laufzeit: ', 8);
ciTextBreiteInBuchstaben weist Du einen Wert zu, der der maximal sinnvoll anzeigbaren Breite in Buchstaben entspricht.

WrapText sorgt für eine entsprechende Textbreite, in dem es bei Erreichen dieses Wertes beim nächsten auftretenden WhiteSpace einen Zeilenumbruch einfügt.

Dann musst Du Dir keine Gedanken über Scrollbar Ja/Nein ... machen. Der Sendungstitel enthält dann jeweils auch entsprechend viele Zeilenumbrüche.

Ob's damit dann besser aussieht, müsstest Du mal ausprobieren.

venice2 16. Dez 2020 16:58

AW: String Umbruch
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1479294)
Alternativvorschlag:
Delphi-Quellcode:
const
  ciTextBreiteInBuchstaben = 25;
...
 LVZattoo.SetItemText(LVZattoo.Handle, (i - 1), 1,
    SysUtils.WrapText(ChlRec.title,ciTextBreiteInBuchstaben) + #13#10 
  + 'Genre: ' + FZat.gEpg[i - 1].g + #13#10 
  + 'Sendung: ' + FZat.gEpg[i - 1].t + #13#10 
  + 'Laufzeit: ', 8);
ciTextBreiteInBuchstaben weist Du einen Wert zu, der der maximal sinnvoll anzeigbaren Breite in Buchstaben entspricht.

WrapText sorgt für eine entsprechende Textbreite, in dem es bei Erreichen dieses Wertes beim nächsten auftretenden WhiteSpace einen Zeilenumbruch einfügt.

Dann musst Du Dir keine Gedanken über Scrollbar Ja/Nein ... machen. Der Sendungstitel enthält dann jeweils auch entsprechend viele Zeilenumbrüche.

Ob's damit dann besser aussieht, müsstest Du mal ausprobieren.

Super werde es direkt mal versuchen..
Danke.

Melde mich dann.

ciTextBreiteInBuchstaben .. kann das nicht length text sein?
bzw. nach was richtet sich die value davon.

PS:
Es macht keinen unterschied.

Delphi.Narium 16. Dez 2020 17:14

AW: String Umbruch
 
Ich weiß halt nicht, wie breit der Text in Deiner Anzeige sein darf, ohne das die Scrollbar benutzt werden muss.

Du müsstest bitte mal mit 'nem sehr langen Sendungstitel ausprobieren, wieviele Zeichen in einer Zeile angezeigt werden können, ohne dass der Text quasi über den rechten Rand hinausreicht. Oder bei der vorhandenen Anzeige mal für 'ne Reihe von Sendungstitel nachzählen, nach wievielen Buchstaben im Schnitt der rechte Rand erreicht ist.

Eventuell probierst Du es mal mit 'nem Sendungstitel ala 'WWW WWW WWW WWW WWW WWW WWW WWW WWW WWW WWW WWW' aus und zählst nach, wieviele WWW plus jeweils ein Leerzeichen angezeigt werden können, bevor der rechte Rand des Listviews erreicht ist. Die Anzahl der WWW * 4 nimmst Du dann als Wert für ciTextBreiteInBuchstaben. Passen z. B. acht WWW in den Listview, ohne den rechten Rand zu "überragen", wäre der Wert für ciTextBreiteInBuchstaben = 32.

Aber letztlich wird es darauf hinauslaufen, dass Du den "richtigen Wert" für ciTextBreiteInBuchstaben durch ausprobieren herausbekommen musst. Bei der Schriftart Courier New haben z. B. alle Buchstaben die gleiche Breite. Bei den anderen Schriftarten eher nicht, so dass man hier eigentlich keinen genauen oder "richtigen" Wert angeben kann. Da hilft nur probieren und sich dann für einen in der Regel passenden Wert entscheiden.

venice2 16. Dez 2020 19:11

AW: String Umbruch
 
Ich mache es jetzt so.

Delphi-Quellcode:
    LVZattoo.SetItemText(LVZattoo.Handle, (i - 1), 1, ChlRec.title, 8,
      'Genre: ' + FZat.gEpg[i - 1].g + ';' +
      'Sendung: ' + FZat.gEpg[i - 1].t + ';' +
      'Laufzeit: ');
und löse es dann so auf.

Delphi-Quellcode:
   if Assigned(ColumnInfo[HeaderItem].SplitStr) then
   begin
     if ColumnInfo[HeaderItem].SplitStr[Item] <> '' then
     begin
       sSplit := Split(ColumnInfo[HeaderItem].SplitStr[Item], ';');
       TmpRect.Top := TextRect.Top;
       TmpRect.Left := TextRect.Left;
       TmpRect.Right := TextRect.Right;
       for i := Low(sSplit) to High(sSplit) do
       begin
         TmpRect.Top := TmpRect.Top + FPointSize + 2;
         DrawEllipsisText(WinHandle, DC, sSplit[i], TmpRect, Color, FFontName,
           FPointSize, FFontStyle, 0, 0);
        end;
     end;
    end;
anders geht es im Moment nicht bis ich eine bessere Lösung gefunden habe.

Oben wird der String mit Delemiter ';' übergeben
und unten ausgewertet.
Der string selbst wird nicht mehr an das Listview übergeben nur ChlRec.title (= wsItems)

Delphi-Quellcode:
procedure TSkinListView.SetItemText(hListView: hWnd; nItem: Integer; nSubItem: Integer;
  wsItems: WideString; TextTop: Integer = 0; SplitStr: WideString = '');
var
  lvItem: LV_ITEMW;
begin

  lvItem.mask := LVIF_TEXT;
  lvItem.iItem := nItem;
  lvItem.pszText := PWideChar(wsItems);
  lvItem.iSubItem := nSubItem;
  ListView_SetItem(hListView, lvItem);

  ColumnInfo[nSubItem].TextTop := TextTop;
  if SplitStr <> '' then
  begin
    SetLength(ColumnInfo[nSubItem].SplitStr, (nItem + 1));
    ColumnInfo[nSubItem].SplitStr[nItem] := SplitStr;
  end;

end;

Moombas 17. Dez 2020 07:49

AW: String Umbruch
 
Zitat:

Zitat von venice2 (Beitrag 1479273)
Zitat:

Zitat von Moombas (Beitrag 1479271)
Kannst du nicht einfach die waagerechte Scrollbar abschalten bzw. spricht da etwas dagegen?

Ja wenn der Text länger ist dann muss ich scrollen.
Ich weis ja nicht welcher String mir da geliefert wird.
Die Sendungstitel könnte ja sehr lang sein ;)

Richtig, ist die Frage ob das von dir dann aber gewollt ist :) und wie dein Aufbau ist.

Vorschlag:
Ich würde ggf. in so einer Liste nur grobe Informationen anzeigen, beim Hover darauf dann ins Detail gehen im Hover.

Dann könntest du einfach eine maximale Stringlänge angeben (Was Delphi.Narium aufgezeigt hat) brauchst aber keinen zusätzlichen Stringumbruch ggf. Einbauen, sondern würdest den Text "Beschneiden" (evtl. auch nur dann den Hover "erlauben") und generell keine waagerechte Scrollleiste erlauben.

Dadurch bleibt das Layout gleich, die Funktionalität leidet nicht und in geschätzt 90% der Fälle solltest du alle Informationen immer angezeigt bekommen.


OT: Ich würde [ und " beim Genre entfernen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:08 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz