Da Edit so spät nicht mehr geht, hier der nächste Eintrag:
Ich konnte zwar die Ursache für das Problem nicht finden, aber eine andere Lösung:
Delphi-Quellcode:
TMyComboBox = class(TComboBox)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
procedure TMyComboBox.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style := Style or CBS_NOINTEGRALHEIGHT;
end;
Mit dieser abgeleiteten Combobox wird die Höhe nicht mehr komplett automatisch berechnet.
Dann kann man z.B. folgendes machen:
Delphi-Quellcode:
FComboBox := TMyComboBox.Create(Self);
with FComboBox do begin
Height := 21;
Style := csOwnerDrawVariable;
ItemHeight := 50;
OnMeasureItem := ComboBoxMeasureItem;
OnDrawItem := ComboBoxDrawItem;
DropDownCount := 7;
Parent := Self;
end;
procedure blabla.ComboBoxMeasureItem(Control: TWinControl;
Index: Integer; var _Height: Integer);
begin
if Index > -1 then begin
_Height := 50; // alle ausgeklappten Einträge mit 50px zeichen
end else
_Height := 14; // den Inhalt der 21px hohen Combobox nur 14px hoch zeichnen
end;
procedure blabla.ComboBoxDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
ItemString: string;
begin
// das hier bitte mit eigener Zeichnen-Funktion ersetzen, das ist nur ein Dummy, der mehrzeilig Text ausgibt
TComboBox(Control).Canvas.FillRect(Rect);
ItemString := TComboBox(Control).Items.Strings[Index];
DrawText(TComboBox(Control).Canvas.Handle, PChar(ItemString), - 1, Rect, DT_WORDBREAK);
end;
Die ComboBox scheint jetzt generell das zu machen, was sie soll.
Tip: Mit Style := csOwnerDrawFixed scheint das nicht zu klappen. Also immer brav csOwnerDrawVariable verwenden.
Ich hoffe, mit dieser kleinen Erkenntnis konnte ich zukünftig Suchenden ein wenig helfen.
PS: Wie kommt man von sich aus darauf, nach "CreateParams" zu suchen?
Lg Mathias
Noch ein Nachtrag: Es muss nicht unbedingt die Lösung für das Spinnen der Höhenberechnung sein, aber eine ComboBox dreht komplett durch, wenn man in der ComboBoxDrawItem Prozedur versehentlich Eigenschaften ändert, die man eigentlich beim Canvas ändern wollte: Am Besten führt man ja die ComboBoxDrawItem Prozedur mit "with TComboBox(Control).Canvas do begin" durch, damit alle Zugriffe auf Font, Brush, ... direkt den Canvas betreffen. Bei einem Quick'n'Dirty Testprogramm, wo man nur 1-2 Sachen testen will, kann im Eifer des Gefechts auch mal ein Font.Color := ... vor oder hinter diesen "with" Block gelanden. Und dann passiert nur noch Unsinn