Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi WordWrap bei ListBoxen (https://www.delphipraxis.net/46792-wordwrap-bei-listboxen.html)

Marvel 31. Mai 2005 17:30


WordWrap bei ListBoxen
 
Hi Leutschers, ich wollt mal fragen, ob wer von euch für folgendes Problem hat:
Ich will in ner ListBox einfach nur Strings ausgeben lassen... ganze Sätze. Dadurch sind die aber oft zu breit für meine ListBox und man müsste dumm hin und her scrollen, damit man die sieht. Nun is meine Frage, wie ich es schaffe, dass der automatisch nen Zeilenumbruch macht, ohne dass ICH jedesmal abzählen muss, nach wie vielen Wörtern denn der Zeilenumbruch kommen muss...

danke im Voraus... und falls es was nützt... ich bin n bissel unter Zeitdruck... wär also nich schlecht, wenn ihr da schnell drauf antworten könnt..

schön Tag noch.

DGL-luke 31. Mai 2005 17:32

Re: WordWrap bei ListBoxen
 
mt einer listbox wird das nicht gehen.
du kannst aber in den hint über getitemat(mouseposition) o.ä. den aktuellen text reinschreiben und damit den satz komplett sichtbar machen.

marabu 31. Mai 2005 18:04

Re: WordWrap bei ListBoxen
 
Hallo Marvel,

schau dir mal den Style lbOwnerDrawVariable deiner Listbox in der Online-Hilfe an. Das müsste dich glücklich machen.

Grüße vom marabu

Marvel 31. Mai 2005 19:07

Re: WordWrap bei ListBoxen
 
naja... das hab ich auch schon gefunden, aber so recht raffen tu ich das nich...
Muss ich da über das OnMeasureItem-Ereignis gehen und dann dort die Variable Height ändern oder wie?

Marvel 31. Mai 2005 19:08

Re: WordWrap bei ListBoxen
 
@ DGL-luke:
naja... an sich ne gute Idee, aber das is nich das, was ich brauch.

marabu 31. Mai 2005 20:20

Re: WordWrap bei ListBoxen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Marvel,

Zitat:

Zitat von Marvel
naja... das hab ich auch schon gefunden, aber so recht raffen tu ich das nich...
Muss ich da über das OnMeasureItem-Ereignis gehen und dann dort die Variable Height ändern oder wie?

das klingt, als bräuchtest du noch etwas Hilfe. Ich habe dir eine kleine Demo angefertigt. Nicht schön aber selten.

Grüße vom marabu

Marvel 1. Jun 2005 15:55

Re: WordWrap bei ListBoxen
 
Erstmal dick fett danke... das is echt krass, was fürn Service es hier im Forum gibt...

Das Problem is aber, dass ich jeztt auch weiß, warum ich das vorher nich verstanden hab... weiß nich... falls es möglich is, dass ohne umfanssende Delphi-Grundlagen zu verstehen, würd mich das schon mal interessieren, was genau du wo machst und was das bedeutet...
Wenn nich habsch halt Pech gehabt...

Nomal danke und Tschö.

marabu 1. Jun 2005 19:36

Re: WordWrap bei ListBoxen
 
Hallo Marvel,

ich habe noch nie vorher eine Listbox mit dem Style lbOwnerDrawVariable gebraucht, aber deine Frage hatte mich dazu gebracht es einmal zu versuchen. Offensichtlich geht es nicht durch simples Klicken im Object Inspector, sonst hättest du ja nicht gefragt.

Durch die Online-Hilfe war mir schnell klar, dass ich diesen speziellen Style benötige, damit das Ereignis OnMeasureItem getriggert wird. Da war schon das erste Problem. Bei meinem Delphi 7 kann man zwar den Style im OI setzen, aber es bringt nichts. Erst durch das Setzen von Style im Ereignis OnCreate meiner DemoForm konnte ich sicher stellen, dass OnMeasureItem ausgeführt wird.

OnDrawItem ist ja einfach, also habe ich nur noch überlegt, wie ich die Höhe des Eintrags feststellen kann. Da DrawText() diese Höhe berechnet, brauchte ich nur noch ein Stück Schmierpapier (tempCanvas) um darauf vorzuschreiben. Die ermittelte Höhe übergebe ich dann an Height und intern wird das Rect ermittelt, welches an OnDrawItem() übermittelt wird - für das Schreiben in Reinschrift.

Alles klar?

Freundliche Grüße vom marabu

blackdrake 14. Aug 2009 05:23

Re: WordWrap bei ListBoxen
 
Eine Verbesserung des Codes von marabu.

Ich habe das Projekt in Delphi 6 Personal geöffnet und war über das Ergebnis nicht sonderlich erfreut. Jedesmal, wenn ich das Form in der Größe geändert habe, waren im weißen noch Reste des vorherigen Textes. Auch ist nur die oberste Zeile eingerückt. Die zweite Zeile ist beispielsweise visuell so geblieben und wurde erst mehrzeilig sichtbar, wenn man sie anklickte.

Die Lösung: Man füge ein Invalidate ein:

Delphi-Quellcode:
// Originalcode: marabu

procedure TDemoForm.ListBoxMeasureItem(Control: TWinControl;
  Index: Integer; var Height: Integer);
var
  tempCanvas: TCanvas;
  notUsed: HWND;
  destRect: TRect;
begin
  tempCanvas := TCanvas.Create;
  try
    tempCanvas.Handle := GetDeviceContext(notUsed);
    destRect := ListBox.ClientRect;
    Height := DrawText(tempCanvas.Handle, PChar(ListBox.Items[Index]), -1, destRect, DT_WORDBREAK);
  finally
    tempCanvas.Free;
  end;
end;

procedure TDemoForm.ListBoxDrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  with Listbox.Canvas do begin
    FillRect(Rect);
    DrawText(Handle, PChar(ListBox.Items[Index]), -1, Rect, DT_LEFT or DT_TOP or DT_WORDBREAK);
    Invalidate; // Hinzugefügt
  end;
end;

procedure TDemoForm.FormCreate(Sender: TObject);
begin
  Listbox.Style := lbOwnerDrawVariable;
end;
(Vorgeschlagen für die CodeLib)

Gruß
blackdrake

blackdrake 17. Aug 2009 19:06

Re: WordWrap bei ListBoxen
 
Ich habe einen weiteren Bugfix. Wenn eine Zeile leer war, dann sind die Zeilen ineinandergerutscht.

Delphi-Quellcode:
procedure TMDIEditor.CheckListBox1MeasureItem(Control: TWinControl;
  Index: Integer; var Height: Integer);
var
  tempCanvas: TCanvas;
  notUsed: HWND;
  destRect: TRect;
  txt: PChar;
begin
  tempCanvas := TCanvas.Create;
  try
    tempCanvas.Handle := GetDeviceContext(notUsed);
    destRect := CheckListBox1.ClientRect;
    if CheckListBox1.Items[Index] = '' then
      txt := ' '
    else
      txt := PChar(CheckListBox1.Items[Index]);
    Height := DrawText(tempCanvas.Handle, txt, -1, destRect, DT_WORDBREAK);
  finally
    tempCanvas.Free;
  end;
end;
PS: Bitte interpretiert das nicht als "gemecker" am Code. Ich freue mich sehr über diesen Code und wäre selbst nicht darauf gekommen und habe den Code jetzt ein wenig korrigiert, damit die Gemeinschaft ihn fehlerfrei nutzen kann.

Gruß
blackdrake


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:46 Uhr.

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