Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - lbOwnerDrawVariable will nicht so richtig


maxk - So 29.08.04 09:27
Titel: lbOwnerDrawVariable will nicht so richtig
Erstmal der Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.ListBox1MeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
begin
 Caption:='Request for '+IntToStr(Index);
 Height:=Random(300);
 ListBox1.Items[Index]:=IntToStr(Height);
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
 with ListBox1.Canvas do begin
  FillRect(Rect);
  TextOut(Rect.Left,Rect.Top,ListBox1.Items[Index]);
 end;
end;
In der Listbox befinden sich 6 Einträge, und Style ist auf lbOwnerDrawVariable gesetzt. Leider scheint das Event OnMeasureItem gar nicht einzuteten. Mein Caption bleibt "Form1". Was mache ich falsch?

Danke für jede Hilfe,
maxk


Keldorn - So 29.08.04 10:17

Hallo

also bei mir geht das. Aber
Zitat:

ListBox1.Items[Index]:=IntToStr(Height);

ist eine kleine endlosschleife, denke ich. damit löst du immer wieder das onmeasureitem/ondrawitem -ereignis aus, da der listbox-eintrag neu gezeuichnet werden muß.

Mfg frank


maxk - So 29.08.04 10:54

Gut das war dann ein Folgefehler. In einem anderen Sourcecode ändere ich den Inhalt nicht und es geht trotzdem nicht. MeasureItem wird zwar aufgerufen, aber das Setzen von Height zeigt gar keine Wirkung. Ich versuche nämlich z.Z. Bilder unterschiedlicher Höhe in der Listbox anzuzeigen. In der OH steht zwar ein Beispiel für Bitmaps, aber das funzt nicht richtig. Warscheinlich gibt es irgendwo eine Property SillyUser, was ich noch auf False setzen muss :lol:


maxk - So 29.08.04 11:32

Das kann es nicht geben! Es funktioniert bei mir nur, wenn ich eine Item mit AddObject erstelle, dann geht's. Alle anderen Items erhalten keine MeasureItem - kann das wahr sein? Suche weiterhin eine Lösung, beider es ohne solche Objekte geht!


Keldorn - So 29.08.04 11:34

nee, ich habe bei mir nur items.add verwendet und es ging auch. Zeig mal mehr code bitte.


maxk - So 29.08.04 11:49

Mehr Code wird kaum nötig sein! MeasureItem wird scheinbar nur nach den Add Methoden aufgerufen und nicht vor dem Zeichnen!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
procedure TForm1.ListBox1MeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
begin
 Caption:='Request for '+IntToStr(Index);
 Height:=100+Random(300);
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
 with ListBox1.Canvas do begin
  FillRect(Rect);
  TextOut(Rect.Left,Rect.Top,ListBox1.Items[Index]);
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
// ListBox1.Items.Text:=ListBox1.Items.Text+#13#10+'Mit Text:= erstelltes Item';
 Listbox1.Items.Add('Items.Add');
 Listbox1.Items.AddObject('Items.AddObject -> Self',Self);
 Listbox1.Items.AddObject('Items.AddObject -> nil',nil);
 Listbox1.AddItem('AddItem -> Self',Self);
 Listbox1.AddItem('AddItem -> nil',nil);
end;
Soviel dazu. Startet man das Programm, funktioniert bei allen mit Add erstellten Items alles. Nur das bereits zur Designtime eingefügte Item wird mit der Standardhöhe dargestellt. Was jetzt lustig ist: Kommentiert man die erste Zeile in FormCreate wieder ein, so werden alle Items mit der richtigen Höhe gewzeichnet (auch das zur Designtime erstellte). Das Problem ist damit also gelöst :wink:

Hier noch etwas:
Online-Hilfe hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.ListBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);

var
  Bitmap: TBitmap;
begin
  with Control as TListBox do
  begin
    Bitmap := TBitmap(Items.Objects[Index]);
    if Bitmap <> nilthen
    if Bitmap.Height > Height then Height := Bitmap.Height;
  end;
end;
Man beachte, dass das im with-Block angegebene Height sich nicht auf die Variable Height bezieht, sondern auf die Listbox (da hat ein Codeschreiber nicht nachgedacht) :mrgreen:

Also Danke für die Hilfe,
maxk