Autor |
Beitrag |
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 21.11.22 23:07
|
|
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Style1Click(Sender: TObject); begin TStyleManager.Setstyle(''); end;
procedure TForm1.Style2Click(Sender: TObject); begin 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.
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.
Delphi-Quelltext 1: 2: 3: 4:
| public 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?
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
Beiträge: 4785
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: 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
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 30.11.22 09:20
|
|
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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.
hRb hat folgendes geschrieben : | 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
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 06.12.22 22:32
|
|
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| Procedure PutAlarm(Fehlertext: string; Col: TColor);
var Rect : TRect; begin with Form1 do begin if bell then exit; Shape1.Brush.Color := col; Shape1.Brush.Style := bsSolid; if Col = clRed then LabelFehler.Font.Color := clWhite else LabelFehler.Font.Color := clblack; LabelFehler.Caption := Fehlertext; bell := true; 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)
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);
var Rect : TRect; begin with Form1 do begin if bell then exit; Canvas.Pen.Width := 1; Canvas.Font.Size:=11; Shape1.Brush.Color := col; Shape1.Brush.Style := bsSolid; if Col = clRed then Canvas.Pen.Color := clWhite else Canvas.Pen.Color := clBlack; Canvas.textout(Panelfehler.Left + 2, Panelfehler.Top+2, Fehlertext); bell := true; end; end; |
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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".
Einloggen, um Attachments anzusehen!
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 14.12.22 12:16
hRb hat folgendes geschrieben : | 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TStyleHook.DrawControlText(Canvas: TCanvas; Details: TThemedElementDetails; const S: string; var R: TRect; Flags: Cardinal); [...] begin [...] if LStyle.GetElementColor(Details, ecTextColor, ThemeTextColor) then begin if not Control.Enabled or (seFont in Control.StyleElements) then 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.
hRb hat folgendes geschrieben : | 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.
hRb hat folgendes geschrieben : | 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
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: 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
Delphi-Quelltext 1:
| ListView1.ItemIndex := i; |
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 Th69: URL-Titel hinzugefügt.
Einloggen, um Attachments anzusehen!
|
|
|