Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TStylemanager verwenden (https://www.delphipraxis.net/192943-tstylemanager-verwenden.html)

Delbor 4. Jun 2017 14:14

Delphi-Version: XE8

TStylemanager verwenden
 
Hi zusammen

Wennich schon beim austesten bin, dann kann ich auch mal die Sachenn um TStylemanager ausprobieren - dachte ich mir und hab dann zur Designtime ein Style eingebunden. Damit sieht dann meine Projektunit so aus:
Delphi-Quellcode:
program SQLiteTestProject;

uses
  Vcl.Forms,
  SQLiteTestMainUnit in 'SQLiteTestMainUnit.pas' {SQLiteTestMain},
  DMLSQLiteUnit in 'DMLSQLiteUnit.pas' {DMLSQLite: TDataModule},
  PathFinderFrameUnit in 'PathFinderFrameUnit.pas' {PathFinderFrame: TFrame},
  Vcl.Themes,
  Vcl.Styles,
  ModifyBitClass in 'ModifyBitClass.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  TStyleManager.TrySetStyle('Golden Graphite');
  Application.CreateForm(TSQLiteTestMain, SQLiteTestMain);
  Application.Run;
end.
Und da vermeinte ich doch den Fehler gleich zu sehen: unter uses sind Vcl.Themes und Vcl.Styles aufgeführt. Ich hingegen hatte in meiner Unit nur gerade eine der beiden eingebunden...(**)

So verpasste ich der Mainform eine Combobox, über die einer der verfügbaren Styles ausgewählt werden kann/soll:
Delphi-Quellcode:
interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
...
  Vcl.Buttons, Vcl.Samples.Spin, Vcl.Menus, Vcl.Themes, Vcl.Styles;

//** Wie ich schon angedeutet habe, war hier erstmal nur VCL.Themes aufgeführt; das Hinzufügen von VCL.Styles hat jedoch nichts geändert


procedure TSQLiteTestMain.CmbxStylesCloseUp(Sender: TObject);
begin
  CmbxStyles.Items.AddStrings(TStylesManager);
end;
Bei ersten Tests ist mal alles themenbezogene hier in dieser Prozedur. Ausgelagert kann, soweit sinnvoll, immer noch werden (ZB die Combo bei Programmstart füllen).
Das Problem ist: TStyleManager ist hier unbekannt, auch wenn ich unter Uses beide Units aufführe.
TStyleManager ist als 'sealed' deklariert (Embarcadero.DelhiXE8), es kann also keine Instanz erstellt werden.
Beispielcodes zur Verwendung von TStyleManager habe ich keinen gefunden.

Was läuft da schief?

Gruss
Delbor

Aviator 4. Jun 2017 14:22

AW: TStylemanager verwenden
 
Ich kann dir zu deinem eigentlichen Problem keine HIlfe geben. Aber
Delphi-Quellcode:
sealed;
heißt doch nur, dass eine Ableitung der Klasse erstellt werden kann. Instanziieren kann man die trotzdem.:gruebel:

Delbor 4. Jun 2017 14:54

AW: TStylemanager verwenden
 
Hi Aviator
Danke fuer deine Antwort! Eigentlich wollte ich nochmal nach sealed suchen, bin dann aber über das gestolpert.
Da wird auch die Klasse direkt verwendet, ohne eine Instanz zu erstellen.
Und dann hat sich das ganze, zumindest bis jetzt, in Luft aufgelöst:
Ich hatte TStylesManager verwendet. Auf er verlinkten Seite wird aber TStyleManager benutzt.
So kanns also mal weitergehen...

Gruss
Delbor

Delbor 4. Jun 2017 15:25

AW: TStylemanager verwenden
 
Hi zusammen
Nun hab ich nochmal nach 'sealed' gesucht und gefunden hab ich das hier und dieses.
Damit dürfte klar sein: es dürfen keine Instanzen erstellt werden.

Gruss
Delbor

Aviator 4. Jun 2017 15:30

AW: TStylemanager verwenden
 
Zitat:

Zitat von Delbor (Beitrag 1373433)
Damit dürfte klar sein: es dürfen keine Instanzen erstellt werden.

Öhhhmm ... :gruebel:

lies mal die Anmerkung durch (Hervorhebung von mir):
Zitat:

Zitat von Docwiki
Anmerkung: TKeyCaptions ist "sealed" und kann daher nicht weiter abgeleitet werden.

Oder auch siehe hier: https://www.delphi-treff.de/object-pascal/vererbung

Abschnitt "Versiegelte Klassen".

Heißt also: Instanziieren funktioniert immer. Im Zweifelsfall versuch es doch einfach mal. Mir ist eigentlich kein Fall bekannt, in dem man eine Klasse nicht instanziieren kann. Es sei denn die besitzt nur Class Methods bei denen es keinen Sinn macht. Auch ein Singleton instanziiert man einmal und nimmt sich danach nur noch die bestehende Instanz.

Delbor 4. Jun 2017 16:24

AW: TStylemanager verwenden
 
Hi Aviator

Kann sein, dass ich falsch liege, aber auch eine Instanz ist für mich genaugenommen abgeleitet. Zumindest ist mir hier in der DP kein Thread aufgefallen, der eine Instanz von TStyleManager verwendet hätte.

Am Beispiel eines Panels: Benenne ich es zB. in 'MainPanel' um, steht im Header des OI 'Mainpanel:TMainpanel'

Gruss
Delbor

Uwe Raabe 5. Jun 2017 14:56

AW: TStylemanager verwenden
 
Zitat:

Zitat von Delbor (Beitrag 1373427)
Das Problem ist: TStyleManager ist hier unbekannt, auch wenn ich unter Uses beide Units aufführe.

In deinem Sourcecode verwendest du allerdings auch
Delphi-Quellcode:
TStylesManager
und nicht
Delphi-Quellcode:
TStyleManager
.

Zitat:

Zitat von Delbor (Beitrag 1373427)
Beispielcodes zur Verwendung von TStyleManager habe ich keinen gefunden.

OK, hier ein bisschen Code für den Anfang. Erstellen eines Sub-Menüs mit allen verfügbaren Styles plus Event zum Wechseln des Style:

Delphi-Quellcode:
  ...
    mnuStyle: TMenuItem;
  private
    FActiveStyle: string;
    procedure SetActiveStyle(const Value: string);
    procedure mnuStyleItemClick(Sender: TObject);
    procedure LoadStyleMenu;
    procedure AddStyleMenuItem(S: string);
  public
    property ActiveStyle: string read FActiveStyle write SetActiveStyle;
  ...

procedure TMainForm.LoadStyleMenu;
var
  arr: TArray<string>;
  S: string;
  systemStyleName: string;
begin
  mnuStyle.Clear;
  arr := TStyleManager.StyleNames;
  TArray.Sort<string>(arr); // alphabetisch sortieren
  systemStyleName := TStyleManager.SystemStyle.Name;
  AddStyleMenuItem(systemStyleName); // Windows immer zuerst
  for S in arr do begin
    if S <> systemStyleName then begin
      AddStyleMenuItem(S);
    end;
  end;
end;

procedure TMainForm.AddStyleMenuItem(const AStyleName: string);
var
  itm: TMenuItem;
begin
  itm := TMenuItem.Create(Self);
  itm.Caption := AStyleName;
  itm.RadioItem := true;
  itm.AutoCheck := true;
  itm.Checked := (AStyleName = TStyleManager.ActiveStyle.Name);
  itm.OnClick := mnuStyleItemClick;
  mnuStyle.Add(itm);
end;

procedure TMainForm.mnuStyleItemClick(Sender: TObject);
begin
  ActiveStyle := (Sender as TMenuItem).Caption;
end;

procedure TMainForm.SetActiveStyle(const Value: string);
begin
  if FActiveStyle <> Value then begin
    FActiveStyle := Value;
    if FActiveStyle = '' then begin
      TStyleManager.SetStyle(nil);
    end
    else begin
      TStyleManager.TrySetStyle(FActiveStyle);
    end;
  end;
end;

Zacherl 5. Jun 2017 15:02

AW: TStylemanager verwenden
 
Zitat:

Zitat von Delbor (Beitrag 1373435)
Kann sein, dass ich falsch liege, aber auch eine Instanz ist für mich genaugenommen abgeleitet.

Ne, da liegst du in der Tat falsch. Die Terminologie "ableiten" ist wirklich nur auf Klassen anzuwenden. Von Klassen mit dem
Delphi-Quellcode:
sealed
Attribut kannst du auf jeden Fall auch Instanzen erzeugen. Das bezieht sich wirklich nur darauf, dass eine versiegelte Klasse nicht die Oberklasse einer weiteren Klasse sein kann.

Zitat:

Zitat von Delbor (Beitrag 1373435)
Am Beispiel eines Panels: Benenne ich es zB. in 'MainPanel' um, steht im Header des OI 'Mainpanel:TMainpanel'

Du meinst vermutlich "Mainpanel: TPanel"? Das soll aber auch keine Ableitungsrelation aufzeigen, sondern einfach nur, dass die Instanz mit dem Namen "Mainpanel" vom Typ "TPanel" ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz