original Window Farben auslesen
Re: original Window Farben auslesen
Sicherlich muss dass alles irgendwie mit den ermittelten Farben "verrechnet" werden, um den wirklichen Farbwert zu bekommen. Nur wie ?! Im Netz und mit anderen Programmiersprachen ist man da auch nicht wirklich zu einer Lösung gekommen. Das ist halt mal wieder eines der zahlreichen Rätsel von Microsoft... Die Dokumentation zur dwmapi.dll wird jedenfalls allgemein bemängelt.
Re: original Window Farben auslesen
Wenn man sich den Fensterrahmen z.B. bei Win7 ansieht, wird dieser durch dahinterliegende
Fenster beinflußt. Schiebt man ein kleineres Fenster über den Desktop mit weiteren geöff-
neten Fenstern hin und her, sieht man doch, daß der Rahmen und damit die Rahmenfarbe sich
durch die darunterliegenden Fenster ändert und damit an jedem Punkt des Rahmens anders
aussehen kann.
Damit erscheint eine 'Berechnung' der Rahmenfarbe zumindest für Win7 nicht möglich.
Mir steht allerdings nur Win7 zur Verfügung, so daß es für höhere Win-Version anders aussehen
kann.
Fenster beinflußt. Schiebt man ein kleineres Fenster über den Desktop mit weiteren geöff-
neten Fenstern hin und her, sieht man doch, daß der Rahmen und damit die Rahmenfarbe sich
durch die darunterliegenden Fenster ändert und damit an jedem Punkt des Rahmens anders
aussehen kann.
Damit erscheint eine 'Berechnung' der Rahmenfarbe zumindest für Win7 nicht möglich.
Mir steht allerdings nur Win7 zur Verfügung, so daß es für höhere Win-Version anders aussehen
kann.
Re: original Window Farben auslesen
Das ist richtig. Bei Win 7 sind die Bedingungen ganz anders. Schließlich war das der Anfang mit diesen "Glas-Effekten", also den "Durchsichtigbarkeiten" der Fenster. In Win 8 und 10 ist das etwas anders geregelt worden, man hat dort nur wieder einen einfarbigen Fenstertitel und Rahmen, der allerdings teilweise wie bei Win 7 durchsichtig werden kann. Mit gewissen Tricks kann man bei den späteren Versionen von Windows aber die Win7 Effekte wieder realisieren - machen aber wohl nicht so viele. Also bleibt es bei einfarbiger Titelzeile und Rahmen, von dem ich immer noch gerne ohne Tricks die Werte auslesen möchte.
Re: original Window Farben auslesen
Evtl. hilft die Funktion:
Code: Alles auswählen
DWMAPI DwmGetColorizationColor(
DWORD *pcrColorization,
BOOL *pfOpaqueBlend
);
Re: original Window Farben auslesen
Genau hier viewtopic.php?p=360558#p360558 also 1 Seite vorher, wurde diese Funktion verwendet. Bringt aber nichts, weil die Farben nicht ganz stimmen. (Zu hell oder zu dunkel.)
Ich möchte daher bitten, mal diesen Code auszuführen und die Ergebnisse hier mitzuteilen.
Und zwar möglichst unter Win 8 (8.1) und Win 10 - denn da gibt es auch noch Unterschiede zwischen den Farben.
Sollte es jemand gelingen, damit die richtigen Farben auszulesen
Ich möchte daher bitten, mal diesen Code auszuführen und die Ergebnisse hier mitzuteilen.
Und zwar möglichst unter Win 8 (8.1) und Win 10 - denn da gibt es auch noch Unterschiede zwischen den Farben.
Sollte es jemand gelingen, damit die richtigen Farben auszulesen
Re: original Window Farben auslesen
Ok hier ein Beispiel
Code: Alles auswählen
EnableExplicit
Procedure.i GetColorization(*ColorRGB.Integer,*Alpha.Ascii = #Null,*Opaque.Integer = #Null);Minimum supported client: Windows Vista
Static hlib.i
Protected *ascii
Protected *proc
Protected opaque.i
Protected color.RGBQUAD
If Not hlib
hlib = LoadLibrary_("Dwmapi.dll")
EndIf
*ascii = Ascii("DwmGetColorizationColor")
If *ascii
*proc = GetProcAddress_(hlib,*ascii)
FreeMemory(*ascii)
If *proc
If CallFunctionFast(*proc,@color,@opaque) = #S_OK
Swap color\rgbRed,color\rgbBlue
If *Alpha
*Alpha\a = color\rgbReserved
EndIf
If *Opaque
*Opaque\i = opaque
EndIf
color\rgbReserved = #Null
CopyMemory(@color,*ColorRGB,4)
ProcedureReturn #True
EndIf
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure.i Main()
Protected color.i
If OpenWindow(0,0,0,320,320,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
GetColorization(@color)
If StartDrawing(WindowOutput(0))
Box(0,0,WindowWidth(0),WindowHeight(0),color)
StopDrawing()
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
CloseWindow(0)
EndIf
ProcedureReturn #Null
EndProcedure
Main()
End
Re: original Window Farben auslesen
Sieht gut aus, allerdings sind da wieder die Farbunterschiede. Bei mir: Titelleiste: R=181 G=164 B=148 Innen: R=166 G=148 B=131
Also etwas dunkler innen als die Titelleiste. Bei dir sind die Farben tatsächlich gleich ?!
Also etwas dunkler innen als die Titelleiste. Bei dir sind die Farben tatsächlich gleich ?!
Re: original Window Farben auslesen
Probier mal...
Code: Alles auswählen
Procedure RegReadDWord(section, path$, key$)
value=-1 : datasize.l=4 ; 4 bytes = 32 bits (long).
If RegOpenKeyEx_(section, path$, 0, #KEY_READ, @tmp) = #ERROR_SUCCESS
If RegQueryValueEx_(tmp, key$, 0, 0, @value, @datasize) <> #ERROR_SUCCESS : value=-1 : EndIf
RegCloseKey_(tmp)
EndIf
ProcedureReturn value
EndProcedure
Global active = RegReadDWord(#HKEY_CURRENT_USER, "Software\Microsoft\Windows\DWM", "AccentColor") & $FFFFFFFF
Global inactive = RegReadDWord(#HKEY_CURRENT_USER, "Software\Microsoft\Windows\DWM", "AccentColorInactive") & $FFFFFFFF
Procedure Callback(hWnd, msg, wParam, lParam)
If msg = #WM_NCACTIVATE
If wParam & $FFFF
SetWindowColor(0, RGB(Red(active), Green(active), Blue(active)))
Else
SetWindowColor(0, RGB(Red(inactive), Green(inactive), Blue(inactive)))
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0, 0, 0, 800, 500, "", #WS_OVERLAPPEDWINDOW|#PB_Window_ScreenCentered)
SetWindowColor(0, RGB(Red(active), Green(active), Blue(active)))
SetWindowCallback(@Callback())
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Re: original Window Farben auslesen
Ich glaube die Farbe muss noch mit der ColorBalance und dem Standard Grauwert vermischt werden.
Re: original Window Farben auslesen
Korrigierter Farbwert
Es wird wie schon vermutet die Farbintensität benötigt.
Diese kann auch über die Registry ausgelesen werden (der vernünftige, offizielle Weg).
Ich werde in meinem Beispiel jedoch die undokumentierte API DwmGetColorizationParameters() verwenden.
Um an die Adresse der Funktion zu kommen scanne ich in der Funktion DwmGetColorizationColor() nach dem Call
zu DwmGetColorizationParameters() und extrahiere die Addresse.
Wenn die Addresse gefunden wurde wird die Funktion aufgerufen welche die Struktur DwmColorizationParams füllt.
Anhand der Farbe ColorizationColor und der Intensität ColorizationColorBalance kann nun die korrekte Farbe berechnet werden.
Hier der Code:
Es wird wie schon vermutet die Farbintensität benötigt.
Diese kann auch über die Registry ausgelesen werden (der vernünftige, offizielle Weg).
Ich werde in meinem Beispiel jedoch die undokumentierte API DwmGetColorizationParameters() verwenden.
Um an die Adresse der Funktion zu kommen scanne ich in der Funktion DwmGetColorizationColor() nach dem Call
zu DwmGetColorizationParameters() und extrahiere die Addresse.
Wenn die Addresse gefunden wurde wird die Funktion aufgerufen welche die Struktur DwmColorizationParams füllt.
Anhand der Farbe ColorizationColor und der Intensität ColorizationColorBalance kann nun die korrekte Farbe berechnet werden.
Hier der Code:
Code: Alles auswählen
EnableExplicit
Procedure.i GetColorizationColor(*Color)
Structure DwmColorizationParams
ColorizationColor.l
ColorizationAfterglow.l
ColorizationColorBalance.l
ColorizationAfterglowBalance.l
ColorizationBlurBalance.l
ColorizationGlassReflectionIntensity.l
ColorizationOpaqueBlend.l
EndStructure
Static hlib.i
Protected *ascii
Protected *proc.Long
Protected *dummy
Protected count.i
Protected param.DwmColorizationParams
Protected color.i
Protected color_r.d
Protected color_g.d
Protected color_b.d
If Not hlib
hlib = LoadLibrary_("Dwmapi.dll")
EndIf
*ascii = Ascii("DwmGetColorizationColor")
If *ascii
*proc = GetProcAddress_(hlib,*ascii)
FreeMemory(*ascii)
If *proc
Repeat
If *proc\l = $244C8D48
*proc + 6
*dummy = *proc - hlib + *proc\l + 5
*dummy + hlib
Break
EndIf
If count = 160
Break
EndIf
*proc + 1
count + 1
ForEver
If *dummy
If CallFunctionFast(*dummy,@param) = #S_OK
count = 100 - param\ColorizationColorBalance
color = (param\ColorizationColor >> 16) & $FF
color_r = Round(color + (127 - color) * count / 100.0,#PB_Round_Nearest)
color = (param\ColorizationColor>> 8) & $FF
color_g = Round(color + (127 - color) * count / 100.0,#PB_Round_Nearest)
color = param\ColorizationColor & $FF
color_b = Round(color + (127 - color) * count / 100.0,#PB_Round_Nearest)
If color_r > 255.0
color_r = 255.0
EndIf
If color_g > 255.0
color_g = 255.0
EndIf
If color_b > 255.0
color_b = 255.0
EndIf
color = RGB(color_r,color_g,color_b)
CopyMemory(@color,*Color,4)
ProcedureReturn #True
EndIf
EndIf
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure.i Main()
Protected color.i
If OpenWindow(0,0,0,320,320,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Tool)
GetColorizationColor(@color)
SetWindowColor(0,color)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
CloseWindow(0)
EndIf
ProcedureReturn #Null
EndProcedure
Main()
End