Aufklappen eines TreeGadgets

Anfängerfragen zum Programmieren mit PureBasic.
Tanaghra
Beiträge: 28
Registriert: 13.05.2017 01:44

Aufklappen eines TreeGadgets

Beitrag von Tanaghra »

Hallo,

ich habe in meinem Programmfenster u.a. ein TreeGadget mit derzeit 20 Einträgen, von denen einige auch Untereinträge (also das, was die Hilfe 'Sublevels' nennt) sind. Da demnächst noch sehr viel mehr Einträge in den Baum hineinkommen, habe ich eine Suchfunktion zum TreeGadget geschrieben. D.h. über dem TreeGadget habe ich ein StringGadget plaziert, in das man einen Suchbegriff eingeben kann, der dann im TreeGadget gefunden werden soll. Ausgelöst wird die Suche durch die Betätigung eines ButtonImageGadgets.

Das Problem besteht nun darin, daß die Suchroutine beim Debuggen einwandfrei funktioniert, aber die Anzeige (das Aufklappen) des Eintrags im TreeGadget nicht. Es folgt der Kode im Case-Zweig zum ButtonImageGadget in meiner Ereignis-Schleife (der angesprungen wird, wenn darauf geklickt wird):

Code: Alles auswählen

Case #Bs_SG ; Bildschaltfläche Suche in Grammatik
  St=GetGadgetText(#Ef_SG)  ; Suchtext
  gf=#False  ; gefunden?
  For Ix=0 To CountGadgetItems(#Bf_gE)-1
    TdE=GetGadgetItemText(#Bf_gE, Ix)  ; Text des Eintrags
    If FindString(TdE, St, 1, #PB_String_NoCase)
      SetGadgetItemState(#Bf_gE, Ix, #PB_Tree_Expanded|#PB_Tree_Selected)
      gf=#True: Break ; gefunden
    EndIf
  Next
  If Not gf
    MessageRequester("Hinweis", "Der Suchtext wurde nicht gefunden.",
      #PB_MessageRequester_Ok|#PB_MessageRequester_Info)
  EndIf
Die eigentliche Suchfunktion (also die For-Next-Schleife, die Eintrag für Eintrag des Baumes #Bf_gE durchgeht) funktioniert, wie gesagt, perfekt. Bis auf den SetGadgetItemState-Befehl, der den Untereintrag, der den Suchbegriff enthält, aufklappen sollte. So versteht ich zumindest die Funktion der Flags #PB_Tree_Expanded|#PB_Tree_Selected laut Hilfe. Es wird aber trotz erfolgreicher Suche überhaupt nichts aufgeklappt, der SetGadgetItemState-Befehl bleibt ohne sichtbare Wirkung. Warum?

Vielen Dank
Windows 7 x64; geposteter Kode bezieht sich (sofern nicht anders angegeben) immer auf das aktuellste PureBasic 64-Bit

Erst wenn man es seiner Schwiegermutter erklären kann, hat man es verstanden.
As gsündeste is oiwei guad essn und dringa und ned grang wern.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8398
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 20.10
NVIDIA Quadro P2200
Wohnort: Saarbrücken
Kontaktdaten:

Re: Aufklappen eines TreeGadgets

Beitrag von NicTheQuick »

Kannst du uns einen kompletten Code geben, mit dem das Verhalten nachvollziehbar ist?
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6826
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Aufklappen eines TreeGadgets

Beitrag von STARGÅTE »

Wenn ich das richtig sehe, dann versuchst du den Eintrag aufzuklappen der im Eltern-Knoten ist (welcher aufgeklappt werden sollte).
Was du allerdings machen müsstest ist, den Eltern-Knoten erst finden, der den Knoten enthält den du sehen willst, und dann den Eltern-Knoten öffnen.
PB 5.73 ― Win 10, 20H2 ― Ryzen 9 3900X ― Radeon RX 5600 XT ITX ― Vivaldi 4.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Tanaghra
Beiträge: 28
Registriert: 13.05.2017 01:44

Re: Aufklappen eines TreeGadgets

Beitrag von Tanaghra »

Danke für Eure Antworten. Stargate hat recht mit seiner Annahme, der aufzuklappende Eintrag ist ein Unterpunkt des zweiten Unterknotens (s. https://www.magentacloud.de/lnk/vXrPLQnt), d.h. man müßte mit SetGadgetItemState erst den Hauptknoten expandieren, dann die beiden Unterknoten und könnte erst dann den gewünschten Eintrag selektieren.

Mit anderen Worten: SetGadgetItemState ist derart nutzlos, daß man fast schon von einem Bug sprechen muß. Zum Glück habe ich in einem API-Makro Rettung gefunden; hier nochmal die For-Next-Schleife mit API-Message:

Code: Alles auswählen

For Ix=0 To CountGadgetItems(#Bf_gE)-1
  If FindString(GetGadgetItemText(#Bf_gE, Ix), St, 1, #PB_String_NoCase)
    SendMessage_(GadgetID(#Bf_gE), #TVM_SELECTITEM, #TVGN_CARET,
      GadgetItemID(#Bf_gE, Ix))
    Rdl(zlRd): gf=#True
    SetActiveGadget(#Bf_gE): Break
  EndIf
Next
Der SendMessage-Befehl klappt die Fundstelle auf und selektiert den Eintrag noch obendrein (was man ja meistens will).

Ich habe darüber hinaus festgestellt, daß SetGadgetItemStatet nicht nur für das Expandieren ungeeignet ist, sondern manchmal auch für das schlichte Markieren. Nach SetGadgetItemState(#Baum-Gadget, Ix, #PB_Tree_Selected) gibt GetGadgetState(#Baum-Gadget) zuweilen 0 oder -1 zurück, und nicht den Index des Eintrags, der zuvor eigentlich mit SetGadgetItemState selektiert worden war. Auch dieses Problem erinnert sich durch obiges SendMessage. Will man übrigens nur expandieren, ohne etwas zu markieren, dann kann man das so:

Code: Alles auswählen

SendMessage_(GadgetID(#Baum-Gadget), #TVM_ENSUREVISIBLE, 0,
  GadgetItemID(#Baum-Gadget, Index des zu expandierenden Eintrags))
Windows 7 x64; geposteter Kode bezieht sich (sofern nicht anders angegeben) immer auf das aktuellste PureBasic 64-Bit

Erst wenn man es seiner Schwiegermutter erklären kann, hat man es verstanden.
As gsündeste is oiwei guad essn und dringa und ned grang wern.
Antworten