[gelöst]TreeGadget-Event-Auswertung klappt nich wie ich will

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

[gelöst]TreeGadget-Event-Auswertung klappt nich wie ich will

Beitrag von scholly »

moin, moin...

Ich hab den Code mal soweit 'runtergestrippt, daß ich mein Problem darstellen kann.

Code: Alles auswählen

  #main_tree =1
  #strg_id = 2
  Define.s parentTGitem
  
  Procedure.s ugs_get_parentTGitem(main_treeID.l)
  Define.l main_treeID
  CurrentItem = GetGadgetState(main_treeID)
  CurrentLevel = GetGadgetItemAttribute(main_treeID,CurrentItem,#PB_Tree_SubLevel)

  If CurrentLevel > 0            
    For i = CurrentItem-1 To 0 Step -1         
      If GetGadgetItemAttribute(main_treeID,i,#PB_Tree_SubLevel) < CurrentLevel
        parent$ = GetGadgetItemText(main_treeID,i,0)
        Break
      EndIf            
    Next      
  Else
    parent$ = "no parent"         
  EndIf

  ProcedureReturn parent$
  
EndProcedure; ugs_getparentTGitem
  
  Procedure   ugs_filter_sql()
    SetGadgetText(#strg_id, GetGadgetItemText(#main_tree, GetGadgetState(#main_tree), 0)) 
  EndProcedure; ugs_filter_sql()
  
  If OpenWindow(0, 50, 50, 355, 250, "TreeGadget", #PB_Window_SystemMenu ) And CreateGadgetList(WindowID(0))
    TreeGadget(#main_tree, 5, 5, 160, 230, #PB_Tree_AlwaysShowSelection )                                         
      AddGadgetItem(#main_tree, -1, "Normal Item "+Str(a), 0, 0) 
      AddGadgetItem(#main_tree, -1, "Node 1", 0, 0)        
      AddGadgetItem(#main_tree, -1, "Sub-Item 1", 0, 1)            
      AddGadgetItem(#main_tree, -1, "Sub-Item 2", 0, 1)
      AddGadgetItem(#main_tree, -1, "Sub-Item 3", 0, 1)
      AddGadgetItem(#main_tree, -1, "Sub-Item 4", 0, 1)
      AddGadgetItem(#main_tree, -1, "File "+Str(a), 0, 0)        
      AddGadgetItem(#main_tree, -1, "Node 2", 0, 0)        
      AddGadgetItem(#main_tree, -1, "Sub-Item 11", 0, 1)           
      AddGadgetItem(#main_tree, -1, "Sub-Item 12", 0, 1)
      AddGadgetItem(#main_tree, -1, "Sub-Item 13", 0, 1)
      AddGadgetItem(#main_tree, -1, "Sub-Item 14", 0, 1)
    StringGadget(#strg_id,170,100,100,20,"")
  EndIf
  SetActiveGadget(#main_tree)
  SetGadgetState(#main_tree, 0)
  ugs_filter_sql()
  Gosub main
  End
  
  main:
;#############################################
;{
  Repeat

    Select WaitWindowEvent()

      Case #PB_Event_CloseWindow
        Quit = #True
    
      Case #PB_Event_Gadget      
        ETyp = EventType()
        Select EventGadget()
          Case #main_tree         
            Select ETyp
            
              Case #PB_EventType_LeftClick         
                If parentTGitem <> GetGadgetItemText(#main_tree, GetGadgetState(#main_tree))
                  ugs_filter_sql()
                EndIf
              Case #PB_EventType_LeftDoubleClick    
              Case #PB_EventType_RightDoubleClick   
              Case #PB_EventType_RightClick         
              Case #PB_EventType_Focus              
              Case #PB_EventType_LostFocus          
              Case #PB_EventType_Change             
              Case #PB_EventType_DragStart          

            EndSelect; Select EventType() for TreeGadget

        EndSelect; Select EventGadget()

        parentTGitem = ugs_get_parentTGitem(#main_tree)
 
    EndSelect; WaitWindowEvent()

  Until Quit = #True
;}
Return; main
Jedesmal, wenn man einen Item-/Knoten-Text Singleklickt, wird der Text ins StringGadget geschrieben.
Das soll so sein.

Wenn ich einen Knoten nur öffne oder schließe, wird das StringGadget nicht verändert.
Das soll so sein.

Wenn ich erst Node1 öffne, dann Node2 öffne und dann Sub-Item 14 anklicke, kommt das ins StringGadget.
Das soll so sein.

Wenn ich aber jetzt Node2 über den Knoten (+-) schließe und wieder öffne, wird "Node2" ins StringGadget geschrieben.
Das soll nicht sein, der alte Inhalt ("Sub-Item 14") soll erhalten bleiben.

Ich seh vielleicht nach ettlichen Versuchen (u.a auch mit #PB_Tree_Collapsed und #PB_Tree_Expanded) den Wald vor lauter Bäumen nicht, aber mir fällt nix mehr ein.

Mag jemand helfen ?
Zuletzt geändert von scholly am 17.05.2008 16:01, insgesamt 1-mal geändert.
Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Beitrag von Shardik »

Die Lösung ist eigentlich ganz einfach, aber sie hat mich jetzt tatsächlich einen halben Tag gekostet: :lol:

Code: Alles auswählen

Enumeration
  #Tree
  #Status
EndEnumeration

Procedure.L ItemButtonClicked()
  Protected ItemHandle.L
  Protected TVHitTest.TV_HITTESTINFO
  Protected TVItem.TV_ITEM

  TVHitTest\Pt\x = WindowMouseX(0) - GadgetX(#Tree)
  TVHitTest\Pt\y = WindowMouseY(0) - GadgetY(#Tree)

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

  If ItemHandle <> 0
    If TVHitTest\Flags = #TVHT_ONITEMBUTTON
      ProcedureReturn #True
    EndIf
  EndIf

  ProcedureReturn #False
EndProcedure

If OpenWindow(0, 50, 50, 355, 250, "TreeGadget", #PB_Window_SystemMenu ) And CreateGadgetList(WindowID(0)) 
  TreeGadget(#Tree, 5, 5, 160, 230, #PB_Tree_AlwaysShowSelection )                                          
  AddGadgetItem(#Tree, -1, "Normal Item "+Str(a), 0, 0) 
  AddGadgetItem(#Tree, -1, "Node 1", 0, 0)        
  AddGadgetItem(#Tree, -1, "Sub-Item 1", 0, 1)            
  AddGadgetItem(#Tree, -1, "Sub-Item 2", 0, 1) 
  AddGadgetItem(#Tree, -1, "Sub-Item 3", 0, 1) 
  AddGadgetItem(#Tree, -1, "Sub-Item 4", 0, 1) 
  AddGadgetItem(#Tree, -1, "File "+Str(a), 0, 0)        
  AddGadgetItem(#Tree, -1, "Node 2", 0, 0)        
  AddGadgetItem(#Tree, -1, "Sub-Item 11", 0, 1)            
  AddGadgetItem(#Tree, -1, "Sub-Item 12", 0, 1) 
  AddGadgetItem(#Tree, -1, "Sub-Item 13", 0, 1) 
  AddGadgetItem(#Tree, -1, "Sub-Item 14", 0, 1) 
  StringGadget(#Status,170,100,100,20,"") 

  SetActiveGadget(#Tree) 
  SetGadgetState(#Tree, 0) 
  SetGadgetText(#Status, GetGadgetItemText(#Tree, GetGadgetState(#Tree))) 

  Repeat 
    Select WaitWindowEvent() 
      Case #PB_Event_CloseWindow 
        Break 
      Case #PB_Event_Gadget      
        Select EventGadget() 
          Case #Tree          
            Select EventType()
              Case #PB_EventType_LeftClick          
                If ItemButtonClicked() = #False
                  SetGadgetText(#Status, GetGadgetItemText(#Tree, GetGadgetState(#Tree))) 
                EndIf 
            EndSelect
        EndSelect
    EndSelect
  ForEver
EndIf
Das Problem liegt darin, daß man mit PureBASIC-Befehlen nicht unterscheiden kann, ob der Anwender auf das [+] oder [-] vor einem Eintrag klickt oder auf den Eintrag (mit Subnodes) selbst! Ich habe daher das WinAPI bemühen müssen, bin dabei aber ohne Callback ausgekommen. Nach jedem Linksklick in das TreeGadget wird die Prozedur ItemButtonClicked() aufgerufen, die ein #True zurückgibt, wenn auf [+] oder [-] geklickt wurde und #False in allen anderen Fällen. Nur dann wird der Inhalt des StringGadgets mit dem aktuellen TreeGadget-Eintrag überschrieben.
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

Beitrag von scholly »

Ich kann mich nur Jaycool anschließen:

:allright: vielen Dank für Deine (erfolgreichen) Bemühungen...
Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

Beitrag von scholly »

moin, moin...

Kann bitte mal jemand diesen Code testen ?

Code: Alles auswählen

#main_win   = 1
#main_tree  = 3

Procedure.L ItemButtonClicked()
  Protected ItemHandle.L
  Protected TVHitTest.TV_HITTESTINFO
  Protected TVItem.TV_ITEM

  TVHitTest\Pt\x = WindowMouseX(#main_win) - GadgetX(#main_tree)
  TVHitTest\Pt\y = WindowMouseY(#main_win) - GadgetY(#main_tree)

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

  If ItemHandle <> 0
    If TVHitTest\Flags = #TVHT_ONITEMBUTTON
      ProcedureReturn #True
    EndIf
  EndIf

  ProcedureReturn #False
EndProcedure

If OpenWindow(#main_win, 50, 50, 355, 250, "TreeGadget", #PB_Window_SystemMenu ) And CreateGadgetList(WindowID(#main_win))
  TreeGadget(#main_tree, 5, 5, 160, 230, #PB_Tree_AlwaysShowSelection )                                         
  AddGadgetItem(#main_tree, -1, "Normal Item 1", 0, 0)
  AddGadgetItem(#main_tree, -1, "Node 1", 0, 0)       
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-1", 0, 1)           
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-2", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-3", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-4", 0, 1)
  AddGadgetItem(#main_tree, -1, "Normal Item 2", 0, 0)       
  AddGadgetItem(#main_tree, -1, "Node 2", 0, 0)       
  AddGadgetItem(#main_tree, -1, "Sub-Item 2-1", 0, 1)           
  AddGadgetItem(#main_tree, -1, "Sub-Item 2-2", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Node 3", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-item 3-1", 0, 2)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-Item 3-2", 0, 2)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-Item 3-3", 0, 2)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-Item 3-4", 0, 2)
  StringGadget(#String,170,100,100,20,"")

  SetActiveGadget(#main_tree)
  SetGadgetState(#main_tree, 0)
  SetGadgetText(#String, GetGadgetItemText(#main_tree, GetGadgetState(#main_tree)))

  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget     
        Select EventGadget()
          Case #main_tree         
            Select EventType()
              Case #PB_EventType_LeftClick         
                If ItemButtonClicked() = #False
                  Debug "item getroffen"
                  SetGadgetText(#String, GetGadgetItemText(#main_tree, GetGadgetState(#main_tree)))
                Else
                  Debug "knoten getroffen"
                EndIf
            EndSelect
        EndSelect
    EndSelect; WaitWindowEvent()
  ForEver
EndIf 
Wenn ich lange genug auf den Knoten hin- und herklicke, wird ein Klick auf Sub-Node 3 in der 2. Ebene als Klick auf ein Item und nicht als Klick auf einen Knoten erkannt.

Kann das jemand bestätigen ?
Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

hi scholly,

ich klicke auf das +/- von Sub-Node 3 und der debugger gibt immer nur "knoten getroffen" aus, nach ca 200 mal klicken hab ich die lust verloren ;)

mfG
tobe
PureBasic 4.40 (Windows - x86)
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

Beitrag von scholly »

Danke, tobe...

Ich hab grad extra nochmal den Code von 26 Jan 2008 0:06:24 per Cut und Paste benutzt und wieder bekomme ich:

Node 1 = knoten getroffen
Node 2 = knoten getroffen

Sub-Node 3 = item getroffen

:freak:
Versteh das wer will, ich nich...
Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

ah, jetzt hab ich es auch grad geschafft,
es tritt bei mir nur auf, wenn das anzeigefenster zu klein wird und die balken an den rändern eingeblendet werden.
vorher hatte ich node1 immer geschlossen, da wurde nix verschoben.
warscheinlich wird der TVM_HITTEST zu spät ausgeführt und erkennt dadurch das nur das "Sub-Sub-Item 3-2" welches durch das fensterverschieben jetzt auch auf der höhe des mauscursors liegt.
mir ist auch aufgefallen wenn ich schnell auf +/- klicke wird nicht jeder klick im debug ausgegeben.
ich würde es mit einem callback probieren, da müsste der hittest vor dem neuzeichnen des fensters durchgehen, glaub ich ;)
PureBasic 4.40 (Windows - x86)
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

Beitrag von scholly »

tobe hat geschrieben:mir ist auch aufgefallen wenn ich schnell auf +/- klicke wird nicht jeder klick im debug ausgegeben.
ich würde es mit einem callback probieren, da müsste der hittest vor dem neuzeichnen des fensters durchgehen, glaub ich ;)
:o hmpf....
For experienced programmers only.
Ma gucken, ob ich Dummy das hinbekomme...
Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

hab dir mal ein kleines beispiel zusammengeschustert ;)

Code: Alles auswählen

#main_win   = 1
#main_tree  = 3

Procedure.l ItemButtonClicked()
  Protected ItemHandle.l
  Protected TVHitTest.TV_HITTESTINFO
  Protected TVItem.TV_ITEM
  TVHitTest\pt\x = WindowMouseX(#main_win) - GadgetX(#main_tree)
  TVHitTest\pt\y = WindowMouseY(#main_win) - GadgetY(#main_tree)
  ItemHandle = SendMessage_(GadgetID(#main_tree), #TVM_HITTEST, 0, @TVHitTest)
  If ItemHandle <> 0
    ProcedureReturn TVHitTest\flags
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure MyWindowCallback(WindowID, message, wParam, lParam)
  Shared HitTest.l
  Result = #PB_ProcessPureBasicEvents
  If message = #WM_NOTIFY
    *nmhdr.NMHDR = lParam
    If *nmhdr\idFrom = #main_tree
      If *nmhdr\code = #NM_CLICK
        HitTest = ItemButtonClicked()
      EndIf
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure


If OpenWindow(#main_win, 50, 50, 355, 250, "TreeGadget", #PB_Window_SystemMenu ) And CreateGadgetList(WindowID(#main_win))
  TreeGadget(#main_tree, 5, 5, 160, 230, #PB_Tree_AlwaysShowSelection )
  AddGadgetItem(#main_tree, -1, "Normal Item 1", 0, 0)
  AddGadgetItem(#main_tree, -1, "Node 1", 0, 0)
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-1", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-2", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-3", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Item 1-4", 0, 1)
  AddGadgetItem(#main_tree, -1, "Normal Item 2", 0, 0)
  AddGadgetItem(#main_tree, -1, "Node 2", 0, 0)
  AddGadgetItem(#main_tree, -1, "Sub-Item 2-1", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Item 2-2", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Node 3", 0, 1)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-item 3-1", 0, 2)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-Item 3-2", 0, 2)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-Item 3-3", 0, 2)
  AddGadgetItem(#main_tree, -1, "Sub-Sub-Item 3-4", 0, 2)
  StringGadget(#String,170,100,100,20,"")
  SetActiveGadget(#main_tree)
  SetGadgetState(#main_tree, 0)
  SetGadgetText(#String, GetGadgetItemText(#main_tree, GetGadgetState(#main_tree)))
  SetWindowCallback(@MyWindowCallback())
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #main_tree
            Select EventType()
              Case #PB_EventType_LeftClick
                Select HitTest
                  Case 0
                    Debug "voll vorbei geklickt"
                  Case #TVHT_ONITEMLABEL
                    Debug "itemtext geklickt"
                    SetGadgetText(#String, GetGadgetItemText(#main_tree, GetGadgetState(#main_tree)))
                  Case #TVHT_ONITEMBUTTON
                    Debug "knoten getroffen"
                  Default
                    Debug "vorbei geklickt"
                EndSelect
            EndSelect
        EndSelect
    EndSelect; WaitWindowEvent()
  ForEver
EndIf
PureBasic 4.40 (Windows - x86)
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

Beitrag von scholly »

Habs mal vor dem ZuBettGehen getestet...gääähhhn....
Scheint immer noch Klicks zu verlieren.
Montag ist auch noch ein Tag, dann guck ichs mir genauer an...

Danke schonma...
Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Antworten