Tree Gadget alle Items expanden / collapsen

Für allgemeine Fragen zur Programmierung mit PureBasic.
TWELVE
Beiträge: 72
Registriert: 01.04.2007 18:33

Tree Gadget alle Items expanden / collapsen

Beitrag von TWELVE »

Hallo zusammen,

ich nutze ein Tree Gadget, welches recht viele Items enthält ( ~ 50.000).Ich möchte dem User die Möglichkeit geben, alle Items / Subitems auf einmal
zu expanden bzw. zu collapsen.

Für das Expand habe ich schon eine Lösung gefunden:

Code: Alles auswählen

Define hwndTV.l, hRoot.l, hItem.l 
  hwndTV.l = GadgetID(gadget)  
  hRoot.l = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)  
  hItem.l = hRoot  
  
     
  Repeat 
    SendMessage_(hwndTV, #TVM_EXPAND, #TVE_EXPAND, hItem) 
    hItem = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_NEXTVISIBLE , hItem)  
    
    
    
  Until hItem = #Null
  
  
  SendMessage_(hwndTV, #TVM_ENSUREVISIBLE, 0, hRoot) 

Für das Collapse habe ich noch keine Lösung gefunden - bzw. nur eine, die jedes Item in einer Schleife durchgeht und den Collapse
herkömmlich über #PB_Tree_Collapsed macht, was aber in der Summe viel zu lange dauert.

Der obige Weg über SendMessage_ ist gemessen an der Zahl der Nodes sehr akzeptabel.Daher hätte ich gern den gleichen Weg
für den Collapse, weiß nur nicht wie.

Habe das hier probiert:

Code: Alles auswählen

SendMessage_(hwndTV, #TVM_EXPAND, #TVE_COLLAPSE, hItem) 
Aber das klappt nur den Root/Top Node zusammen, alle weiteren Items / Nodes bleiben ausgeklappt.

Ich finde es eh schade, dass man für relativ simple Sachen auf WinAPI Funktionen zurückgreifen muß, damit
kann man eine Portablität vergessen, aber gut, anderes Thema ;-)

Hat jemand eine Lösung für mich ? Optional wäre ich noch an einer Lösung interessiert, wie man Expand / Collapse
für alle Elemente unterhalb einer bestimmten Ebene machen kann.Kenne mich nicht mit WinAPI aus, daher sind
solche Codeschnipsel immer reines Copy / Paste für mich, leider...


Ich bedanke mich im voraus...

Viele Grüße,

TWELVE
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von RSBasic »

Hallo TWELVE,

die WinAPI-Verwendung ist nicht nötig, da PureBasic bereits solche Möglichkeiten zum Ein- und Ausklappen von Tree-Einträgen anbietet.

Code: Alles auswählen

SetGadgetItemState(#Gadget, #Entry, #PB_Tree_Expanded)

Code: Alles auswählen

SetGadgetItemState(#Gadget, #Entry, #PB_Tree_Collapsed)
Siehe Hilfe und/oder mein Beispiel:

Code: Alles auswählen

EnableExplicit

Define a

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(1, 0, 0, WindowWidth(0), WindowHeight(0)-40, 0)
  AddGadgetItem(1, -1, "Eintrag 1", 0, 0)
  AddGadgetItem(1, -1, "Eintrag 1.1", 0, 1)
  AddGadgetItem(1, -1, "Eintrag 1.2", 0, 1)
  AddGadgetItem(1, -1, "Eintrag 1.2.1", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 2", 0, 0)
  
  ButtonGadget(2, WindowWidth(0)-220, WindowHeight(0)-30, 100, 20, "Alles ausklappen", 0)
  ButtonGadget(3, WindowWidth(0)-110, WindowHeight(0)-30, 100, 20, "Alles einklappen", 0)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 2
            For a=0 To CountGadgetItems(1)-1
              SetGadgetItemState(1, a, #PB_Tree_Expanded)
            Next  
          Case 3
            For a=0 To CountGadgetItems(1)-1
              SetGadgetItemState(1, a, #PB_Tree_Collapsed)
            Next
        EndSelect
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
Falls der Vorgang zu lange dauern sollte, liegt es wahrscheinlich am automatischen Neuzeichnen. Um das Problem beheben zu können, musst du vor dem Ein-/Ausklappen das Neuzeichnen deines TreeGadgets temporär deaktivieren und danach wieder aktivieren: http://www.rsbasic.de/aktualisierung/wi ... 3%BCgen.pb
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
TWELVE
Beiträge: 72
Registriert: 01.04.2007 18:33

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von TWELVE »

Hallo RSBasic,

vielen Dank für die Antwort.

Durch das Deaktvieren des Tree Gadgets komme ich mit #PB_Tree_Collapsed/Expanden auf sehr akzeptable Zeiten, allerdings hatte ich
diese Idee schon für die WinAPI Lösung umgesetzt und danach die herkömmliche Lösung nie wieder in Betracht gezogen.Ich habe mal
die Zeiten über ElapsedMilliseconds() gestopp und mit dem Disablen des Tree Gagdets ist die WinAPI Lösung sogar etwas langsamer.

Die nicht-API Version braucht etwa nur 84% der Zeit der WinAPI Version....

Soviele Elemente in einem Tree ist sicher auch nicht der Standardfall und ich versuch meine Applikationen immer auf die bestmögliche
Performance hin zu optimieren...die erreichbaren Zeiten finde ich allerdings allesamt alle zu hoch.


Danke...

Viele Grüße,

TWELVE
TWELVE
Beiträge: 72
Registriert: 01.04.2007 18:33

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von TWELVE »

Ich habe da nochmal eine Frage zu.Nachdem ich den Tree komplett expanded habe ( siehe oben), hat das Tree Gadget eine Scrollleiste wegen der Anzahl der Nodes, allerdings steht der Scroller
ganz unten.Ich möchte aber, dass der Scrollbalken den obersten Teil anzeigt.Habe es mit #PB_Tree_Selected probiert:

SetGadgetItemState(Tree_0, 0 , #PB_Tree_Selected)

Der entsprechende Node wird auch selektiert, aber der Scrollbalken bleibt trotzdem ganz unten.Wie krieg ich den Scroller nach dem Expand wieder nach oben ?

Gleiches Problem habe ich auch nach dem Laden eines Textes in ein Editor Gadget.
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von RSBasic »

Da musst du glaube ich SetScrollPos_() verwenden.
Bezüglich des EditorGadgets: http://www.rsbasic.de/aktualisierung/wi ... crollen.pb
Ich bin mir nicht sicher, ob PB eine eigene Funktion zum Scrollen anbietet.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Kiffi
Beiträge: 10719
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von Kiffi »

@TWELVE:

habe hier was von IdeasVacuum gefunden:

Code: Alles auswählen

Procedure TreeTop()
 Protected hwndTV.i = GadgetID(#MyTree)
 Protected  hItem.i = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
                      SendMessage_(hwndTV, #TVM_ENSUREVISIBLE, 0, hItem)
EndProcedure
Grüße ... Peter
a²+b²=mc²
TWELVE
Beiträge: 72
Registriert: 01.04.2007 18:33

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von TWELVE »

Für das Tree Gadget hatte ich mit:

SetGadgetState(Tree,1)

eine "Fast"-Lösung.Allerdings ist dann Item 1 selektiert und nicht Item 0 ( also der Top Node).Nehme ich 0 als Argument,
dann bleibt der Scrollbereich unten und es wird auch kein Item selektiert.Alles was größer 0 ist, selektiert das entsprechende
Item, aber bei > 1 wird der Scrollbereich nicht nach oben bewegt.

Mit

SetGadgetState(Editor,1)

wird komischerweise der Scrollbereich auf den Anfang des geladenen Textes gesetzt, obwohl SetGadgetState für das Editor Gadget
gar nicht dokumentiert ist.


Kiffi hat geschrieben:@TWELVE:

habe hier was von IdeasVacuum gefunden:

Code: Alles auswählen

Procedure TreeTop()
 Protected hwndTV.i = GadgetID(#MyTree)
 Protected  hItem.i = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
                      SendMessage_(hwndTV, #TVM_ENSUREVISIBLE, 0, hItem)
EndProcedure
Grüße ... Peter
Also das funktioniert einwandfrei und genauso, wie es soll.

RSBasic hat geschrieben:Da musst du glaube ich SetScrollPos_() verwenden.
Bezüglich des EditorGadgets: http://www.rsbasic.de/aktualisierung/wi ... crollen.pb
Ich bin mir nicht sicher, ob PB eine eigene Funktion zum Scrollen anbietet.
Also die entscheidende Zeile aus Deinem Source funktioniert ebenfalls einwandfrei:

SendMessage_(GadgetID(Editor_1),#EM_SCROLL,#SB_TOP,0)

Vielen Dank Euch zwei für die schnelle Lösung !

Ich bin nur mal wieder enttäuscht, dass so einfache Dinge wieder nur mit WinAPI gehen und damit eine leichte Portablität auf
Linux nicht mehr möglich ist.

Falls jemand noch eine Nicht-API Version davon anbieten kann, das würde ich mich freuen ! Bin froh um jedes Stück WinAPI code, dass
ich aus meinem Source Code verbannen kann.

Jetzt erhöhe ich nochmal den Schwierigkeitsgrad, wie kann man den Scrollbereich gezielt so setzen, dass ein bestimmtes Item
im sichtbaren Bereich ist ? Also wieder für Editor und Tree.Egal ob WinAPI oder nicht ! Ich vermute, dafür muß man für das EditorGadget
#SB_TOP gegen die Position des Items austauschen ?

Ich bedanke mich schonmal...
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von RSBasic »

Ich habe schon lange aufgegeben, betriebssystemunabhängig zu schreiben. Da ich eh Windows primär nutze, ist mir das auch egal. Hauptsache ich komme ans Ziel (Umsetzung der von mir gewünschten Features).
Ich finds schlimmer, wenn ich auf bestimmte Funktionen aufgrund der WinAPI-Verwendung verzichten müsste. Entweder müsste man das ganze Projekt abbrechen/aufgeben (weil das ohne API nicht anders geht) oder haufenweise Workarounds schreiben.
Man könnte zwar versuchen, die im Quellcode verwendeten WinAPI-Funktionen auch für andere Betriebssysteme zu portieren, aber ob sich der Mehraufwand lohnt, weiß ich nicht. Außerdem muss man sich natürlich mit der API-Schnittstelle von Linux und/oder MacOS auskennen. Das ist bei mir nicht der Fall und deshalb schreibe ich Anwendungen ausschließlich für Windows.

Es ist zwar schön, dass PB grundsätzlich betriebssystemunabhängige Funktionen anbietet, aber manchmal möchte man mehr und dann ist die Frage, ob mit oder ohne API.
TWELVE hat geschrieben:Jetzt erhöhe ich nochmal den Schwierigkeitsgrad, wie kann man den Scrollbereich gezielt so setzen, dass ein bestimmtes Item
im sichtbaren Bereich ist ? Also wieder für Editor und Tree.Egal ob WinAPI oder nicht ! Ich vermute, dafür muß man für das EditorGadget
#SB_TOP gegen die Position des Items austauschen ?
Ich kann es gerade nicht testen, aber vielleicht ist #TVM_GETITEM was du suchst.
Also statt #TVM_GETNEXTITEM kannst du #TVM_GETITEM verwenden. Du brauchst nur die Handle-Nummer des gewünschten Items, die du mit Hilfe des 4. Parameters (lParam) als Strukturübergabe (TVITEM\HTREEITEM) bekommen kannst.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von ts-soft »

@RSBasic

Wie wäre es mit Linux-API? :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Tree Gadget alle Items expanden / collapsen

Beitrag von Andesdaf »

bei mir funktionierts auf Windows so auch ohne API, das erste Item ist immer oben, egal ob ein- oder ausgeklappt wurde.
(RSBasics Beispiel von oben genommen)

Code: Alles auswählen

EnableExplicit

Define a

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(1, 0, 0, WindowWidth(0), 90, 0)
  AddGadgetItem(1, -1, "Eintrag 1", 0, 0)
  AddGadgetItem(1, -1, "Eintrag 1.1", 0, 1)
  AddGadgetItem(1, -1, "Eintrag 1.2", 0, 1)
  AddGadgetItem(1, -1, "Eintrag 1.2.1", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 1.2.2", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 1.2.3", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 1.2.4", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 1.2.5", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 1.2.6", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 1.2.7", 0, 2)
  AddGadgetItem(1, -1, "Eintrag 2", 0, 0)
 
  ButtonGadget(2, WindowWidth(0)-220, WindowHeight(0)-30, 100, 20, "Alles ausklappen", 0)
  ButtonGadget(3, WindowWidth(0)-110, WindowHeight(0)-30, 100, 20, "Alles einklappen", 0)
 
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 2
            For a=0 To CountGadgetItems(1)-1
              SetGadgetItemState(1, a, #PB_Tree_Expanded)
            Next
            SetGadgetState(1, 1)
            SetGadgetState(1, 0)
          Case 3
            For a=0 To CountGadgetItems(1)-1
              SetGadgetItemState(1, a, #PB_Tree_Collapsed)
            Next
        EndSelect
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
Win11 x64 | PB 6.20
Antworten