![]() |
Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Seit einiger Zeit habe ich mit den Delphi Styles einwenig experimentiert. Da ich eine Menge eigener (visueller) Komponenten habe stellt sich mir aber nun die Frage, wie man am besten deren Style integriert, sodass sie bei einem Stylewechsel passend angezeigt werden.
Für ein paar ganz einfach Komponenten reicht es natürlich im Paint() die StyleServices zu verwenden und eventuell auch System oder Stylefarben für eigene Zusätze zu "missbrauchen". Mitunter gibt es aber komplexere Komponenten, die mehrere zum Style passende Elemente benötigen würden (in der Regel eigene Farben wie zum Beispiel bei einer "Log"-Komponente die für Fehler, Warnungen und normalen Text unterschiedliche Farben benötigt - und das eben abhängig vom durch einen Style gegebenen Hintergrund). Hin und wieder wären aber auch ein paar Grafiken von Vorteil die auch, abhängig vom Style, mal heller mal dunkler daherkommen sollten. Irgend etwas zu den original Styles hinzuzufügen ist ja wohl verboten und auch Kopien davon, dafür zu verwenden erscheint mir nicht gerade vernünftig. Man könnte natürlich für jede Komponente die entsprechenden Ressourcen für alle momentan bekannten Styles speichern und bei einem Stylewechsel nachsehen ob Einstellungen dafür vorhanden sind (über den Stylenamen?) und diese dann verwenden. Ist aber mühsam und bei einer Lib mit 50+ Komponenten ganz schön aufwendig und dann auch über die ganze Lib. verstreut! Schön wäre es etwa, wenn ich für alle Komponenten ein gemeinsames Style-File haben könnte indem nur meine Einstellungen enthalten sind (scheitert schon mal daran, dass im Bitmap-Stil-Designer ein "Neu"es Projekt komplett mit einer vollen Konfiguration bestückt ist und leider Löschen auch verboten ist). Theoretisch könnte ich dann für jeden Delphi Style eine eigene .vsf haben und diese müsste mit ausgeliefert werden (ob als eigenständige Datei oder auch als Ressource) und dann müsste es auch noch eine Methode geben, die meine Zusätze mit denen der dazugehörenden Styles verbindet.... Letzteres wäre dann auch noch ein zweites Mal von Vorteil, weil auch die eigentliche Applikation noch styleabhängige Komponenten mitbringen kann (z.B.: einen umfangreichen Satz an Icons die zumindestens für "helle" und "dunkle" Styles andere Farben haben müssen)... Also eine Menge Fragen, ich hoffe, dass es - wie immer - ein paar Spezialisten gibt, die sich damit auskennen... |
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Zitat:
Wenn du in deinen Komponenten viel selber auf den Canvas zeichnest, bieten sich die Methoden von StyleServices an. Beispielsweise GetSystemColor und GetStyleColor. Welche Farben das für die einzelnen Styles sind, kann man sich im Bitmap Style Designer unter "Colors" und "SysColors" anschauen. Eine weitere Möglichkeit wäre das Schreiben eigener StyleHooks für deine Komponenten. Somit wäre zumindest das Zeichen im Styling-Fall von den bisherigen Code entkoppelt. Das VCL Styles Project ist dir ein Begriff? ![]() |
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Ja kenn ich, hab auch selber ein paar fixes für Delphi XE5 an den StyleHooks gemacht... ist aber ein Beispiel dafür, wie man es eben nicht machen sollte die eigenen Erweiterungen in den Originalstyle zu integrieren ist - aus meiner Sicht - ein "no go".
Vielleicht waren meine Fragen aber wirklich nicht klar genug definiert. Die Hauptfrage ergibt sich aber aus dem Titel des Threads: 1. Korrekter Umgang mit Delphi Styles und eigenen Komponenten? 1.1. Eigene Farben für jeden Stil definieren (wo am besten)? 1.2. Eigene Graphiken für jeden Stil definieren (wo/wie)? 2. Korrektes Management für die einzelnen Zusätze 2.1. Wo hin mit den eigenen Definitionen (siehe 1.1, 1.2)? 2.2. Wie linken mit den bestehenden Styles (so dass, die Umschaltung eines Styles auch die eigenen Komponenten betrifft)? Alles andere sind Gedanken die ich mir zu diesem Thema gemacht habe und sollte nur zeigen in welche Richtungen meine Überlegungen bisher gegangen sind. |
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Ich habe die VCL.Styles aufgegeben. Was nützt es, wenn die 3 Standard-Komponenten unterstützt werden, aber die 20 anderen Fremdkomponenten nicht. Ich hab keine Zeit mich darum auch noch zu kümmern. Das ganze Konzept des skinning taugt nicht in Delphi, weil es nicht adaptiv ist. Ausserdem sollte das immer die Aufgabe des nativen Betriebssystems sein.
|
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Zitat:
Zitat:
Zumindestens von Steema weis ich, dass mit dem nächsten Release Style Support kommen wird (habe aber keine Ahnung wann konkret <Kristallkugel> wohl spätestens irgendwann im Herbst </Kristallkugel> und wie das Ganze dann aussehen wird). Zitat:
Zitat:
|
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Von XE5 auf XE6 wurde die
![]() (Soll nur ein Hinweis sein, deine eigentlichen Fragen beantwortet das nicht) |
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Zitat:
|
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Zitat:
|
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mich in meiner eigenen Anwendung auf einen einzigen selbst erstellten Style konzentriert.
Jeden Style abdecken zu wollen ist eine Mammutaufgabe. Fraglich auch, ob das sinnvoll ist. Ich würde den Anwender die Wahl lassen zwischen den normalen Windows-Style und einen anderen. Dementsprechend muss man ggf. alles doppelt haben: Imagelisten, Image-Ressourcen usw. und zur Laufzeit beim Programmstart austauschen. Die Farben müssen dann entsprechend aus den Style extrahiert werden (GetSystemColor/GetStyleColor). Hier mal so ein Minimalbeispiel:
Delphi-Quellcode:
unit StylesTestFrm;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, System.Generics.Collections, Vcl.Themes, Vcl.ImgList; type TLineState = (Start, Move, Stop); TPainter = class strict private FIsLineStarted : Boolean; FCanvas : TCanvas; FImageIndex : Integer; FImageList : TImageList; FPoints : TList<TPoint>; public procedure Clear; function PaintLine(LineState : TLineState; X, Y : Integer) : Boolean; procedure Paint; constructor Create(ACanvas : TCanvas; AImageList : TImageList); destructor Destroy; override; property IsLineStarted : Boolean read FIsLineStarted write FIsLineStarted; end; TForm2 = class(TForm) PaintBox1 : TPaintBox; ilSystem : TImageList; ilStyle : TImageList; procedure FormCreate(Sender : TObject); procedure PaintBox1MouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer); procedure PaintBox1MouseMove(Sender : TObject; Shift : TShiftState; X, Y : Integer); procedure PaintBox1Paint(Sender : TObject); procedure PaintBox1MouseUp(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer); procedure FormDestroy(Sender: TObject); private FPainter : TPainter; public end; var Form2 : TForm2; implementation uses System.Math; {$R *.dfm} procedure TForm2.FormCreate(Sender : TObject); var LCurrentImageList : TImageList; begin LCurrentImageList := ilStyle; if StyleServices.IsSystemStyle then begin LCurrentImageList := ilSystem; end; FPainter := TPainter.Create(PaintBox1.Canvas, LCurrentImageList); end; procedure TForm2.FormDestroy(Sender: TObject); begin FPainter.Free; end; procedure TForm2.PaintBox1MouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer); begin case Button of TMouseButton.mbLeft : begin if FPainter.PaintLine(TLineState.Start, X, Y) then PaintBox1.Repaint; end; end; end; procedure TForm2.PaintBox1MouseMove(Sender : TObject; Shift : TShiftState; X, Y : Integer); begin if FPainter.PaintLine(TLineState.Move, X, Y) then PaintBox1.Repaint; end; procedure TForm2.PaintBox1MouseUp(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer); begin case Button of TMouseButton.mbLeft : begin if FPainter.PaintLine(TLineState.Stop, X, Y) then PaintBox1.Repaint; end; TMouseButton.mbRight : begin FPainter.Clear; PaintBox1.Repaint; end; end; end; procedure TForm2.PaintBox1Paint(Sender : TObject); begin if Assigned(FPainter) then begin FPainter.Paint; end; end; procedure TPainter.Clear; begin FCanvas.FillRect(FCanvas.ClipRect); FPoints.Clear; FImageIndex := 0; end; constructor TPainter.Create(ACanvas : TCanvas; AImageList : TImageList); begin FCanvas := ACanvas; FImageList := AImageList; FPoints := TList<TPoint>.Create; FCanvas.Pen.Width := 5; FCanvas.Pen.Color := StyleServices.GetSystemColor(clHighlight); FCanvas.Brush.Color := StyleServices.GetSystemColor(clBackground); end; destructor TPainter.Destroy; begin FPoints.Free; inherited; end; procedure TPainter.Paint; var LPoints : TArray<TPoint>; LLastPosition : TPoint; begin LPoints := FPoints.ToArray; FCanvas.Polyline(LPoints); if InRange(FImageIndex, 0, FImageList.Count - 1) then begin Inc(FImageIndex) end else begin FImageIndex := 0; end; if FPoints.Count > 0 then begin LLastPosition := FPoints.Last; FImageList.Draw(FCanvas, LLastPosition.X + 3, LLastPosition.Y + 3, FImageIndex); end; end; function TPainter.PaintLine(LineState : TLineState; X, Y : Integer) : Boolean; var LPosition : TPoint; begin LPosition := TPoint.Create(X, Y); case LineState of Start : begin FPoints.Add(LPosition); IsLineStarted := True; end; Move : begin if IsLineStarted then begin if LPosition <> FPoints.Last then begin FPoints.Add(LPosition); end; end; end; Stop : begin if IsLineStarted then begin FPoints.Clear; IsLineStarted := False; end; end; end; Result := IsLineStarted; end; end. |
AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Für eigene Applikationen mache ich das in geeignetem Rahmen auch so ähnlich und da kann man sich sicher auch auf ein paar wenige Styles beschränken.
Mir geht es aber eher um (m)eine Komponenten Library die ja dann für anderen Entwickler und deren Projekte verwendet werden und damit wird es schon schwieriger einen Style vorzuschreiben! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:34 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