Seite 1 von 1

Brauche Hilfe zum TreeGadget mit Checkboxen...

Verfasst: 14.02.2008 09:03
von Ghosty1967
Hallo PBler...

Ich arbeite gerade an einem Installationsprogramm für ein Mess- und Auswertesystem.
Dabei bin ich auf eine Barriere gestoßen, welche ich alleine nicht überwunden bekomme.
Das Problem:
Im Installationprogramm werden diverse Teilinstallationen mittels eines TreeGadget angezeigt, welches dann teilweise über SubNodes verfügt.
Das Treegadget wird mit Checkboxen aufgebaut. Nun soll der Benutzer natürlich wählen können, was er installieren möchte. Das sieht dann etwar so aus...

- [x] Kalibriersoftware
......[x] Dokumentvorlagen
......[x] Gerätedaten
......[x] Beispiele
+[x] Prüfsystem
- [ ] Auswertung
......[ ] Tabellenvorlagen
......[ ] Referenzdaten
......[ ] Beispiele
usw...

Nun möchte ich gerne, das z.B. beim wählen/abwählen eines Nodes alle zugehörigen SubNodes mit gewählt/abgewählt werden.
Außerdem frage ich mich, wieso der Focus bei einem Klick auf irgendeine Checkbox immer wieder
zu vorherigen Node/SubNode zurückkehrt und nicht auf dem gewählten bleibt. Wenn ich auf den Nodetext klicke, geht es doch auch?
Kann mir vielleicht jemand praktisch weiterhelfen :mrgreen:

Verfasst: 14.02.2008 10:35
von gnasen
hmm das gestaltet sich tatsächlich schwieriger als Gedacht. Nicht nur, dass er auf das erste Element zurückspringt, er gibt bei getgadgetstate() auch grundsätzlich dieses zurück.
Wenn das ein Bug ist, muss wohl WinApi oder ein Callback dran...

Verfasst: 14.02.2008 10:44
von Ghosty1967
yep, denk ich mir... aber ich habe von API-Programmierung wirklich NULL Ahnung und deswegen suche ich Leute, die mir weiterhelfen können.
Es gibt zwar diverse Artikel hier zu ähnlichen Problemen, aber ich konnte noch nicht konkretes finden! :?

..und dann fand er doch noch was...
http://www.purebasic.fr/english/viewtop ... t+checkbox
Hilft zumindest schon einmal einen entscheidenden Schritt weiter... :D

Verfasst: 14.02.2008 12:08
von Xaby
Mmmm, also wenn du mich fragst, sollte das als Bug gemeldet werden.

Wieso muss man immer WinAPI nutzen, wenn es die Gadgets allein können sollten?

Vielleicht kann man das ja mit einer Verhaltensvariable in einem neuen Release von PureBasic definieren.

Also ob die Markierung zur Mausklick-Stelle springt oder auf dem zuletzt beklicktem Text bleibt.

Bei [+] und [-] Dinger ist es auch so. Nur wenn man einen Zweig schließt, springt die Markierung zur schließstelle.

Das TreeGadgetverhalten ist schon seltsam. Sollte auf jeden Fall noch mal drüber diskutiert werden :?

Verfasst: 14.02.2008 15:34
von RSBasic
@Ghosty1967
Das ist mir auch schon aufgefallen bei meinem EHDC.

Verfasst: 05.05.2008 21:20
von Shardik
Ghosty1967 hat geschrieben:- [x] Kalibriersoftware
......[x] Dokumentvorlagen
......[x] Gerätedaten
......[x] Beispiele
+[x] Prüfsystem
- [ ] Auswertung
......[ ] Tabellenvorlagen
......[ ] Referenzdaten
......[ ] Beispiele
usw...

Nun möchte ich gerne, das z.B. beim wählen/abwählen eines Nodes alle zugehörigen SubNodes mit gewählt/abgewählt werden.
Außerdem frage ich mich, wieso der Focus bei einem Klick auf irgendeine Checkbox immer wieder
zu vorherigen Node/SubNode zurückkehrt und nicht auf dem gewählten bleibt. Wenn ich auf den Nodetext klicke, geht es doch auch?
Kann mir vielleicht jemand praktisch weiterhelfen :mrgreen:
Was lange währt, wird endlich gut: :wink:

Code: Alles auswählen

Declare.L CheckForChildItems(ItemHandle.L)
Declare   TreeCallback(WindowHandle.L, Msg.L, wParam.L, lParam.L)

Define SelectionState.L

If OpenWindow(0, 0, 0, 220, 230, "Alle Subnodes aus-/abwählen", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If CreateGadgetList(WindowID(0))
    TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, #PB_Tree_CheckBoxes)

    AddGadgetItem(0, -1, "Kalibriersoftware", 0, 0)
    AddGadgetItem(0, -1, "Dokumentvorlagen", 0, 1)
    AddGadgetItem(0, -1, "Gerätedaten", 0, 1)
    AddGadgetItem(0, -1, "Beispiele", 0, 1)
    SetGadgetItemState(0, 0, #PB_Tree_Expanded)
    
    AddGadgetItem(0, -1, "Prüfsystem", 0, 0)

    AddGadgetItem(0, -1, "Auswertung", 0, 0)
    AddGadgetItem(0, -1, "Tabellenvorlagen", 0, 1)
    AddGadgetItem(0, -1, "Referenzdaten", 0, 1)
    AddGadgetItem(0, -1, "Beispiele", 0, 1)
    SetGadgetItemState(0, 5, #PB_Tree_Expanded)

    SetWindowCallback(@TreeCallback())

    Repeat
      WindowEvent = WaitWindowEvent()
    Until WindowEvent = #PB_Event_CloseWindow
  EndIf
EndIf

End


Procedure TreeCallback(WindowHandle.L, Msg.L, wParam.L, lParam.L)
  Shared SelectionState.L

  Protected ItemHandle.L
  Protected *NMTV.NM_TREEVIEW
  Protected TVHitTest.TV_HITTESTINFO
  Protected TVItem.TV_ITEM
  Protected WantedSelectionState.L

  If Msg = #WM_NOTIFY
    *NMTV = lParam

    If *NMTV\Hdr\hwndFrom = GadgetID(0)
      If *NMTV\Hdr\Code = #NM_CLICK
        TVHitTest\Pt\x = WindowMouseX(0) - GadgetX(0)
        TVHitTest\Pt\y = WindowMouseY(0) - GadgetY(0)

        ItemHandle = SendMessage_(GadgetID(0), #TVM_HITTEST, 0, @TVHitTest) 

        If ItemHandle <> 0
          If TVHitTest\Flags = #TVHT_ONITEMSTATEICON
            SendMessage_(GadgetID(0), #TVM_SELECTITEM, #TVGN_CARET, TVHitTest\hItem)

            If CheckForChildItems(ItemHandle)
              WantedSelectionState = SelectionState
              SendMessage_(GadgetID(0), #TVM_EXPAND, #TVE_EXPAND, ItemHandle)
              ItemHandle = SendMessage_(GadgetID(0), #TVM_GETNEXTITEM, #TVGN_CHILD, ItemHandle)

              While ItemHandle <> 0
                If CheckForChildItems(ItemHandle) = #False
                  TVItem\Mask = #TVIF_HANDLE | #TVIF_STATE
                  TVItem\hItem = ItemHandle
                  TVItem\StateMask = #TVIS_STATEIMAGEMASK
                  TVItem\State = WantedSelectionState
                  
                  SendMessage_(GadgetID(0), #TVM_SETITEM, 0, @TVItem)
                EndIf

                ItemHandle = SendMessage_(GadgetID(0), #TVM_GETNEXTITEM, #TVGN_NEXT, ItemHandle)
              Wend
            EndIf
          EndIf
        EndIf
      EndIf
    EndIf
  EndIf

  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure


Procedure.L CheckForChildItems(ItemHandle.L)
  Shared SelectionState.L

  Protected TVItem.TV_ITEM

  TVItem\Mask = #TVIF_CHILDREN | #TVIF_HANDLE | #TVIF_STATE
  TVItem\hItem = ItemHandle
  TVItem\StateMask = #TVIS_STATEIMAGEMASK
  SendMessage_(GadgetID(0), #TVM_GETITEM, 0, @TVItem)

  ; Checkbox vor Item
  ; 4096 = ohne Häkchen, 8192 = mit Häkchen

  If (TVItem\State >> 12) - 1
    SelectionState = 4096
  Else
    SelectionState = 8192
  EndIf

  If TVItem\cChildren = 1
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure