Es geht mir um den automatischen Zeilenumbruch. Da ich nicht weiß wie groß das Fenster, die Schrift etc sein wird, kann ich leider vorher nicht wissen, wo die richtige Stelle für einen Zeilenumbruch wäre und ihn vorher setzen, zumal es ja auch schön wäre, wenn sich die Größe automatisch anpasst, wenn man die Fenstergröße ändert, wie es ja auch beim Label schon funktioniert.
Plattformunabhängig wäre natürlich super, dann müsste man den Text allerdings vermutlich selber zeichnen. Ich habe mal versucht einen eigenen Nachfahr zu schreiben, komme aber an dieser Stelle nicht mehr weiter:
Code: Alles auswählen
unit RadioButtonWordWrap;
{$mode objfpc}{$H+}
interface
uses
Classes, StdCtrls, SysUtils, Windows, Graphics, Math;
type
{ TRadioButtonWordWrap }
TRadioButtonWordWrap = class(TRadioButton)
private
FWordWrap: boolean;
procedure SetWordWrap(AValue: boolean);
protected
procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer; WithThemeSpace: Boolean); override;
//procedure Paint; override; <-- gibt es nicht
public
constructor Create(AOwner: TComponent); override;
published
property WordWrap: boolean read FWordWrap write SetWordWrap;
end;
implementation
{ TRadioButtonWordWrap }
constructor TRadioButtonWordWrap.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
self.FWordWrap := false;
end;
procedure TRadioButtonWordWrap.SetWordWrap(AValue: boolean);
var
rb: DWORD;
begin
if FWordWrap = AValue then Exit;
FWordWrap := AValue;
rb := GetWindowLong(self.Handle, GWL_STYLE);
if rb <> 0 then begin
if AValue then begin
rb := rb or BS_MULTILINE or BS_VCENTER;
end else begin
rb := rb and not BS_MULTILINE and not BS_VCENTER;
end;
SetWindowLong(self.Handle, GWL_STYLE, rb);
self.Invalidate;
end;
end;
procedure TRadioButtonWordWrap.CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer; WithThemeSpace: Boolean);
var
bmp: TBitmap;
ALines: integer;
begin
inherited CalculatePreferredSize(PreferredWidth, PreferredHeight, WithThemeSpace);
if self.FWordWrap then begin
bmp := TBitmap.Create;
bmp.Canvas.Font.Assign(self.Font);
ALines := ceil(bmp.Canvas.TextWidth(self.Caption) / (self.Width - 25));
PreferredHeight := ALines * bmp.Canvas.TextHeight(self.Caption);
bmp.Free;
end;
end;
//procedure TRadioButtonWordWrap.Paint;
//begin
// self.canvas gibt es leider nicht...
//end;
end.
Leider gibt es keine Paint-Prozedur die ich einfach überschreiben könnte, wie es bei anderen Controls ja geht... Auch einen Canvas gibt es beim RadioButton nicht worauf ich zeichnen könnte. Wie kann man dann den Text selber zeichnen?
Bei der Berechnung der nötigen Höhe komme ich auch nicht wirklich weiter, man könnte hier zwar mit TextWidth arbeiten (siehe mein Code), aber ich weiß ja zum Beispiel nicht wie viel Platz durch das Feld für den Haken drauf geht und wo genau ein Wort umbricht, daher sind die Werte ungenau, gerade in Grenzfällen (sieht man wenn man das Fenster langsam vergrößert und verkleinert, wo es dann entweder zu spät oder zu früh umbricht).
Weiß vielleicht jemand wie man das anpassen kann damit es klappt?
PS: Hab das ganze mal als Beispielprojekt angehängt.