Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi ColorToString auch für Systemfarben (https://www.delphipraxis.net/114764-colortostring-auch-fuer-systemfarben.html)

taaktaak 30. Mai 2008 22:00


ColorToString auch für Systemfarben
 
Moin, Moin.

Ich möchte den Farbwert eines Pixels auch mit dem Namen der "symbolischen Konstante" anzeigen. Die Delphi-Hilfe bietet hierzu ColorToString() und ColorToIdent() an. Ich zitiere:

Zitat:

Mit ColorToString können Sie einen String abrufen, der einem bestimmten TColor-Wert entspricht. Wenn für die Farbe eine symbolische Konstante definiert ist (z.B. clBlack oder clHighlightText)....
Die ersten Testläufe haben mir nun wieder ein paar graue Haare mehr beschert. Beide Funktionen liefern für die "Basisfarben" clBlack bis clWhite wie erwartet die symbolische Konstante zurück. Soll der String aber für eine Systemfarben ermittelt werden, scheitern beide Funktionen und liefern nur einen Hex-Wert zurück.

Also schaue ich mir in "Graphics" die betreffenden Funktionen bzw. Konstanten mal an: Beide Funktionen suchen den übergebenen Wert im const-Array "Colors" - und finden bei Systemfarben offenbar keine Übereinstimmung von übergebenen Farbwert und den im const-Array abgelegten Farbwerten. Die Farbwerte des Arrays sind in der gleichen Unit als Konstanten definiert. Dabei fällt mir auf, dass die "Basisfarben" anders definiert werden als die Systemfarben:

z.B. clBlack = TColor($000000) aber z.B. clBtnFace = TColor(clSystemColor or COLOR_BTNFACE)

Das bringt mich aber noch nicht weiter. Also ermittle ich vielleict erst einmal, welchen Wert ich für einen Pixel der Farbe clBtnFace an die Funktion übergebe und welcher Wert für clBtnFace im Array "Colors" enthalten ist:

TColor(clBtnFace) = 13160660 <- übergebener, zu suchender Wert)
StringToColor('clBtnFace') = -16777201 <- Value im Array "Colors"

Na klar, dann kan nix gefunden werden! Laut Hilfe soll aber bei ColorToString() ein TColor-Wert übergeben werden können und die Bezeichnung auc der Systemfarben ermittelt werden.

Ahhhh, schiete!
Ist die Aussage der Hilfe falsch?
Habe ich ein Brett vor dem Kopf?

Need help :wall:

FAlter 30. Mai 2008 22:08

Re: ColorToString nicht für Systemfarben???
 
Hi,

wie es sich anhört, nimmst du eine "echte" Farbe und willst sie übersetzen. Dabei gibt es folgendes Problem:

Die Systemfarben werden beim Zeichnen durch die "richtigen" Farben ersetzt. Es sind quasi Platzhalter, die je nachdem, welche Farbe du als User eingestellt hast, für eine bestimmte Farbe stehen. Nimmst du nun einen Farbwert aus einem Bild, entspricht dieser auch tatsächlich dem Farbwert und nicht mehr der Systemfarbe, die eventuell genauso aussieht und die es einmal war.

Falls ich deine Verfahrensweise also richtig verstanden habe: Es gibt keine Lösung für dein Problem. Du kannst ColorToString(clBtnFace) eingeben, und erhältst 'clBtnFace'. Malst du aber etwas mit clBtnFace in ein Bild und bestimmst die Farbe im Bild, so ist es irgendein Farbwert. Früher war dies meist gleich clSilver, heute ist es "in", andere Farben zu verwenden. Auf clBtnFace kommst du so leicht nicht mehr zurück.

Mfg
FAlter

himitsu 30. Mai 2008 22:18

Re: ColorToString nicht für Systemfarben???
 
man könnte alle cl...Farbkonstanten in RGB-Werte umwandeln lassen
und dann diese Farben mit der Farbe vergleichen.

nu gibt es obtmal verschiedene cl-Konstanten mit er selben Farbe,
was bedeutet daß nicht immer eine eindeutige Zuordnung möglich wäre.

taaktaak 30. Mai 2008 22:20

Re: ColorToString nicht für Systemfarben???
 
Hmmmmmmmmmmmmm, Grübel....

FAlter - Danke erst einmal für die Antwort....

Wenn ich mir das so überlege.... Windows müsste doch aber eigentlich wissen, welche "tatsächliche" Farbe verwendet wird, wenn ein Programm die Farbe "clBtnFace" verwendet. Man müsste also Windows fragen: Welchen Farbwert verwendest du tatsächlich für "clXXXX". Dann vergessen wir das Array in Graphics, und machen das "zu Fuss" es müssten dann natürlich immer alle symbolischen Konstanten abgefragt werden (?) das dürfte (so überhaupt möglich) nicht besonders schnell sein...

// edit:
@himitsu - wenn ich FAlter aber richtig verstanden habe, dann ist mit Konstanten doch gar nix anzufangen, da die Farben praktisch "dynamisch" sind... Ah, ich geh' jetzt erst mal eine rauchen, muss überlegen...

// edit2:
@himitsu - na, klar! mehrere symbolische Konstanten haben (bzw. können haben) identische Werte - egal wie: eine eindeutige Zuordnung wird nicht möglich sein - du hast Recht!!!

Muetze1 30. Mai 2008 22:29

Re: ColorToString nicht für Systemfarben???
 
1. Die Farbkonstanten welche Farben aus einem Farbschema wiederspiegeln (clBtnFace, etc), können als Konstante nicht mit richtigen Farbwerten definiert werden, da sie auf dem Zielsystem von Windows festgelegt werden, da der Nutzer die Farbschemas frei definieren kann. Somit sind es nur Platzhalter, welcher als Kennzeichnung das 31. Bit gesetzt hat. Dadurch sind diese Konstanten nach einem Typecast auf Integer immer negativ. Die VCL wandelt diese Konstanten u.a. in der Funktion ColorToRGB() um und fragt dann für die jeweilige Konstante Windows nach dem Farbwert.
2. Der Nutzer kann in Windows die einzelnen Farbkonstanten frei festlegen und somit kann der Nutzer auch z.B. rot für den Menühintergrund, einen Button und auch für den Fensterrand definieren. Somit ist es im Endeffekt einfach nur ein RGB Wert, der dahinter liegt. Und von diesem kann man nun nicht mehr eindeutig auf eine solche Farbkonstanten zurückkommen, da es eine 1:n Beziehung ist.
Auch wenn du einen RGB Wert hast, ist die Frage, ob er jemals eine Konstante war oder direkt so genutzt wurde und nicht über eine Konstante ermittelt wurde.

himitsu 30. Mai 2008 22:34

Re: ColorToString nicht für Systemfarben???
 
am Einfachsten du machst dir ein Array mit den clNamen
0 = 'clScrollBar'
1 = 'clBackground'
...

Delphi-Quellcode:
for i := 0 to 31{255} do
  if GetSysColor($ff000000 or i) = C then
    ... { S := MyColorConstArray[i]; }

for i := $ff000000 to $ff00001f{$ff0000ff} do
  if GetSysColor(i) = C then
    ...
(im Notfall ein temporäres Array mit den Farbwerten erstellen, falls man mehrere Farben abfragen und nicht ständig GetSysColor aufrufen will)



Rein theoretisch gibt es nur maximal 256 Systemfarben, wobei aktuell nur die unteren 5 Bit verwendet sind ... also 0 bis 31



Und wie Muetze1 und Co. schon sagten, ist diese Zuordnung dann nur zu diesem Zeitpunkt und auf dem einem System/Benutzer eindeutig.

taaktaak 30. Mai 2008 22:52

Re: ColorToString nicht für Systemfarben???
 
Vielen Dank an alle! :hi:

Habe das grundsätzlich verstanden. Vor diesem Hintergrund macht es dann eigentlich auch keinen besonders großen Sinn, den Namen in einem ColorPicker zu nennen. Nun wird mir auch klar, warum ich die "Farbnamen" noch nicht in einem derartigen Programm gesehen habe...

@himitsu: Ja, es würde sicher ausreichen die Farbzuordnungen beim Programmstart zu bestimmen. Wer während des Programmablaufs die Windows-Farben ändert ist dann selber schuld. Werde den Beispielcode aber erst einmal nicht verwenden, sondern archivieren.

Besser werde ich nun mal am Programm weitermachen, möchte es ja hier bald vorstellen!

taaktaak 30. Mai 2008 23:09

Re: ColorToString nicht für Systemfarben???
 
Ahhh, bevor ich jetzt endlich weitermache, doch noch eine dem Thema folgende Frage:

In Graphics hatte ich ja folgendes gefunden:

clBtnFace = TColor(clSystemColor or COLOR_BTNFACE)

Wenn ich den "Weg " jetzt noch weiter zurück verfolge, dann finde ich die Deklaration der Konstanten COLOR_BTNFACE. Dort steht dann

{$EXTERNALSYM COLOR_BTNFACE}
COLOR_BTNFACE = 15;

Leider spinnt meine Delphi7 Hilfe, wenn ich auf $EXTERNALSYM positioniere und F1 drücke. Was bedeutet das? So laienhaft betrachtet, klingt das nach: "Hole einen Wert von ausserhalb(also von Windows)" - würde das (so ich richtig geraten habe) aber nicht bedeuten, dass im Array "Colors" doch die aktuell in Windows gültigen Farbwerte stehen?

himitsu 30. Mai 2008 23:17

Re: ColorToString nicht für Systemfarben???
 
nee neee, die Konstante (im Beispiel 15) wird nicht verändert/umgewandelt.


Zitat:

Zitat von OH
The EXTERNALSYM directive prevents the specified Delphi symbol from appearing in header files generated for C++. If an overloaded routine is specified, all versions of the routine are excluded from the header file.


taaktaak 30. Mai 2008 23:43

Re: ColorToString nicht für Systemfarben???
 
hihihi,

...prevents...appearing...

falsch geraten :oops: Gute Nacht!


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 Uhr.
Seite 1 von 2  1 2      

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