Jetzt gibt es von mir eine etwas leichtere Kost. Die meisten Librarys zum TreeView-Gadget bieten zwar nette Erweiterungen, sind allerdings auch nicht auf Kompatibilität mit den Purebasic-Item-Funktionen ausgelegt.
Wenn mittels AdvTree_Create ein TreeView Gadget erstellt wird, dann wird zunächst einmal ein Original-PureBasic-TreeView-Gadget erstellt. So wird auch die Kompatibilität der Events des Gadgets sichergestellt.
AdvTree_Create liefert allerdings nicht die Identifikation des PureBasic-Gadgets zurück, sondern dessen hWnd-ID. Denn so kann man diese Library ganz nach seinen Wünschen erweitern: zum Beispiel mit einen Effekt aus einen VisualBasic-Code schnipsel, welches natürlich auf die WinAPI zurückgreift.
Jetzt stellen sich sicherlich einige wieder die Frage: "Warum hat das aber bisher noch nie jemand so Realisiert?". Wobei diese Frage nur Gegenfragen aufwirft: "Wie willst Du an die PureBasic-ID des Gadgets kommen um z.B. das normale AddGadgetItem anwenden zu können?" oder auch "Wie willst du den Memory-Leak beseitigen, wenn Du die IDs mit einer Linked-List speichern würdest?"
Die Antworten würden wie folgt lauten:
Wie willst Du an die PureBasic-ID des Gadgets kommen um z.B. das normale AddGadgetItem anwenden zu können?
Ich speichere die ID mit dem hWnd des Gadgets in einer Linked-List und biete die Funktion AdvTree_GetGadget an. Wer hat diese Antwort erahnt?

Wie willst du den Memory-Leak beseitigen, wenn Du die IDs mit einer Linked-List speichern würdest?
Der Memory-Leak, welches entsteht wenn das Programm abrupt beendet wird, ist nicht Kritisch anzusehen, in Anbetracht der Vorteile die man hat. Zumal der größte Speicherplatz mittlerweile 2 Gigabyte misst.
Ich schätze da macht es nicht viel aus wenn nach dem Beenden mal 8 Bytes von solch einem Gadget noch Reserviert bleiben.
Was anderes wäre es, wenn jetzt auf einmal über 50.000 TreeView-Gadgets erstellt werden würden. Aber mal ernsthaft, selbst Windows schafft nur 2550 (255 * 10) Gadgets gleichzeitig auf dem Bildschirm darzustellen.
Code: Alles auswählen
; AdvancedTreeView_Sample.pb V1.0
; by ShadowTurtle @ Sonntag, 08. Juli 2007
; Wenn dieses Beispiel gestartet wurde, dann wird bei einen
; Auswahl eines Items die entsprechenden Untereinträge im
; ersten Item (oben im Gadget/Fenster) dargestellt.
IncludeFile("AdvancedTreeView.pb")
#TreeView = 1
If OpenWindow(0, 100, 100, 500, 500, "PureBasic Window")
If CreateGadgetList(WindowID(0))
MyTree = AdvTree_Create(#TreeView, 5, 5, 490, 490)
TextInfo = AdvTree_AddItem( MyTree, "Click on item", 0)
WummB = AdvTree_AddItem( MyTree, "My item " + Str(I), 0)
MyItemA = AdvTree_AddItem( MyTree, "My item A", 0, WummB)
MyItemC = AdvTree_AddItem( MyTree, "My item C", 0, MyItemA )
MyItemB = AdvTree_AddItem( MyTree, "My item B", 0, MyItemA )
MyItemD = AdvTree_AddItem( MyTree, "My item D", 0, MyItemB )
For I = 1 To 4
Wumm = AdvTree_AddItem( MyTree, "My item " + Str(I), 0)
MyItemA = AdvTree_AddItem( MyTree, "My item A", 0, Wumm)
MyItemC = AdvTree_AddItem( MyTree, "My item C", 0, MyItemA )
MyItemB = AdvTree_AddItem( MyTree, "My item B", 0, MyItemA )
MyItemD = AdvTree_AddItem( MyTree, "My item D", 0, MyItemB )
Next
EndIf
AdvTree_SortNode( MyTree, 0, #True )
Repeat
Event = WaitWindowEvent()
WindowID = EventWindow()
GadgetID = EventGadget()
EventType = EventType()
If Event = #PB_Event_Gadget
If GadgetID = #TreeView
SelectedItem = AdvTree_GetSelectedItem(MyTree)
ItemText.s = AdvTree_GetItemText( MyTree, SelectedItem )
SubItems_PrintList.s = ItemText.s + " child's:"
WorkItem.l = AdvTree_GetItems( MyTree, SelectedItem )
Repeat
SubItems_PrintList.s = SubItems_PrintList.s + " " + AdvTree_GetItemText( MyTree, WorkItem.l )
WorkItem.l = AdvTree_GetNextItem( MyTree, WorkItem.l )
Until (WorkItem.l = #Null)
AdvTree_SetItemText( MyTree, TextInfo, SubItems_PrintList.s)
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
Code: Alles auswählen
; AdvancedTreeView.pb V1.0
; by ShadowTurtle @ Sonntag, 08. Juli 2007
; Die meisten Librarys zum TreeView-Gadget bieten zwar nette Erweiterungen,
; sind allerdings auch nicht auf Kompatibilität mit den Purebasic-Item-
; Funktionen ausgelegt.
;
; Wenn mittels AdvTree_Create ein TreeView Gadget erstellt wird,
; dann wird zunächst einmal ein Original-PureBasic-TreeView-Gadget
; erstellt. So wird auch die Kompatibilität der Events des Gadgets
; sichergestellt.
;
; AdvTree_Create liefert allerdings nicht die Identifikation des
; PureBasic-Gadgets zurück, sondern dessen hWnd-ID. Denn so kann man
; diese Library ganz nach seinen Wünschen erweitern: zum Beispiel mit
; einen Effekt aus einen VisualBasic-Code schnipsel, welches natürlich auf
; die WinAPI zurückgreift.
;
; Jetzt stellen sich sicherlich einige wieder die Frage: "Warum hat das
; aber bisher noch nie jemand so Realisiert?". Wobei diese Frage nur
; Gegenfragen aufwirft: "Wie willst Du an die PureBasic-ID des Gadgets
; kommen um z.B. das normale AddGadgetItem anwenden zu können?" oder auch
; "Wie willst du den Memory-Leak beseitigen, wenn Du die IDs mit einer
; Linked-List speichern würdest?"
;
; Die Antworten würden wie folgt lauten:
; "Wie willst Du an die PureBasic-ID des Gadgets kommen um z.B. das
; normale AddGadgetItem anwenden zu können?"
; Ich speichere die ID mit dem hWnd des Gadgets in einer Linked-List und
; biete die Funktion AdvTree_GetGadget an.
;
; "Wie willst du den Memory-Leak beseitigen, wenn Du die IDs mit einer
; Linked-List speichern würdest?"
; Der Memory-Leak, welches entsteht wenn das Programm abrupt beendet
; wird, ist nicht Kritisch anzusehen, in Anbetracht der Vorteile die man
; hat. Zumal der größte Speicherplatz mittlerweile 2 Gigabyte misst.
;
; Ich schätze da macht es nicht viel aus wenn nach dem Beenden mal 8 Bytes
; von solch einem Gadget noch Reserviert bleiben.
;
; Was anderes wäre es, wenn jetzt auf einmal über 50.000 TreeView-Gadgets
; erstellt werden würden. Aber mal ernsthaft, selbst Windows schafft nur
; 2550 (255 * 10) Gadgets gleichzeitig auf dem Bildschirm darzustellen.
Structure AdvTree_TVITEM
mask.l
hItem.l
state.l
stateMask.l
pszText.l
cchTextMax.l
iImage.l
iSelectedImage.l
cChildren.l
lParam.l
EndStructure
Structure AdvTree_TVINSERTSTRUCT
hParent.l
hInsertAfter.l
item.AdvTree_TVITEM
EndStructure
Structure AdvTreeItem_Struct
item.l
itemData.l
EndStructure
Structure AdvTreeGadget
hwnd.l
PureGadget.l
*NextGadget.AdvTreeGadget
EndStructure
Global *AdvTreeLastGadget.AdvTreeGadget
*AdvTreeLastGadget = 0
Procedure.l AdvTree_GetGadget(hwnd.l)
GetBackPureGadget.l = -1
*AdvSTG = *AdvTreeLastGadget
While( *AdvSTG )
*I_AdvSTG.AdvTreeGadget = *AdvSTG
If hwnd.l = *I_AdvSTG\hwnd
GetBackPureGadget.l = *I_AdvSTG\PureGadget
;Break
EndIf
*AdvSTG = *I_AdvSTG\NextGadget
Wend
ProcedureReturn( GetBackPureGadget.l )
EndProcedure
Procedure.l AdvTree_Create( Gadget.l, x.l, y.l, width.l, height.l, flags.l = #PB_Explorer_AlwaysShowSelection )
If Gadget.l = #PB_Any
Gadget.l = TreeGadget( #PB_Any, x.l, y.l, width.l, height.l, flags.l)
Else
TreeGadget( Gadget.l, x.l, y.l, width.l, height.l, flags.l)
EndIf
*AdvTG.AdvTreeGadget = AllocateMemory(SizeOf(AdvTreeGadget))
*AdvTG\hwnd = GadgetID( Gadget )
*AdvTG\PureGadget = Gadget.l
*AdvTG\NextGadget = *AdvTreeLastGadget
*AdvTreeLastGadget = *AdvTG
AddGadgetItem( Gadget.l, 0, "temp")
RemoveGadgetItem( Gadget.l, 0)
SetFocus_( Gadget )
ProcedureReturn GadgetID( Gadget )
EndProcedure
Procedure AdvTree_SetFocus( Gadget )
SetFocus_( Gadget )
EndProcedure
Procedure AdvTree_Lock( Gadget )
SendMessage_(Gadget, #WM_SETREDRAW, #False, 0)
EndProcedure
Procedure AdvTree_Unlock( Gadget )
SendMessage_(Gadget, #WM_SETREDRAW, #True, 0)
EndProcedure
Procedure.l AdvTree_AddItem( Gadget, text.s, hImg.l, parent.l = 0 )
If ( parent.l = 0 )
parent.l = #TVGN_ROOT
EndIf
lpis.AdvTree_TVINSERTSTRUCT
lpis\hParent = parent
lpis\hInsertAfter = #TVI_LAST ;#TVI_SORT
lpis\item\iImage = 0
lpis\item\iSelectedImage = 0
lpis\item\mask = #TVIF_TEXT
lpis\item\pszText = @text
NewItem.l = SendMessage_(Gadget, #TVM_INSERTITEM, 0, @lpis)
ProcedureReturn NewItem
EndProcedure
Procedure.s AdvTree_GetItemText( Gadget, item.l )
text.s = Space(999)
pitem.AdvTree_TVITEM
pitem\mask = #TVIF_TEXT
pitem\hItem = item
pitem\pszText = @text
pitem\cchTextMax = 999
SendMessage_(Gadget, #TVM_GETITEM, 0, @pitem)
ProcedureReturn Trim(PeekS(pitem\pszText))
EndProcedure
Procedure AdvTree_SetItemText( GadGet, Item.l, text.s )
pitem.AdvTree_TVITEM
pitem\mask = #TVIF_TEXT
pitem\hItem = Item
pitem\pszText = @text
pitem\cchTextMax = Len(text)
SendMessage_(GadGet, #TVM_SETITEM, 0, @pitem)
EndProcedure
Procedure AdvTree_GetParentItem( GadGet, Item.l )
Result = SendMessage_( GadGet, #TVM_GETNEXTITEM, #TVGN_PARENT, Item)
If ( Result = #TVGN_ROOT )
ProcedureReturn 0
Else
ProcedureReturn Result
EndIf
EndProcedure
Procedure AdvTree_DeleteItem( GadGet, Item.l )
SendMessage_(GadGet, #TVM_DELETEITEM, 0, Item)
EndProcedure
Procedure AdvTree_SelectItem( GadGet, Item.l )
ProcedureReturn SendMessage_(GadGet, #TVM_SELECTITEM, #TVGN_CARET, Item)
EndProcedure
Procedure.l AdvTree_GetSelectedItem( GadGet )
ProcedureReturn SendMessage_(GadGet, #TVM_GETNEXTITEM, #TVGN_CARET, #Null)
EndProcedure
Procedure AdvTree_ExpandNode( GadGet, Item.l )
SendMessage_( GadGet, #TVM_EXPAND, #TVE_EXPAND, Item)
EndProcedure
Procedure AdvTree_ToggleNode( GadGet, Item.l )
SendMessage_( GadGet, #TVM_EXPAND, #TVE_TOGGLE, Item)
EndProcedure
Procedure AdvTree_CollapseNode( GadGet, Item.l )
SendMessage_( GadGet, #TVM_EXPAND, #TVE_COLLAPSE, Item)
EndProcedure
Procedure.l AdvTree_GetItems( Gadget, item.l = #TVGN_ROOT )
If ( item.l = #TVGN_ROOT )
ProcedureReturn SendMessage_( Gadget, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
Else
ProcedureReturn SendMessage_( Gadget, #TVM_GETNEXTITEM, #TVGN_CHILD, item)
EndIf
EndProcedure
Procedure.l AdvTree_GetNextItem( Gadget, item.l )
ProcedureReturn SendMessage_( Gadget, #TVM_GETNEXTITEM, #TVGN_NEXT, item)
EndProcedure
Procedure AdvTree_SortNode( Gadget, item.l, subnodes.l = #False )
SendMessage_(Gadget, #TVM_SORTCHILDREN, subnodes.l, item)
EndProcedure
Procedure AdvTree_Clear( Gadget )
SendMessage_(Gadget, #TVM_DELETEITEM, 0, #TVGN_ROOT)
EndProcedure
Procedure AdvTree_Destroy( Gadget )
SendMessage_(Gadget, #TVM_DELETEITEM, 0, #TVGN_ROOT)
GetBackPureGadget.l = -1
*AdvLastSTG = 0
*AdvSTG = *AdvTreeLastGadget
While( *AdvSTG )
*I_AdvSTG.AdvTreeGadget = *AdvSTG
If Gadget.l = *I_AdvSTG\hwnd
*I_AdvLastSTG.AdvTreeGadget = *AdvLastSTG
*I_AdvLastSTG\NextGadget = *I_AdvSTG\NextGadget
FreeMemory( *I_AdvSTG )
Break
EndIf
*AdvLastSTG = *I_AdvSTG
*AdvSTG = *I_AdvSTG\NextGadget
Wend
EndProcedure
Procedure.l AdvTree_AddItemB( Gadget, text.s, hImg.l, parent.l = 0)
If ( parent.l = 0 )
ItemWork.l = SendMessage_( Gadget, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
openflag = 0
Else
ItemWork.l = parent.l
openflag = 1
EndIf
lpis.AdvTree_TVINSERTSTRUCT
If openflag = #True
pitem.AdvTree_TVITEM
pitem\mask = #TVIF_CHILDREN | #TVIF_HANDLE
pitem\hItem = ItemWork
pitem\cChildren = 1
SendMessage_(Gadget, #TVM_SETITEM, 0, @pitem)
lpis\hParent = ItemWork
lpis\hInsertAfter = ItemWork
Else
lpis\hParent = SendMessage_(Gadget, #TVM_GETNEXTITEM, #TVGN_PARENT, ItemWork)
lpis\hInsertAfter = ItemWork
EndIf
lpis\item\mask = #TVIF_TEXT
lpis\item\cchTextMax = Len(text)
lpis\item\pszText = @text
NewItem.l = SendMessage_(GadGet, #TVM_INSERTITEM, 0, @lpis)
SendMessage_(GadGet, #TVM_ENSUREVISIBLE, 0, NewItem)
ProcedureReturn NewItem.l
EndProcedure