AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Korrekter Umgang mit Delphi Styles und eigenen Komponenten
Thema durchsuchen
Ansicht
Themen-Optionen

Korrekter Umgang mit Delphi Styles und eigenen Komponenten

Ein Thema von Whookie · begonnen am 7. Aug 2014 · letzter Beitrag vom 18. Aug 2014
Antwort Antwort
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten

  Alt 11. Aug 2014, 10:38
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.
Angehängte Dateien
Dateityp: zip StylesTest.zip (160,3 KB, 24x aufgerufen)

Geändert von TiGü (11. Aug 2014 um 10:44 Uhr)
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
446 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten

  Alt 11. Aug 2014, 10:59
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!
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten

  Alt 11. Aug 2014, 16:15
Aha, eine wichtige Info!

Ich denke mal, du zeichnest irgendwas (Charts, Diagramme) und bist darauf angewiesen, dass bestimmte Farb- und Helligkeitsunterschiede vorhanden sind.

Auf einen Panel, was früher Windows grau war und nun durch Styling dunkelgrün, kann man wahrscheinlich schlecht hellgrüne Linien einzeichnen.

Vielleicht suchst du einfach nur nach einer Lösung, um eine bestehende Farbe zu analysieren (Einzelne RGB-Komponenten, Helligkeit, Sättigung)?!?
So a la: "Hier ist eine dunkle bzw. helle Hintergrundfarbe, bitte gib mir ein passenden Canvas.Pen.Color".
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
446 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten

  Alt 11. Aug 2014, 21:10
Posting #1 und #3 fassen das eigentl. recht gut zusammen und für einfache Sachen kann man sich ja Farben vom Style "ausborgen" aber mir geht es hauptsächlich darum wie man zusatzinfos zu bestehenden Styles definieren könnte und diese dann mit den bestehenden "verlinkt" damit für den Endanwender alles wie aus einem Guss aus sieht.

Farben zu analysieren ist kein Thema aber das schöne an einem Style ist ja gerade, dass alle Farben aufeinander abgestimmt sind (hoffentlich ) und dann nur noch verwendet werden müssen.

Als konkretes Beispiel könnte man sich eine kleine Komponete vorstellen die einen Graphen - im Sekundentakt - nach rechts oder links scrollt (siehe angehängtes Bild, schnell mit Gimp erstellt - nichts reales).
Da gibts jetzt einen Rand, ein paar Linien ein Hintergrundraster, eine Cursorline und eventuell ein Image das als Indikator je nach zugrundeliegendem Signal anders aussehen könnte.

Für so eine Komponente wären nun also 5-6 Farben für alle Elemente nötig plus - zb. 3 Images (niedrig,mittel, hoch). Das Ganze nun für jeden der (unter XE5) vorhandenen 27 Styles....
Angehängte Grafiken
Dateityp: png democompo.png (4,5 KB, 36x aufgerufen)
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten

  Alt 12. Aug 2014, 08:38
Man könnte sich jetzt den Aufwand machen und anhand der Style-Farben sich irgendwas passendes für den Graphen extrahieren.

Aber ich denke, dass ist der falsche Weg!

Derartige Eigenschaften gehören published, damit der Anwender selber entscheiden kann, welche Farben er einsetzt.

Bedenke, dass es neben den mitgelieferten Styles noch selbst erstellte Styles gibt.
Für unsere Anwendung bspw. habe ich mir vom Style 'Carbon' eine Kopie erstellt und die weiter verfeinert (clHighlight ist z.B. orange anstatt Pastellfarbenblau).
Von daher ist es unmöglich sich irgendeine Form von Mapping-Tabelle zu erstellen.
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
446 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten

  Alt 12. Aug 2014, 14:39
Aber ich denke, dass ist der falsche Weg!
Darum, um mich mal selbst zu zitieren:
...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...
... Theoretisch könnte ich dann für jeden Delphi Style eine eigene .vsf haben und diese müsste mit ausgeliefert werden ... und dann müsste es auch noch eine Methode geben, die meine Zusätze mit denen der dazugehörenden Styles verbindet...
Dann kann man in diesen Dateien selbst auch noch was ändern...


Derartige Eigenschaften gehören published, damit der Anwender selber entscheiden kann, welche Farben er einsetzt.
Eben nicht! Wenn das ein gestyltes Control ist müsste erst wieder der Anwender für alle Style selbst eine Tabelle mit passenden Farben und Images vorrätig halten, damit beim Umschalten die Farben passen!

Für unsere Anwendung bspw. habe ich mir vom Style 'Carbon' eine Kopie erstellt und die weiter verfeinert...
Das ist wohl eine Sackgasse, der bestehende Style sollte niemals(!!) geändert werden. Damit fixierst du dein Projekt an eine bestimmte Delphiversion oder bist ständig am nachbessern (was ja vielleicht noch vertretbar ist bei einem Style). Wenn du sowas für 27 Styles machst ist das nicht mehr vernünftig vertretbar.
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Korrekter Umgang mit Delphi Styles und eigenen Komponenten

  Alt 12. Aug 2014, 16:47
Für unsere Anwendung bspw. habe ich mir vom Style 'Carbon' eine Kopie erstellt und die weiter verfeinert...
Das ist wohl eine Sackgasse, der bestehende Style sollte niemals(!!) geändert werden. Damit fixierst du dein Projekt an eine bestimmte Delphiversion oder bist ständig am nachbessern (was ja vielleicht noch vertretbar ist bei einem Style). Wenn du sowas für 27 Styles machst ist das nicht mehr vernünftig vertretbar.
Warum sollten bestehende Styles nicht Ausgangspunkt für eigene sein?

Ich habe nicht die 'Carbon.vsf' an sich bearbeitet!
Sondern kopiert und umbenannt a la 'MyStyle.vsf' und dort dann fröhlich geändert.

Die VSF-Datei wird vom Installer neben die EXE gelegt und dann dynamisch beim Programmstart geladen.
Sehe nicht, dass ich mich damit auf irgendeine spezielle Delphi-Version festlege??
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:57 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