![]() |
Proportionalschrift in Listbox
Hi,
ich habe eine Listbox, bei der jede Zeile aus 3 Strings besteht, also st1+st2+st3 Die drei Teilstrings sollen allerdings untereinander stehen. Bei Font Sansserif z.B. klappt das selbst dann nicht, wenn ich die Strings rechts oder linksbündig mit Blanks auffülle. Mir fällt dazu nur ein : Schriftart wechseln, oder Stringgrid. Letzteres ist mir für diesen Zweck aber fast zu kompliziert. Und das erste sieht etwas seltsam aus. Gibts da noch irgendwas anderes? |
Hallo Hansa,
Du könntest die Listbox auch selber zeichnen und mittels Canvas.TextWidth() Deine Teilstrings pixelgenau plazieren. |
Wie wirkt sich das denn bei verschiedenen Bildschirm-Auflösungen aus :?: Ich will niemanden zwingen, eine bestimmte Auflösung zu benutzen.
|
Hei Hansa
Nimm doch eine Schrift wie CourierNew, bei der alle Zeichen gleich breit sind. Mirilin |
Zitat:
|
Hallo Hansa,
falls Du eine maximale Stringlänge haben solltest, kannst Du ja die Strings, vorne oder hinten mit Leerstellen auffüllen und so die Strings unterienander ausrichten. Das hatte ich mal in meinen anfängen gemacht, bis ich das auf eine LV wechseln musste, was aber nichts damit zutun hatte. Grüsse, Daniel :hi: |
Zitat:
Zitat:
|
Zitat:
Grüsse, Daniel :hi: |
Zitat:
|
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Hansa,
anbei ein Beispiel für die mehrspaltige Ausgabe. Ist zwar auf zwei gekürzt, kann aber beliebig erweitert werden.
Code:
Im Anhang noch ein Bild, wie's aussieht.
{ lbxOrt.Style muß auf lbOwnerDrawFixed gesetzt sein für eigene Auswahlliste
Ergebnis: 2-spaltige Tabelle (mehr ist möglich Nachteil: der Sprung auf den bereits eingegebenen Ort erfolgt nicht } procedure TFKasse.lbxOrtDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var strVal, strAll : string; pos1, pos2 : integer; rc : TRect; arrWidth : array[0..3] of integer; begin lbxOrt.Canvas.Brush.Style := bsSolid; lbxOrt.Canvas.FillRect(Rect); { Die einzelnen Spalten müssen durch ';' getrennt sein } strAll := lbxOrt.Items[Index]; arrWidth[0] := 0; arrWidth[1] := 120; arrWidth[2] := lbxOrt.Width; { Zeichenbereich für erste Spalte } rc.Left := Rect.Left + arrWidth[0] + 2; rc.Right := Rect.Left + arrWidth[1] - 2; rc.Top := Rect.Top; rc.Bottom := Rect.Bottom; { Text für erste Spalte ausfiltern } pos1 := Pos(';', strAll); strVal := Copy(strAll, 1, pos1 - 1); { Text ausgeben } lbxOrt.Canvas.TextRect(rc, rc.Left, rc.Top, strVal); { Trennlinie zwischen Spalten zeichnen } lbxOrt.Canvas.MoveTo(rc.Right, rc.Top); lbxOrt.Canvas.LineTo(rc.Right, rc.Bottom); { Zeichenbereich für zweite Spalte } rc.Left := Rect.Left + arrWidth[1] + 2; rc.Right := Rect.Left + arrWidth[2] - 2; { Text für zweite Spalte ausfiltern } strAll := Copy(strAll, pos1 + 1, Length(strAll) - pos1); pos1 := Pos(';', strAll); if pos1 > 0 then strVal := Copy(strAll, 1, pos1 - 1) else strVal := strAll; { Text ausgeben } lbxOrt.Canvas.TextRect(rc, rc.Left, rc.Top, strVal); { Trennlinie zwischen Spalten zeichnen } lbxOrt.Canvas.MoveTo(rc.Right, rc.Top); lbxOrt.Canvas.LineTo(rc.Right, rc.Bottom); end; mfg eddy |
mußt Du mir das wirklich antun? Jetzt muß ich mir das doch tatsächlich noch durchlesen. Das Bild sieht nämlich gut aus und wenn ich das allgemeingültig hinkriege ists auch gut.
|
Hallo Hansa,
gute Idee! (Das mit dem Verallgemeinern) Hier mein eine erste optimierte Version:
Code:
mfg
{ lbxOrt.Style muß auf lbOwnerDrawFixed gesetzt sein für eigene Auswahlliste
Ergebnis: 2-spaltige Tabelle (mehr ist möglich Nachteil: der Sprung auf den bereits eingegebenen Ort erfolgt nicht } procedure TFKasse.lbxOrtDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); const mx = 2; // = Anzahl der Spalten arrWidth : array[0..mx] of integer = (0,120,150); var strVal, strAll : string; i, pos1 : integer; rc : TRect; begin lbxOrt.Canvas.Brush.Style := bsSolid; lbxOrt.Canvas.FillRect(Rect); // nur zur Sicherheit: arrWidth[mx] := lbxOrt.Width; // oben und unten bleiben unverändert rc.Top := Rect.Top; rc.Bottom := Rect.Bottom; { Die einzelnen Spalten müssen durch ';' getrennt sein } strAll := lbxOrt.Items[Index]; // z.B.: "Ortename;12345" for i := 0 to High(arrWidth) - 1 do begin { Zeichenbereich für erste Spalte } rc.Left := Rect.Left + arrWidth[i] + 2; rc.Right := Rect.Left + arrWidth[i+1] - 2; { Text für erste Spalte ausfiltern } pos1 := Pos(';', strAll); if pos1 > 0 then strVal := Copy(strAll, 1, pos1 - 1) else strVal := strAll; { Text ausgeben } lbxOrt.Canvas.TextRect(rc, rc.Left, rc.Top, strVal); { Trennlinie zwischen Spalten zeichnen } lbxOrt.Canvas.MoveTo(rc.Right, rc.Top); lbxOrt.Canvas.LineTo(rc.Right, rc.Bottom); { Text für nächste Spalte ausfiltern } strAll := Copy(strAll, pos1 + 1, Length(strAll) - pos1); end; end; eddy |
|
Hallo Daniel,
hast Du das getestet? Bisher halte ich noch nicht viel davon. 1. habe ich jetzt keine Spalten mehr sondern nur noch: Ortname^I09000 statt Ortname 09000 und 2. hätte ich gern unterschiedlich breite Spalten, weil für die Plz weniger Platz benötigt wird wie für den Ort. mfg eddy |
Hallo eddy,
Zitat:
Zitat:
Zitat:
Aber für Hansa würde es doch langen, wenn Du Dich schon nicht damit zufrieden gibst, aber Du musst zugeben, es ist deutlich kürzer als Dein Code. ;) Grüsse, Daniel :hi: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:44 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