Hintergrundfarbe des Fensters/Gadges ermitteln

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
jogo
Beiträge: 123
Registriert: 22.11.2020 20:05
Computerausstattung: 'ne Handvoll gebrauchte Laptops & PCs mit Mint und LMDE

Hintergrundfarbe des Fensters/Gadges ermitteln

Beitrag von jogo »

Moin,
ich habe es bisher nicht geschafft, mit GetGadgetColor() die Hintergrundfarbe eines Fensters oder Gadges zu ermitteln, wenn ich sie zuvor NICHT mit SetGadgetColor() gesetzt habe. Die Hintergrundfarbe wird also abhänging vom eingestellten Theme gesetzt.

Da wollte ich dann bei Programmstart entsprechend der aktuellen Hintergrundfarbe eine passende Schriftfarbe wählen.
Hat da jemand einen Lösungsansatz?
--
Ideen gibt es viele - man muss sie nur haben...
Mint / LMDE5+6 // PureBasic 6.21
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Beitrag von RSBasic »

Hallo,

mit der WinAPI-Funktion GetSysColor_() kannst du die Standard-Hintergrundfarbe ermitteln.
Für GetSysColor_() gibt es zahlreiche Konstanten für jede einzelne Systemfarbe, z.B. Fenster-Hintergrundfarbe, Farbe der Schrift, der Titelleiste usw.
Beispielcode: https://www.rsbasic.de/aktualisierung/w ... mitteln.pb
Auflistung einiger Systemfarben mit den jeweiligen Konstanten, die du verwenden kannst: https://learn.microsoft.com/de-de/windo ... etsyscolor
Die Konstante, die du für Fensterhintergrund suchst, ist: #COLOR_3DFACE
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Macros
Beiträge: 1361
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Beitrag von Macros »

@RSBasic: Gut gemeint, aber guck mal auf den Forumnamen ;)

@jogo:
Das keine Farbe zurückgegeben wird, solang keine gesetzt wurde steht ja auch in der Hilfe.

Ähnlich wie es RSBasic für Windows demonstriert hat, kannst du auch unter Linux die Farbe mittels der APIs ermitteln.
Falls du GTK verwendest, ist hier ein Ansatz: https://stackoverflow.com/questions/303 ... ound-color
Für das QT Subsystem hier: https://stackoverflow.com/questions/174 ... log-window
Jemand, der geübter damit ist die Apis zu nutzen als ich, kann dir sicher mit einem Beispiel helfen.

z.B. hat sich im Englischen Forum "wombats" einem ähnlichen Problem für QTgestellt:
https://www.purebasic.fr/english/viewtopic.php?t=73874
Und mk-soft hat ein Beispiel für die Nutzung der GTK API hier:
http://forums.purebasic.com/english/vie ... hp?t=77261

Interessant wäre auch was du erreichen willst. Willst du z.B. die Farbe einfach wieder auf die Systemfarbe zurückändern, kannst du sie im QT Subsystem einfach wieder auf -1 setzen.
Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Beitrag von RSBasic »

Arg, verdammt, danke für den Hinweis, Macros.
Dann bitte meinen Beitrag ignorieren.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
jogo
Beiträge: 123
Registriert: 22.11.2020 20:05
Computerausstattung: 'ne Handvoll gebrauchte Laptops & PCs mit Mint und LMDE

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Beitrag von jogo »

Mein Problem ist folgendes:
ich habe für das Fenster keine Hintergrundfarbe gesetzt // ist also bei mir standardmäßig grau bzw weiß bei den StringGadgets.
In diesem Fenster habe einige Text- bzw. Stringgadgets platziert.
Diese Gadgets haben verschiedene Schriftfarben, um gewisse Zustände besser zu signalisieren.
Das Probelem ist, dass es dann auf anderen Systemen vorkommen kann, auf denen zum Beispiel ein dunkles Theme eingestellt ist, dass die Schrift in einigen Farben sehr schlecht zu lesen ist.

Meine Idee ist deshalb, beim Programmstart die Hintergrundfarbe des Fensters oder des Gadgets zu ermitteln (zB. die Pixelposition 1,1 oder ähnlich // wie auch immer).
Und wenn sie dunkel ist, setzte ich für die Schrift dann andere Farben, die für den dunklen Hintergrund geeignet sind.
Was besseres ist mit dafür halt erstmal nicht eingefallen. :)
--
Ideen gibt es viele - man muss sie nur haben...
Mint / LMDE5+6 // PureBasic 6.21
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Beitrag von mk-soft »

Sollte so laufen ...

Code: Alles auswählen

;-TOP

; GTK DarkMode by mk-soft, v1.02.1, 18.12.2022
; Link: https://www.purebasic.fr/english/viewtopic.php?t=80298

Procedure.s GetThemeName()
  Protected ThemeName.s, *Settings, *Theme
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    g_object_get_(*Settings, "gtk-theme-name", @strVal);
    ThemeName.s = PeekS(strVal, -1, #PB_UTF8)
    g_free_(strVal)
    ProcedureReturn ThemeName
  EndIf
EndProcedure

Procedure SetThemeName(ThemeName.s)
  Protected *Settings, *Theme
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    *Theme = UTF8(ThemeName)
    g_object_set_(*Settings, "gtk-theme-name", *Theme);
    FreeMemory(*Theme)
    ProcedureReturn #True
  EndIf
EndProcedure

; ----

Procedure IsDarkMode()
  Protected boolVal, *Settings, *Theme
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    g_object_get_(*Settings, "gtk-application-prefer-dark-theme", @boolVal);
    ProcedureReturn boolVal
  EndIf
EndProcedure

Procedure SetDarkMode(State)
  Protected boolVal, *Settings
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    g_object_get_(*Settings, "gtk-application-prefer-dark-theme", @boolVal)
    g_object_set_(*Settings, "gtk-application-prefer-dark-theme", State);
    ProcedureReturn boolVal
  EndIf
EndProcedure

; ****

;-TOP

; GTK GetWindowColor by mk-soft, v1.01.1, 27.08.2023

ImportC ""
  gtk_widget_get_style_context(Widget)
  gtk_style_context_get_background_color(context, state, pcolor)
EndImport

#GTK_STATE_FLAG_NORMAL       = 0
#GTK_STATE_FLAG_ACTIVE       = 1 << 0
#GTK_STATE_FLAG_PRELIGHT     = 1 << 1
#GTK_STATE_FLAG_SELECTED     = 1 << 2
#GTK_STATE_FLAG_INSENSITIVE  = 1 << 3
#GTK_STATE_FLAG_INCONSISTENT = 1 << 4
#GTK_STATE_FLAG_FOCUSED      = 1 << 5
#GTK_STATE_FLAG_BACKDROP     = 1 << 6
#GTK_STATE_FLAG_DIR_LTR      = 1 << 7
#GTK_STATE_FLAG_DIR_RTL      = 1 << 8

Structure GdkRGBA
  red.d;
  green.d;
  blue.d;
  alpha.d;
EndStructure

Procedure.l GetWindowColorEx(Window)
  Protected r1, context, color.GdkRGBA
  
  context = gtk_widget_get_style_context(WindowID(Window))
  gtk_style_context_get_background_color(context, #GTK_STATE_FLAG_NORMAL, @color)
  r1 = RGBA(color\red * 255, color\green * 255, color\blue * 255, color\alpha * 255)
  ProcedureReturn r1
EndProcedure

; ****

Enumeration Windows
  #Main
EndEnumeration

Enumeration MenuBar
  #MainMenu
EndEnumeration

Enumeration MenuItems
  
EndEnumeration

Enumeration Gadgets
  #MainEdit
  #MainButton1
  #MainButton2
EndEnumeration

Enumeration StatusBar
  #MainStatusBar
EndEnumeration

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar)
  ; Resize gadgets
  ResizeGadget(#MainEdit, 5, 5, dx -10, dy - 45)
  ResizeGadget(#MainButton1, 10, dy - 35, 120, 30)
  ResizeGadget(#MainButton2, dx - 130, dy - 35, 120, 30)
EndProcedure

Procedure Main()
  Protected dx, dy, Theme.s
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, "Window" , #MainStyle | #PB_Window_Invisible)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    
    ; StatusBar
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar)
    EditorGadget(#MainEdit, 5, 5, dx -10, dy - 45)
    ButtonGadget(#MainButton1, 10, dy - 35, 120, 30, "Set Dark")
    ButtonGadget(#MainButton2, dx - 130, dy - 35, 120, 30, "Clear Dark")
    
    Theme = GetThemeName()
    Theme = RemoveString(Theme, "-dark", #PB_String_NoCase)
    SetThemeName(Theme)
    
    If Not IsDarkMode()
      SetDarkMode(#True)
    EndIf
    
    SetGadgetText(#MainEdit, "ThemeName: " +  GetThemeName())
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    HideWindow(#Main, 0)
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
          
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                PostEvent(#PB_Event_CloseWindow, #Main, #Null)
                
            CompilerEndIf
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #MainEdit
              Select EventType()
                Case #PB_EventType_Change
                  ;
              EndSelect
              
            Case #MainButton1
              Select EventType()
                Case #PB_EventType_LeftClick
                  If SetDarkMode(#True)
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: True")
                  Else
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: False")
                  EndIf
                  
              EndSelect
              Debug "$" + RSet(Hex(GetWindowColorEx(#Main), #PB_Long), 8, "0")
              
            Case #MainButton2
              Select EventType()
                Case #PB_EventType_LeftClick
                  If SetDarkMode(#False)
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: True")
                  Else
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: False")
                  EndIf
                  
              EndSelect
              Debug "$" + RSet(Hex(GetWindowColorEx(#Main), #PB_Long), 8, "0")
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten