Seite 1 von 2

Gelöst! Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 11:29
von EmmJott
Hallo !

Beim ExplorerTreegadget wird (wie bei anderen Gadgets auch) per Farbwechsel des ausgewählten Items gezeigt, ob das Gadget (noch) aktiv oder nicht (mehr) ist. Kann man den Farbwechsel ausschalten, damit immer die Farbgebung "mit Focus" bzw. "Gadget aktiv" angezeigt wird, unabhängig vom echten Focus?

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 12:33
von gekko
SetGadgetColor() führt nicht zum gewünschten Ergebnis?

Kopiert aus der Hilfe:
This gadget supports the SetGadgetColor() and GetGadgetColor() functions with the following values as 'ColorType':
#PB_Gadget_FrontColor: Textcolor
#PB_Gadget_BackColor : Backgroundcolor

Code: Alles auswählen

If OpenWindow(0, 0, 0, 300, 300, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ExplorerTreeGadget(0, 10, 10, 280, 280, "*.pb;*.pbi")
  SetGadgetColor(0, #PB_Gadget_FrontColor, $000000)
  SetGadgetColor(0, #PB_Gadget_BackColor, $FFFFFF)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 13:05
von EmmJott
Hi,

nein, das war so nicht gemeint. Es geht nicht um die farbliche Darstellung des ganzen Gadgets, sondern nur um die des ausgewählten Items eines Gadgets. Um beim Beispielcode zu bleiben: Wähle ich einen Eintrag aus wird der (jedenfalls bei mir) mit weißer Schrift und blau unterlegt dargestellt. Wenn das Gagdet den Fokus verliert (weil anderes Gadget aktiv), wird der Eintrag mit weißer Schrift und hellgrau unterlegt dargestellt.

Ich hätte es aber gerne, dass der Eintrag weiß-blau bleibt, unabhängig vom Fokus.

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 15:09
von H.Brill
Ich glaube, das hat eher mit der Eigenart von Windows zu tun, wenn du den blauen Balken, den es auch bei Listboxen usw. gibt,
meinst. Dafür ist dann auch SetGadgetItemSate() zu nutzen. Für Gridboxen und Listboxen gibt es auch eine Mehrfach-Auswahl.
Man hält ja die STRG-Taste gedrückt und markiert mit der Maus die Einträge. Windows wird aber alle nicht fokusierten Einträge
beim nächsten Klick wieder auf normal stellen.
Du könntest mal schauen, ob du beim Erstellen des Gadget mit #PB_Explorer_AlwaysShowSelection als Flag etwas erreichst.

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 16:31
von Axolotl
Dir sollte aber klar sein, dass das dann nicht mehr der M$ Style Vorgabe entspricht.
Leider habe ich es mit dem ExplorerTreeGadget (noch) nicht hinbekommen, sondern nur mit dem TreeGadget.
Aktueller Stand meiner (kläglichen) Versuche:
Zum Ausprobieren einfach einen Eintrag selektieren und mit der TAB Taste zwischen den beiden Gadgets hin- und herspringen.....

Code: Alles auswählen

Procedure WCallback(hWnd,uMsg,wParam,lParam)
  Protected tt.s 

  Select uMsg
    Case  #WM_NOTIFY
      *tvCD.NMTVCUSTOMDRAW = lParam 

      If *tvCD\nmcd\hdr\code = #NM_CUSTOMDRAW  
        If *tvCD\nmcd\hdr\hwndFrom = GadgetID(0) 
          tt = "Gadget_0  " 
        ElseIf *tvCD\nmcd\hdr\hwndFrom = GadgetID(1) 
          tt = "Gadget_1  " 
        EndIf 


        If *tvCD\nmcd\hdr\hwndFrom = GadgetID(0) Or *tvCD\nmcd\hdr\hwndFrom = GadgetID(1) 
          Select *tvCD\nmcd\dwDrawStage
            Case #CDDS_PREPAINT                                 ;: Debug "#CDDS_PREPAINT" 
              ProcedureReturn #CDRF_NOTIFYITEMDRAW

            Case #CDDS_ITEMPREPAINT 
                If *tvCD\nmcd\uItemState & #CDIS_SELECTED                   : Debug "#CDDS_ITEMPREPAINT  "+tt+"Selected " 
                  *tvCD\clrText   = GetSysColor_(#COLOR_HIGHLIGHTTEXT)
                  *tvCD\clrTextBk = GetSysColor_(#COLOR_HIGHLIGHT)
                Else                                                        : Debug "#CDDS_ITEMPREPAINT  "+tt+"Default  " 
                  *tvCD\clrText   = GetSysColor_(#COLOR_WINDOWTEXT)
                  *tvCD\clrTextBk = GetSysColor_(#COLOR_WINDOW) 
                EndIf 
              ProcedureReturn #CDRF_NOTIFYPOSTPAINT

;             Case #CDDS_ITEMPOSTPAINT                            : Debug "#CDDS_ITEMPOSTPAINT #### " 
;               ProcedureReturn #CDRF_NEWFONT           
          EndSelect
        EndIf
      EndIf
  EndSelect 
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure


If OpenWindow(0, 0, 0, 600, 640, "Tree vs. ExplorerTree", #PB_Window_SystemMenu| #PB_Window_ScreenCentered) 
  TreeGadget(0, 10, 0, 580, 300, #PB_Tree_AlwaysShowSelection) 
  ExplorerTreeGadget(1, 10, 310, 580, 300, "c:\temp", #PB_Tree_AlwaysShowSelection)

  AddGadgetItem(0, -1, "Main Node ", 0, 0) 
  AddGadgetItem(0, -1, "Sub Node", 0, 1)
  AddGadgetItem(0, -1, "Second Main Level Node", 0, 0) 
  AddGadgetItem(0, -1, "Sub text", 0, 1)
  AddGadgetItem(0, -1, "Third Node")
 
  SetWindowCallback(@WCallback())
 
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break ; bye 
    EndSelect
  ForEver  
EndIf

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 16:33
von EmmJott
Servus @ all!

habe im engl. Forum den Beitrag https://www.purebasic.fr/english/viewtopic.php?t=49289 gefunden. Darin geht's zwar um ein anderes Gadget, aber das Thema ist das Gleiche. Da kann man mit "Keep blue on lost focus" die Selektion markiert "halten" (bzw. das Gadget "aktiv halten"), auch wenn ein anderes Gadget den Focus hat. Wünschte nur, ich könnte das auf ein ExplorerTreeGadget anwenden ...

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 16:53
von Axolotl
Ja, der Beispielcode geht genauso wenig mit ExplorerTreeGadget wie meiner im vorherigen Post......
Evtl. ist es ein "Work-around" mit einem TreeGadget zu arbeiten und es selbst zu füllen?

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 28.05.2025 17:33
von H.Brill
Nur mal so eine Idee von mir :
Vielleicht könnte man die Posionen, die vorher mit GetGadgetState() ermittelten und fokusierten Items in ein Array schreiben
und beim nächsten Klick auf ein Item wieder markieren.
Mit AddKeyboardShortcut() in einer Schleife könnte man dann die STRG-Taste und ein MouseDown schicken.

Ist aber, wie oben schon gesagt wurde, nicht mehr Windowskonform.

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 29.05.2025 11:33
von EmmJott
An ein Treegadget hatte ich zuerst gedacht, da das Explorertreegadget ein paar Schwächen hat (höchst subjektive Meinung), die mit dem Treegadget zu umgehen gewesen wären. Aber ein ganzes Laufwerk in ein Treegadget zu laden, dauert zu lange. Man müsste es dynamisch befüllen, also Verzeichniszweige (Sublevels) je nach Bedarf hinzufügen - daran bin ich (kläglich) gescheitert.

Re: Farbwechel mit/ohne Focus bei ExplorerTreegadget

Verfasst: 30.05.2025 19:06
von Shardik
EmmJott hat geschrieben: 28.05.2025 16:33 Wünschte nur, ich könnte das auf ein ExplorerTreeGadget anwenden ...
Axolotl hat geschrieben: 28.05.2025 16:53 Ja, der Beispielcode geht genauso wenig mit ExplorerTreeGadget wie meiner im vorherigen Post......
Dass mein angesprochenes 13 Jahre altes TreeGadget-Beispiel im englischen Forum nicht mit einem ExplorerTreeGadget funktioniert, liegt daran, dass PureBasic die Funktion GadgetItemID() nur für das TreeGadget, aber nicht für das ExplorerTreeGadget unterstützt. Außerdem liefert das ebenfalls verwendete GetGadgetState() im TreeGadget den aktuell ausgewählten Eintrag, im ExplorerTreeGadget aber den Verzeichnistyp (#PB_Explorer_File für eine Datei oder #PB_Explorer_Directory für ein Verzeichnis).

Ich habe daher das TreeGadget-Beispiel für ein ExplorerTreeGadget leicht abgeändert und benutze nun die API-Funktion TVM_GETNEXTITEM mit TVGN_CARET, um das Handle des aktuell selektierten Eintrags zur ermitteln.

Ich habe dieses Beispiel erfolgreich getestet in Windows 10 x64 22H2 mit PB 6.20 x86 und x64 (mit Asm- und C-Backend).

Code: Alles auswählen

EnableExplicit

Procedure HighlightItem(ExplorerTreeID.I, HighlightFlag.I)
  Protected ItemHandle.I
  Protected TVHitTest.TV_HITTESTINFO
  Protected TVItem.TV_ITEM

  ItemHandle = SendMessage_(GadgetID(ExplorerTreeID), #TVM_GETNEXTITEM,
    #TVGN_CARET, 0)

  If ItemHandle <> 0
    If TVHitTest\Flags <> #TVHT_ONITEMBUTTON
      TVItem\Mask = #TVIF_STATE
      TVItem\hItem = ItemHandle

      If HighlightFlag = #True
        TVItem\StateMask = #TVIS_DROPHILITED
        TVItem\State = #TVIS_DROPHILITED
      Else
        TVItem\StateMask = #TVIS_DROPHILITED
        TVItem\State = 0
      EndIf

      SendMessage_(GadgetID(0), #TVM_SETITEM, 0, @TVItem)

      RedrawWindow_(GadgetID(0), 0, 0, #RDW_UPDATENOW)
    EndIf
  EndIf
EndProcedure

Define TreeGadgetIsInFocus.I

OpenWindow(0, 0, 0, 350, 550, "ExplorerTreeGadget",
  #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ExplorerTreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 80,
  "C:\", #PB_Tree_AlwaysShowSelection)
ButtonGadget(1, 10, WindowHeight(0) - 60, WindowWidth(0) - 20, 20,
  "Toggle focus")
CheckBoxGadget(2, 10, WindowHeight(0) - 30, WindowWidth(0) - 20, 20,
  "Keep blue on lost focus")

; ----- Activate ExplorerTreeGadget
SetActiveGadget(0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0 ; <---- TreeGadget was clicked
          HighlightItem(0, #False)
        Case 1 ; <---- Button was pressed
          TreeGadgetIsInFocus ! 1
          
          If TreeGadgetIsInFocus
            If GetGadgetState(2)
              HighlightItem(0, #True)
            EndIf
            
            SetActiveGadget(1)
          Else
            SetActiveGadget(0)
          EndIf
        Case 2 ; <---- CheckBox was clicked
          If GetGadgetState(2)
            HighlightItem(0, #True)
          Else
            HighlightItem(0, #False)
            SetActiveGadget(0)
          EndIf
      EndSelect
  EndSelect
ForEver