![]() |
Abgeleiteter TButton mit Delphi Styles nicht richtig
Ich habe eine von TButton abgeleitete Komponente, die ich mit weiteren Win SDK Featurs ergänzt habe, die von der Delphi Implementation nicht unterstützt werden. Dazu habe ich zwei neue Properties ergänzt und entsprechend die System Flags gesetzt. Das Problem ist nun, dass diese nicht mehr funktionieren, sobald ein Delphi Style aktiviert wurde.
Die neuen Properties sind: TextAlign: TrfTextAlign Dieses Property steuert wie der Text im Button platziert wird. Dazu werden die entsprechenden System Styles (BS_xxx) gesetzt. Das Probem ist nun, dass diese beim Einsatz von Delphi Styles nicht richtig ausgewertet werden und der Text immer Links vertikal zentriert angezeigt wird. Das Probelm ist, dass BS_CENTER ($300) auch BS_LEFT ($100) enhält (?) und die Abfrage (TextStyle AND BS_LEFT) = BS_LEFT auch bei BS_CENTER gilt. Daher sollte da zuerst nach BS_CENTER abgefragt werden und erst danach nach BS_LEFT. Auch wird im TButton StyleHook das TextFlag immer auf DT_VCENTER gesetzt und somit die BS_TOP und BS_BOTTOM komplett ignoriert. Das TextFlag sollte doch auch die beiden vertikalen Flags beachten. WordWrap: Boolean (EDIT: Hat nichts mit den Delphi Styles zu tun sondern betrifft es immer) Das solle Multiline Funktionalität liefern. Das ist zwar in neueren Delphis nun auch automatisch "ein", aber ich möchte die Multiline Funktion auch gerne ausschalten können. Dieses hat aber leider nun keien Funktinon mehr, weil das intern übersteuert wird.
Delphi-Quellcode:
Die Frage ist nun wie ich das lösen kann, damit dieser Code für TextAlign auch bei Nutzung von Delphi Styles funktioniert. Muss ich da wirklich den ButtonStyleHook kopieren und für mich anpassen und wie kriege ich diesen dann in meine Komponente? Oder gibt es da eine einfachere objektbasierende Methode ohne Code zu kopieren?
TrfTextAlign = (talLeftTop, talLeft, talLeftBottom, talCenterTop, talCenter, talCenterBottom,
talRightTop, talRight, talRightBottom); TrfButton = class(TButton) private { Private-Deklarationen } FMultiLine: Boolean; FTextAlign: TrfTextAlign; procedure SetMultiLine(Value: Boolean); procedure SetTextAlign(Value: TrfTextAlign); protected { Protected-Deklarationen } public { Public-Deklarationen } constructor Create(AOwner: TComponent); override; procedure CreateParams(var Params: TCreateParams); override; published { Published-Deklarationen } property MultiLine: Boolean read FMultiLine write SetMultiLine default True; property TextAlign: TrfTextAlign read FTextAlign write SetTextAlign default talCenter; end; implementation const TextAligns: Array[TrfTextAlign] of Cardinal = (BS_LEFT or BS_TOP, BS_LEFT, BS_LEFT or BS_BOTTOM, BS_CENTER or BS_TOP, BS_CENTER, BS_CENTER or BS_BOTTOM, BS_RIGHT or BS_TOP, BS_RIGHT, BS_RIGHT or BS_BOTTOM); { TrfButton } constructor TrfButton.Create(AOwner: TComponent); begin inherited Create(AOwner); FMultiLine := True; FTextAlign := talCenter; end; //-------------------------------------------------------------------------------// procedure TrfButton.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); if FMultiLine then Params.Style := Params.Style or BS_MULTILINE; Params.Style := Params.Style or TextAligns[FTextAlign] or BS_TEXT; end; //-------------------------------------------------------------------------------// procedure TrfButton.SetMultiLine(Value: Boolean); begin if Value <> FMultiLine then begin FMultiLine := Value; RecreateWnd; end; end; //-------------------------------------------------------------------------------// procedure TrfButton.SetTextAlign(Value: TrfTextAlign); begin if Value <> FTextAlign then begin FTextAlign := Value; RecreateWnd; end; end; |
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Zitat:
Im konkreten Fall läuft es darauf hinaus eine neue Klasse von TButtonStyleHook zu deklarieren und dort das DrawButton zu überschreiben. Den Code kannst du erstmal von der originalen Klasse übernehmen und dann am Anfang das LTextFlags entsprechend anzupassen. Damit der Stylehook auch für deinen TrfButton funktioniert, musst du analog zu TButton einen class constructor und destructor anlegen, in dem der neue Stylehook registriert bzw. de-registriert wird. Nur so als Idee: Ich würde statt einem TextAlign zwei separate Properties für HAlign und VAlign machen. Das fände ich übersichtlicher als aus neun Möglichkeiten die passende auswählen zu müssen. |
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Ok sowas habe ich befürchtet. Muss ich denn im Create zuerst einen Unregsiter aufrufen, da ja der orignal Hook im Create des Vorfahren bereits gesetzt wurde. Ein weiteres Register mit einer abgeleiteten Klasse, würde doch dann zu einem Fehler führen, wenn ich das richtig sehe. Ist das so richtig oder wie wird das korrekt gemacht?
|
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Zitat:
Ein Unregister an dieser Stelle würde eher dazu führen, dass normale Buttons nicht mehr richtig gezeichnet würden. |
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Ach ja, das wäre eventuell ein Feature in QP wert. Sowohl die Windows-Implementierung als dann konsequenterweise auch beim Style.
|
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Was meinst du genau? Die Implementierung des TextAlign Features in der TButton Basisklasse oder was anderes?
Ich habe es übrigens nun mit Änderung der Flags lösen können. Ich untze BS_CENTER nciht mehr, da das anscheinend der Default ist. Ist mir zwar nachwievor unklar, wieso BS_CENTER auch BS_LEFT enthält und die Auswertung "Style AND x" hier eigentlich falsch ist. Alte Version, die nicht geht, wegen BS_CENTER
Delphi-Quellcode:
Neue Version, die so zu funktionieren scheint
const
TextAligns: Array[TrfTextAlign] of Cardinal = (BS_LEFT or BS_TOP, BS_LEFT, BS_LEFT or BS_BOTTOM, BS_CENTER or BS_TOP, BS_CENTER, BS_CENTER or BS_BOTTOM, BS_RIGHT or BS_TOP, BS_RIGHT, BS_RIGHT or BS_BOTTOM);
Delphi-Quellcode:
const
TextAligns: Array[TrfTextAlign] of Cardinal = (BS_LEFT or BS_TOP, BS_LEFT, BS_LEFT or BS_BOTTOM, BS_TOP, BS_VCENTER, BS_BOTTOM, BS_RIGHT or BS_TOP, BS_RIGHT, BS_RIGHT or BS_BOTTOM); |
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Zitat:
Delphi-Quellcode:
ist deklariert als 768, was hex $300 entspricht. Das ist dasselbe wie
BS_CENTER
Delphi-Quellcode:
.
BS_LEFT or BS_RIGHT
Das gilt übrigens auch für
Delphi-Quellcode:
.
BS_VCENTER = 3072 = $C00 = BS_TOP or BS_BOTTOM
|
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Zitat:
In dem Fall würde ich TextAlign und TextVAlign als zusätzliche Features für TCustomButton/TButton vorschlagen. Bei FMX gibt es das ja schon in TTextSettings. Dort sind es HorzAlign und VertAlign jeweils mit den Werten Center, Leading und Trailing, wobei mich die Benennung hier nicht so ganz überzeugt. Interessanterweise gibt es das innerhalb der VCL-Styles in StyleAPI.inc auch schon:
Delphi-Quellcode:
TSeTextAlign = (taTopLeft, taTopCenter, taTopRight, taLeft, taCenter,
taRight, taBottomLeft, taBottomCenter, taBottomRight); |
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Zitat:
|
AW: Abgeleiteter TButton mit Delphi Styles nicht richtig
Zitat:
Delphi-Quellcode:
.
LTextFlags := LTextFlags or DT_CENTER
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:10 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