Autor Beitrag
hRb
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mo 21.11.22 16:55 
Hallo zusammen,
Unter den Compilereinstellungen Projekt/Optionen/Erscheinungsbild kann man ein gegenüber Windows-Standard abweichende Farbdarstellung der grapfischen Oberfläche wählen, z.B. Windows-Dark. Ja nach Tageslicht hätte ich gern einmal eine normale dann eine dunkle Darstellung. Wirksam wird jedoch eine hellle/dunkle Darstellung erst nach dem Compilieren und ist fest im Programm verankert.
Frage: gibt eine einfache Möglichkeit zur Laufzeit die Farbdarstellung zu wechseln?
MfG hRb
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 21.11.22 23:07 
Meinst du vielleicht TStyleManager.TrySetStyle?
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mi 30.11.22 01:38 
Hallo jaenicke
Vielleicht ist es das. Konnte es aber nicht testen. Habe keine Erfahrung mit Class-Definitionen
Folgenden Code versuchte ich
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.Style1Click(Sender: TObject);
begin //normal hell
  TStyleManager.Setstyle('');
end;

procedure TForm1.Style2Click(Sender: TObject);
begin  //dunkel
  TStyleManager.Setstyle('Windows10 Dark');
end;

Dies brachte Laufzeitfehler, mit der Meldung "Stil 'Windows10 Dark' " bzw "Stil '' " nicht gefunden.
Wollte dann den aktuellen Stil ermitteln mit.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Style2Click(Sender: TObject);
var s :string;
begin
  s:= TStyleManager.Setstyle;
end;

Dies liefert beim Compilieren Fehler: E2010 Inkompatible Typen: 'string' und 'TCustomStyleServices', d.h. es fehlt die overload-Anweisung wie in der Hilfe beschrieben.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  public
    { Public-Deklarationen }
    class procedure SetStyle(const Name: string); overload;
  end;

Hier komme ich nicht weiter. Setstyle ist nicht bekannt An welcher Stelle im Programm muss eine dieser Anweisungen stehen?
ausblenden Delphi-Quelltext
1:
2:
3:
class procedure SetStyle(const Name: string); overload;
class procedure SetStyle(Style: TCustomStyleServices); overload;
class procedure SetStyle(Handle: TStyleServicesHandle); overload;

Weiß also nicht nicht wie man die in Delphi vorgegebenen Stile anspricht. Gibt es dafür Constanten?
siehe SetStyle
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 30.11.22 09:01 
Ich habe einfach mal die TStyleManager Eigenschaften in der Doku durchgeschaut:
- StyleNames
- Style[Name]
bzw. gezielt
- SystemStyleName

PS: Da SetStyle eine Prozedur ist, mußt du entweder nach einer passenden Eigenschaft oder der zugehörigen Get-Funktion suchen, in diesem Fall also GetStyle (nur ist diese hier [eigenartigerweise] protected, also bleibt nur der Zugriff über die public Eigenschaften).
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 30.11.22 09:20 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Dies brachte Laufzeitfehler, mit der Meldung "Stil 'Windows10 Dark' " bzw "Stil '' " nicht gefunden.
Hast du die entsprechenden Stile denn in den Projektoptionen angehakt? Sonst werden diese nicht mit einkompiliert.

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Folgenden Code versuchte ich
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Style1Click(Sender: TObject);
begin //normal hell
  TStyleManager.Setstyle('');
end;
Das wird nicht gehen. Leere Stilnamen gibt es nicht.

Tipp:
Den Namen für den Standardstil findest du unten in der Combobox: Windows ;-)
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mi 30.11.22 23:06 
Zitat:
Hast du die entsprechenden Stile denn in den Projektoptionen angehakt? Sonst werden diese nicht mit einkompiliert.

Ok, war mir nicht bewusst. Dachte mit der Einbindung der Unit VCL.Themes auch die Standard-Style dabei zu haben. Nach dem Hinweis die Styles "einzubinden" d,h, angekreuzt zu lassen, war auch klar dass ein Style-Typ ohne Name [''] nicht funktioniert: korrekt muss es 'Windows' lauten.
Folgendes Ergebnis erhalte nach Einbindung:
Bei Klick auf Style 2 (Dunkel) = 'Windows10 Dark' erscheint nachstehende Fehlermeldung (s. Anhang Image2)
Nach Fortsetzen erscheint noch eine Meldung über Zugriffsverletzung (s. Anhang Image3), aber die gewünschte Oberfläche erscheint.
Nach diesen beiden (ignorierten) Meldungen kann ich beliebig zwischen Style1 und Style2 hin- und herschalten OHNE WEITERE FEHLERMELDUNG!
Bleibt also nur noch die Frage, warum die Fehlermeldung.
Allerdings: nehme ich meine exe aus dem Ordner des Compilers heraus in einen fremden Ordner, gibt es keine Meldungen, d.h es könnte trotz dieser Meldungen alles ok sein.
Ein Problem mit verschiedenen Styles besteht noch (ist auch in den Hilfen erwähnt). Ich habe in meiner Anwendung ein Panel alButtom, in dem ich Anwenderfehlermeldungen anzeige. Dieses Panel färbe ich je nach Fehlergrad unterschiedlich ein. Dieses Umfärben funktioniert bei 'Windows10 Dark' nicht mehr. Weiterhin färben sich Icon-Symbole nicht mit um, d.h. schwarze Pixel werden nicht weiß. Also so easy wie es zunächst mit anderen Styles aussieht, ist es nicht.
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von hRb am Mi 30.11.22 23:18, insgesamt 1-mal bearbeitet
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mi 30.11.22 23:16 
Noch eine Ergänzung:
Laut Doku werden Styles in vsf-Dateien gespeichert. Habe schon geglaubt mit Loadfromfile arbeiten zu müssen. Dies ist mit dem Hinweis von jaenicke, die gewünschten Styles anzukreuzen, offenbar nicht notwendig (sofern man sich mit den Varianten unter Objekt/Optionen begnügt).
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 30.11.22 23:33 
Ich bekomme hier keine Fehler. Vielleicht hast du Komponenten, die mit den VCL-Styles nicht klarkommen?
Wenn du das Problem in einem Beispielprojekt reproduzieren kannst, das du hier anhängen kannst, schaue ich es mir gern an.

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Ein Problem mit verschiedenen Styles besteht noch (ist auch in den Hilfen erwähnt). Ich habe in meiner Anwendung ein Panel alButtom, in dem ich Anwenderfehlermeldungen anzeige. Dieses Panel färbe ich je nach Fehlergrad unterschiedlich ein.
Dafür ist ein Panel nicht geeignet. Versuche es mal mit TShape.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Di 06.12.22 18:28 
Hallo jaenicke,
1. das Angebot klingt gut. Inzwischen habe ich alle möglichen Farbdesign durchprobiert und nun tritt der Fehler auch bei mir nicht mehr auf (auch bei einem komplett neu erstellten Programmbeispiel). Also lassen wir es als Phänomen stehen. Vielleicht kommt es bei einem anderen Programm wieder mal vor.
2.
Zitat:
Vielleicht hast du Komponenten, die mit den VCL-Styles nicht klarkommen?

Ja, z.B. die Hintergrundfarbe eines Panel oder bei Richedit.
Zitat:
Dafür ist ein Panel nicht geeignet. Versuche es mal mit TShape.

(Warum zeichnen?, will doch nur Text ausgeben?)
Auf dem Panel liegt natürlich noch ein Label zur Textausgabe.
Bei Warnmeldungen z.B.: Panel = Rot und Labelcolor = weiß,
Bei Hinweismeldungen: Panel = Grün und Labelcolor = schwarz
Dies funktioniert bei Style Windows wie gewünscht, nicht aber bei anderen Styles.
Ich habe mal ein kleines Testprogramm beigefügt. Unter Style Windows ist alles ok aber schon bei Windows10 funktioniert es nicht wie programmiert. Da scheint so manches offen, bzw bei Style-Wechsel muss vieles nachgearbeitet werden.
Bei der Gelegenheit: Warum bekommt ein komplett neu erzeugtes Programm Dateinamen mit Nr 4 (project4.dproj)?
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 06.12.22 22:32 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
(Warum zeichnen?, will doch nur Text ausgeben?)
Auf dem Panel liegt natürlich noch ein Label zur Textausgabe.
Ein Panel hat mit Themes per Definition keine Hintergrundfarbe, ein TShape aber schon. Wenn du das TShape hinter das Label auf das Panel legst, kannst du Brush.Color setzen, um die Hintergrundfarbe zu setzen.

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Bei der Gelegenheit: Warum bekommt ein komplett neu erzeugtes Programm Dateinamen mit Nr 4 (project4.dproj)?
Dann liegen bereits 3 Projekte im Projekte-Ordner.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mo 12.12.22 23:47 
Ich habe mal versucht mit Tshape zu arbeiten (statt das Panel umzufärben). Die Hintergrund-Umfärbung funktioniert auch, aber auch TLabel scheint die Umstellung von 'Windows' auf 'Tablett Dark' nicht mitzumachen.
Folgender Code ändert im Dunkel-Mode die Textfarbe nicht auf black, d.h. wenn Col<>clRed ist, ist immer Font-Color immer white.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Procedure PutAlarm(Fehlertext: string; Col: TColor);
{ Programm- oder Bedien-Fehlermeldungen anzeigen }
var Rect : TRect;
begin
  with Form1 do
  begin
    if bell then exit; // keine zweite Meldung solange erste aktiv
    Shape1.Brush.Color := col;
    Shape1.Brush.Style := bsSolid; //bsDiagCross;
    if Col = clRed
      then LabelFehler.Font.Color := clWhite
      else LabelFehler.Font.Color := clblack;
    LabelFehler.Caption := Fehlertext;
    bell := true; // Anzeige aktiv, (immer nur die erste)
  end;
end;

Ein Versuch den Text nicht mit Label.Caption sondern mit Canvas.textout direkt auf das Shape zu schreiben zeigt keinen Text. Da mache ich wohl etwas falsch - aber was? (HG-Umfärben funktionier)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
Procedure PutAlarm(Fehlertext: string; Col: TColor);
{ Programm- oder Bedien-Fehlermeldungen anzeigen }
var Rect : TRect;
begin
  with Form1 do
  begin
    if bell then exit; // keine zweite Meldung solange erste aktiv
    Canvas.Pen.Width := 1;
    Canvas.Font.Size:=11;
    Shape1.Brush.Color := col;
    Shape1.Brush.Style := bsSolid; //bsDiagCross;
    if Col = clRed
      then Canvas.Pen.Color := clWhite
      else Canvas.Pen.Color := clBlack;  
// dieser Text erscheint nicht (ist zumindest nicht sichtbar)
    Canvas.textout(Panelfehler.Left + 2, Panelfehler.Top+2, Fehlertext);
    bell := true; // Anzeige aktiv, (immer nur die erste)
  end;
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 13.12.22 00:57 
Eine Ausgabe auf die Canvas Zeichenfläche musst du immer im OnPaint machen, sonst wird diese ggf. gleich wieder überschrieben.

Und zur Farbe:
Entferne einfach seFont aus der Property StyleElements des Labels, damit der Style die Farbwahl für das Label nicht übernimmt.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mi 14.12.22 01:03 
Hallo jaenicke
Zitat:
Entferne einfach seFont aus der Property StyleElements des Labels,

Ach, was kann programmieren so schön sein, wenn man alle Tricks kennt und so mühsam, wenn es anders ist.
Die "Panel-Shape-Label-Variante" funktioniert jetzt bestens. Danke !!!
Zitat:
Eine Ausgabe auf die Canvas Zeichenfläche musst du immer im OnPaint machen

Diese Info lese ich zwar, ist mir in der Umsetzung unklar bzw. "zu hoch". Weder Panel, noch Shape, noch Label besitzen ein OnPaint-Ereignis. Wüsste also nicht, unter welchem Objekt (OnPaint) der Text ausgegeben werden soll. Unter Form1?
Aber eine Lösung genügt mir. Wichtiger:

Ich traue mich kaum noch eine letzte Frage zum Thema nachzuschieben. Die Wirkung der StyleElements habe ich ausgiebig getestet. Dennoch verbleibt noch ein Problem mit einem Listview-Objekt. Füge einfach zwei Bilder bei. Die zeigen besser als 1000 Worte wo es noch klemmt. Ein markiertes Imagebild zeigt normal einen Farbrahmen, um das Icon schnell zu erkennen. Das funktioniert bei dunkler Darstellung nicht.
Frage: Gibt es neben den StyleElements-Parametern noch weitere Parameter um den Rahmen hervorzuheben? Oder muss man unter das Listview auch noch ein anderes Objekt legen (ein TShape)? Geht wohl nicht, denn dann bräuchte man für jedes Icon eine eigene "Unterlage".
Image1Image2
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 14.12.22 12:16 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Ach, was kann programmieren so schön sein, wenn man alle Tricks kennt und so mühsam, wenn es anders ist.
Ich hatte keine Ahnung wie die Styles funktionieren und kannte auch die Property nicht. Ich habe aber im Debugger nachgeschaut, wo die Schriftfarbe des Labels beim Zeichnen verwendet wird und habe dann diese Codestelle gefunden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TStyleHook.DrawControlText(Canvas: TCanvas; Details: TThemedElementDetails;
  const S: stringvar R: TRect; Flags: Cardinal);
[...]
begin
[...]
  if LStyle.GetElementColor(Details, ecTextColor, ThemeTextColor) then
  begin
    if not Control.Enabled or (seFont in Control.StyleElementsthen
      Canvas.Font.Color := ThemeTextColor;
    LStyle.DrawText(Canvas.Handle, Details, S, R, TextFormat, Canvas.Font.Color);
[...]

Dort habe ich dann gesehen, dass die Theme-Farbe nur verwendet wird, wenn seFont gesetzt ist.

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Wüsste also nicht, unter welchem Objekt (OnPaint) der Text ausgegeben werden soll.
Wenn ein Control kein OnPaint hat, kann man die procedure Paint in einer abgeleiteten Klasse überschreiben. Alternativ kann man eine TPaintBox und deren OnPaint nehmen.

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Frage: Gibt es neben den StyleElements-Parametern noch weitere Parameter um den Rahmen hervorzuheben? Oder muss man unter das Listview auch noch ein anderes Objekt legen (ein TShape)? Geht wohl nicht, denn dann bräuchte man für jedes Icon eine eigene "Unterlage".
Ich weiß nicht, ob man das anders erledigen kann, als es selbst zu zeichnen. Mir geht es gerade nicht gut, deshalb kann ich auch gerade nicht nachschauen.
Eine Markierung sollte aber schon zu sehen sein, nur nicht der Rahmen außen um das Bild herum.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Do 15.12.22 22:43 
Kann leider nur in Etappen antworten.
Zitat:
Eine Markierung sollte aber schon zu sehen sein, nur nicht der Rahmen außen um das Bild herum.

Nein, im dunklen Style nicht, den farblichen Rahmen sieht man nur im hellen Style Der farbliche Rahmen ist Hinweis, dass dieses Item den Fokus hat. Ansteuern lässt sich dies mit dem Befehl
ausblenden Delphi-Quelltext
1:
ListView1.ItemIndex := i; // setzt Fokus auf Item i - wenn i=0, dann erstes Item					

Im dunklen Style wird das Item nur "milchig", wenn man mit der Maus darauf klickt. Beim hellen Style erscheint dauerhaft der Rahmen.
Nachdem ich alle Parameter des StyleElements getestet habe, will ich das Thema jetzt abschließen - viel ohnehin in den Bereich "nice to have". Habe dennoch viel gelernt.
Danke für alle bisherige Unterstützung.
jaenicke wünsche ich gute Besserung.
Für diejenigen, die ähnliche Aufgaben bearbeiten füge ich die zip-Datei bei (mit Code).
Das Programm leistet: Laden von Dateien (bevorzugt Bilder), einfaches optisches Sortieren, ggf. Umbenennen, Speichern der Bild-Liste, Vollbilddarstellung in Sinne einer Diashow.
PS: um das Programm voll funktionsfähig zu bekommen sind im Listview1.StyleElements alle Elemente zu entfernen.
PS2: wer noch weiter am Thema arbeiten will, siehe nachstehend. Habe ich soeben noch gefunden:
Überblick über VCL-Stile
TStyleManager.LoadFromFile

Moderiert von user profile iconTh69: URL-Titel hinzugefügt.
Einloggen, um Attachments anzusehen!