Ca peut être utile si l'un de vos programmes nécessite une gestion de liste hiérarchique par l'utilisateur. Personnellement, je vais m'en servir pour permettre aux utilisateur de DropUpLoad d'organiser et de gérer la liste des serveurs FTP. Ca pourrait servir à gérer une liste de raccourcis, une liste de fichiers, etc.
Si vous le testez, merci de me tenir au courant des résultats

Code : Tout sélectionner
; Drag'nDrop manual sort for TreeGadget
; By Zapman
;
; This demo code shows how to implemente a drag'n drop ability for TreeGadget
; in order to allow the user to sort manually the gadget content by draging
; it elements.
;
Procedure GetFolderIconHandle()
*sfi.SHFILEINFO = AllocateMemory(SizeOf(SHFILEINFO))
If SHGetFileInfo_("aa.txt",#FILE_ATTRIBUTE_DIRECTORY,*sfi, SizeOf(SHFILEINFO), #SHGFI_ICON| #SHGFI_SMALLICON | #SHGFI_USEFILEATTRIBUTES)
hFolderIcon = *sfi\hIcon
EndIf
FreeMemory(*sfi)
ProcedureReturn hFolderIcon
EndProcedure
Procedure GetTreeItemIndexFromHandle(IHandle,TreeGadgetID)
; By Timo 'fr34k' Harter and Zapman
dItem = 0
hItem = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
While IHandle And hItem And hItem <> IHandle
hItem2 = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_CHILD, hItem)
Repeat
If hItem2 = #Null: hItem2 = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_NEXT, hItem): EndIf
If hItem2 = #Null: hItem = SendMessage_(TreeGadgetID, #TVM_GETNEXTITEM, #TVGN_PARENT, hItem): EndIf
Until hItem2 <> #Null
hItem = hItem2
dItem + 1
Wend
ProcedureReturn dItem
EndProcedure
;
Procedure HighLightTreeItem(TreeGadgetID,hItem,HighLight)
; By Timo 'fr34k' Harter and Zapman
If HighLight : HighLight = #TVIS_DROPHILITED : EndIf ; to be sure that te right value is used
; We'll send a #TVM_SETITEM message. We only need to change the
; item state, so #TVIF_STATE is enough for the mask.
pitem.TV_ITEM
pitem\mask = #TVIF_STATE
pitem\hItem = hItem
; 'stateMask' determines, what will be changed, and 'state' sets the actual value,
; so here, we set the TVIS_DROPHILITED state flag to HighLight.
pitem\state = HighLight
pitem\stateMask = #TVIS_DROPHILITED
Result = SendMessage_(TreeGadgetID, #TVM_SETITEM, 0, @pitem)
; a redraw is neccesary here to avoid problems.
RedrawWindow_(TreeGadgetID, 0, 0, #RDW_UPDATENOW)
ProcedureReturn Result
EndProcedure
;
Procedure GetTreeItemIconIndex(TreeGadget,hitem)
; by Zapman
tvitem.TV_ITEM\mask=#TVIF_IMAGE
tvitem\hitem=hitem
If SendMessage_(GadgetID(TreeGadget), #TVM_GETITEM,0,@tvitem) ; get the icon index from the item
ProcedureReturn tvitem\iImage
Else
ProcedureReturn -1
EndIf
EndProcedure
;
Procedure SetTreeItemIconIndex(TreeGadget,hitem,iconeIndex)
; by Zapman
tvitem.TV_ITEM\mask=#TVIF_IMAGE|#TVIF_SELECTEDIMAGE
tvitem\hitem=hitem
tvitem\iImage= iconeIndex
tvitem\iSelectedImage = iconeIndex
result = SendMessage_(GadgetID(TreeGadget), #TVM_SETITEM,0,@tvitem) ; set the icon index from the item
ProcedureReturn result
EndProcedure
;
Procedure InvertTreeGadgetItems(TreeGadget,p1,p2)
t1$=GetGadgetItemText(TreeGadget,p1)
t2$=GetGadgetItemText(TreeGadget,p2)
SetGadgetItemText(TreeGadget,p1,t2$)
SetGadgetItemText(TreeGadget,p2,t1$)
iconindex1 = GetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p1)); get the icon from the first item
iconindex2 = GetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p2)); get the icon from the second item
SetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p1),iconindex2); set the icon for the first item
SetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,p2),iconindex1); set the icon for the second item
EndProcedure
;
;
Global DD_TreeGadget
Procedure DD_TreeCallback(Window, Message, wParam, lParam)
; By Timo 'fr34k' Harter for ListView Gadget
; Adapted to TreeView by Zapman
Shared OldTreeItem,TreeIsDraging,DraggedItemsList$,DragImageList
result = #PB_ProcessPureBasicEvents
; The first message we need is #TVN_BEGINDRAG. This is a so called
; Notification message. This means, that you don't get a message called
; #TVN_BEGINDRAG, but you get a #WM_NOTIFY message, with further information,
; that tells you, that it is #TVN_BEGINDRAG
If Message = #WM_NOTIFY
; The lparam paramenter contains a pointer to a NMHDR structure. There is
; the information about the Message
*nmhdr.NMHDR = lParam
; The 'hwndfrom' member tells you, which Gadget actually sent the message
; This must be always checked to be sure, it is the right gadget.
; We allow only our own Gadgets:
If *nmhdr\hwndfrom = GadgetID(DD_TreeGadget)
; The 'code' member contains the real message, in our case #TVN_BEGINDRAG
If *nmhdr\code = #TVN_BEGINDRAG
; Ok, for the #TVN_BEGINDRAG notification message, lParam is a pointer to a
; NMTREEVIEW Structure. You might think that this can't be, as lParam allready
; pointed to a NMHDR structure, but this is correct, as NMTREEVIEW has a
; NMHDR structure inside, it only adds more members to it.
*nmv.NMTREEVIEW = lParam
; The 'hItem' member contains the index of the source item, which we will need
; later.
TreeItemSource = *nmv\itemNew\hItem
OldTreeItem = TreeItemSource ; will be used to unhilite the item which was hilited
; By sending a #TVM_CREATEDRAGIMAGE message to the gadget, we create an ImageList
; that contains just one image, the drag&drop image. We will need the Imagelist WinAPI
; commands to work with that one later.
HighLightTreeItem(GadgetID(DD_TreeGadget),TreeItemSource,0)
HighLightTreeItem(GadgetID(DD_TreeGadget),GadgetItemID(DD_TreeGadget,GetGadgetState(DD_TreeGadget)),0)
DragImageList = SendMessage_(GadgetID(DD_TreeGadget), #TVM_CREATEDRAGIMAGE, 0,TreeItemSource)
;
; If the user is draging a node,
; we'll modify the image by adding all the items contained by the node
LImage = 400
HImage = 600
Pb_Image = CreateImage(#PB_Any,LImage,HImage)
Font1 = LoadFont(#PB_Any, "Tahoma" , 8)
StartDrawing(ImageOutput(Pb_Image))
DrawingFont(FontID(Font1))
Box(0, 0, LImage, HImage ,RGB(255,255,255))
ItemIndex = GetTreeItemIndexFromHandle(TreeItemSource,GadgetID(DD_TreeGadget))
ItemText$ = GetGadgetItemText(DD_TreeGadget,ItemIndex,0)
DraggedItemsList$ = Str(ItemIndex)+Chr(13)+ReplaceString(ItemText$,Chr(13),"")+Chr(13)+"0"+Chr(13)
DrawText(0,0,ItemText$,0,RGB(255,255,255))
dep = TextWidth(ItemText$)
posvert=0
hcar = 14
hItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_CHILD, TreeItemSource)
If hItem
level = 1
Repeat
posvert + hcar
ItemIndex = GetTreeItemIndexFromHandle(hItem,GadgetID(DD_TreeGadget))
ItemText$ = GetGadgetItemText(DD_TreeGadget,ItemIndex,0)
DraggedItemsList$ + Str(ItemIndex)+Chr(13)+ReplaceString(ItemText$,Chr(13),"")+Chr(13)+Str(level)+Chr(13)
DrawText(level*20,posvert,ItemText$,0,RGB(255,255,255))
nWidth = TextWidth(ItemText$)+(level*20)
If nWidth>dep ; calculate max text width for our draging image
dep = nWidth
EndIf
hItem2 = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_CHILD, hItem) ; is the next item a child ?
If hItem2
level + 1
hItem = hItem2
Else
hItem2 = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_NEXT, hItem) ; is it a same level item ?
If hItem2
hItem = hItem2
Else
hItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM,#TVGN_PARENT, hItem) ; get the parent of our item
hItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_GETNEXTITEM, #TVGN_NEXT, hItem) ; and go to the next
level - 1
EndIf
EndIf
Until level = 0 Or hItem = 0
EndIf
DraggedItemsList$ + "Store_end" + Chr(13)
StopDrawing()
FreeFont(Font1)
ImageList_SetIconSize_(DragImageList,dep+5,posvert+hcar)
ImageList_AddMasked_(DragImageList,ImageID(Pb_Image),RGB(255,255,255))
FreeImage(Pb_Image)
If DragImageList
; This begins the drag&drop operation by displaying the image
If ImageList_BeginDrag_(DragImageList , 0, 0, 0)
; this command shows or hides the drag&drop image. Or course,
; we want to see it now :)
ImageList_DragShowNolock_(#True)
; this causes windows to send all mouse messages to our window,
; even if the mouse is outside of our window. This is neccesary,
; because we need to detect the mouseup event to abort the
; operation, even if the mouse is outside our window.
SetCapture_(GetParent_(GadgetID(DD_TreeGadget)))
; hide the standard cursor
ShowCursor_(#False)
; When processing the other events, we need to know whether something
; is being draged or not.
TreeIsDraging = #True
EndIf ; check for ImageList_BeginDrag_()
EndIf ; check for DragImageList
EndIf ; check for #TVN_BEGINDRAG
EndIf ; check for right gadget
; The next message we need is #WM_MOUSEMOVE, to update the mouse.
; But only if TreeIsDraging is #TRUE.
ElseIf Message = #WM_MOUSEMOVE And TreeIsDraging
; now we hide the image to avoid redrawn problems.
ImageList_DragShowNolock_(#False)
; the next thing we do is hilighting the target item in the target gadget.
GetWindowRect_(GadgetID(DD_TreeGadget),re.RECT)
GetCursorPos_(pt.POINT)
If PtInRect_(@re, pt\x | (pt\y<<32))
; What we need next is the Item, that is currently under the mouse cursor.
; the #TVM_HITTEST message does that test for us.
; here, we need coordinates relative to the top/left corner of our target
; Gadget, so we substract the Gadget position from our window coordinates
; When #EM_MOUSEMOVE is sent, the lParam parameter contains
; the x coordinate in the low-word and the y coordinate in the high-word, so we
; just use them here:
MouseX = lParam & $FFFF
MouseY = lParam >> 16
hittestinfo.TV_HITTESTINFO
hittestinfo\pt\x = MouseX - GadgetX(DD_TreeGadget)
hittestinfo\pt\y = MouseY - GadgetY(DD_TreeGadget)
; find the item, if none is under the cursor, we get -1, and the next
; SendMessage won't work, and nothing is hilighted.
TargetItem = SendMessage_(GadgetID(DD_TreeGadget), #TVM_HITTEST, 0, @hittestinfo)
If TargetItem<>-1 And TargetItem<>OldTreeItem
If OldTreeItem
HighLightTreeItem(GadgetID(DD_TreeGadget),OldTreeItem,0) ; Unhilighte the precedent hilighted item
EndIf
OldTreeItem = TargetItem
HighLightTreeItem(GadgetID(DD_TreeGadget),OldTreeItem,1)
EndIf
Else ; scroll treegadget if mouse is upper or lower than it
GetWindowRect_(GadgetID(DD_TreeGadget),re.RECT)
GetCursorPos_(@MP.POINT)
If MP\y < re\top
SendMessage_(GadgetID(DD_TreeGadget), #WM_VSCROLL, #SB_LINEUP, 0);
EndIf
If MP\y > re\bottom
SendMessage_(GadgetID(DD_TreeGadget), #WM_VSCROLL, #SB_LINEDOWN, 0);
EndIf
EndIf
; now we can show the drag image again:
ImageList_DragShowNolock_(#True)
; this moves the drag Image.
GetCursorPos_(@MP.Point)
ImageList_DragMove_(MP\x, MP\y-7)
; that's all to do while moving the mouse. Of course, there can be more checks added,
; and for example, a different cursor displayed, if you don't want the source to
; be draged to the current target and so on, but i think this is enough for a basic
; example.
; next is the end of the drag&drop operation... when the user releases the mouse.
ElseIf Message = #WM_LBUTTONUP And TreeIsDraging
; first, we release all we did, to unlock the mouse.
; mouse messages will be sent to other windows again
ReleaseCapture_()
; and drag&drop (remove the image)
ImageList_EndDrag_()
; free the image list
ImageList_Destroy_(DragImageList)
; show cursor again
ShowCursor_(#True)
; no draging in progress now.
TreeIsDraging = #False
; next, we unhilight the last target item
If OldTreeItem
HighLightTreeItem(GadgetID(DD_TreeGadget),OldTreeItem,0)
EndIf
GetWindowRect_(GadgetID(DD_TreeGadget),re.RECT)
GetCursorPos_(pt.POINT)
If PtInRect_(@re, pt\x | (pt\y<<32))
; now, move the items as demanded by the user:
;
; examine items at old positions
;
nbitems = 0
FIndex = -1
ct = 0
Repeat
ct + 1
LValue$ = StringField(DraggedItemsList$,ct,Chr(13))
If LValue$ <> "Store_end"
ItemIndex = Val(LValue$)
If FIndex = -1 : FIndex = ItemIndex: EndIf
ct + 2
nbitems + 1
EndIf
Until LValue$ = "Store_end"
;
; add items at new position
;
nPosition = GetTreeItemIndexFromHandle(OldTreeItem,GadgetID(DD_TreeGadget))+1
If nPosition>FIndex And nPosition<(FIndex+nbitems+1)
Debug "Trying to put a node inside its own content !!!!"
Else
mnPosition = nPosition
nLevel = GetGadgetItemAttribute(DD_TreeGadget,nPosition-1,#PB_Tree_SubLevel)
iconindex = GetTreeItemIconIndex(DD_TreeGadget,GadgetItemID(DD_TreeGadget,nPosition-1))
If iconindex And iconindex<>-1 ; get the icon from the target item
Debug "target is a folder" ; if there is one, we suppose that the item is a folder (a potential node)
nLevel + 1
EndIf
ct = 0
Repeat
ct + 1
LValue$ = StringField(DraggedItemsList$,ct,Chr(13))
If LValue$ <> "Store_end"
ItemIndex = Val(LValue$)
ct + 1
ItemText$ = StringField(DraggedItemsList$,ct,Chr(13))
ct + 1
level = Val(StringField(DraggedItemsList$,ct,Chr(13)))
If FIndex>= mnPosition
ItemIndex + nPosition - mnPosition
EndIf
iconindex = GetTreeItemIconIndex(DD_TreeGadget,GadgetItemID(DD_TreeGadget,ItemIndex)); get the icon from the old item
AddGadgetItem(DD_TreeGadget, nPosition, ItemText$,0,level+nLevel)
SetTreeItemIconIndex(DD_TreeGadget,GadgetItemID(DD_TreeGadget,nPosition),iconindex); set the icon for the new item
nPosition + 1
EndIf
Until LValue$ = "Store_end"
If FIndex>= mnPosition ; position has to be adjusted if items to delete are after added items
FIndex + nbitems
nPosition = mnPosition
Else
nPosition = mnPosition-nbitems
EndIf
RemoveGadgetItem(DD_TreeGadget,FIndex)
SetGadgetState(DD_TreeGadget,nPosition)
SetActiveGadget(DD_TreeGadget)
EndIf ; IsMouseOver(GadgetID(DD_TreeGadget))
EndIf ; If Message = #WM_LBUTTONUP And TreeIsDraging
EndIf ; check Message
ProcedureReturn Result
EndProcedure
;
Global hFolderIcon
Procedure Enable_DragnDrop_On_TreeGadget(Window,TreeGadget)
DD_TreeGadget = TreeGadget
hWndTV = GadgetID(TreeGadget)
Style = GetWindowLong_(hWndTV, #GWL_STYLE)
Style = Style & (~#TVS_DISABLEDRAGDROP)
SetWindowLong_(hWndTV, #GWL_STYLE, Style) ; enable drag'n drop for the gadget
;
hFolderIcon = GetFolderIconHandle() ; get a folder icon to use later in our list
;
SendMessage_(hWndTV, #TVM_GETIMAGELIST,#TVSIL_NORMAL,imageList)
If imageList = 0 ; The TreeGadget has no image list!! We need one, so we'll create one.
AddGadgetItem(TreeGadget, -1, "ToDelete", hFolderIcon,0) ; PB will automatically create an image list if we add an item with an icon
RemoveGadgetItem(TreeGadget, CountGadgetItems(TreeGadget)-1) ; OK, we can now delete this item
EndIf
;
SetWindowCallback(@DD_TreeCallback(),Window)
EndProcedure
; Window und Gadget...
winMain = OpenWindow(#PB_Any, 0, 0, 350, 260, "Drag'n Drop sorting with a TreeView", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget = TreeGadget(#PB_Any, 5, 5, 200, 250,#PB_Tree_AlwaysShowSelection)
Enable_DragnDrop_On_TreeGadget(winMain,TreeGadget)
ItemString = StringGadget(#PB_Any,220,5,120,20,"")
TextGadget = TextGadget(#PB_Any, 220, 50, 120, 250,"You can sort this treeview manually by draging items from one position to another one.")
PosVert = 160
BNewFolder = ButtonGadget(#PB_Any,220,PosVert,120,20,"New Folder")
PosVert + 25
BNewItem = ButtonGadget(#PB_Any,220,PosVert,120,20,"New Item")
PosVert + 25
BDelete = ButtonGadget(#PB_Any,220,PosVert,120,20,"Delete")
PosVert + 25
BSort = ButtonGadget(#PB_Any,220,PosVert,120,20,"Alphabetical Sort")
AddGadgetItem(TreeGadget, -1, "Item1"+Chr(13), 0,0)
AddGadgetItem(TreeGadget, -1, "Folder#1", hFolderIcon,0)
AddGadgetItem(TreeGadget, -1, "Item11",0,1)
AddGadgetItem(TreeGadget, -1, "Item12",0,1)
AddGadgetItem(TreeGadget, -1, "Folder#12",hFolderIcon,1)
AddGadgetItem(TreeGadget, -1, "Item121",0,2)
AddGadgetItem(TreeGadget, -1, "Item122",0,2)
AddGadgetItem(TreeGadget, -1, "Folder#2", hFolderIcon,0)
AddGadgetItem(TreeGadget, -1, "Itemz11",0,1)
AddGadgetItem(TreeGadget, -1, "zItem1a",0,1)
For ct = 1 To 20
AddGadgetItem(TreeGadget, -1, "Item"+Str(ct+1),0,0)
Next
SetGadgetState(TreeGadget,0)
SetGadgetText(ItemString,GetGadgetText(TreeGadget))
SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(GetGadgetText(TreeGadget)))
SetActiveGadget(ItemString)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
If EventGadget() = TreeGadget
ItemText$ = GetGadgetItemText(TreeGadget,GetGadgetState(TreeGadget))
SetGadgetText(ItemString,ItemText$)
SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(ItemText$))
EndIf
If EventGadget() = ItemString And EventType() = #PB_EventType_Change
SetGadgetItemText(TreeGadget,GetGadgetState(TreeGadget),GetGadgetText(ItemString))
ElseIf EventGadget() = BNewFolder Or EventGadget() = BNewItem
IIndex = GetGadgetState(TreeGadget)+1
If EventGadget() = BNewFolder
AddGadgetItem(TreeGadget,IIndex,"New folder",hFolderIcon)
Else
AddGadgetItem(TreeGadget,IIndex,"New item")
EndIf
SetGadgetState(TreeGadget,IIndex)
ItemText$ = GetGadgetItemText(TreeGadget,IIndex)
SetGadgetText(ItemString,ItemText$)
SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(ItemText$))
SetActiveGadget(ItemString)
ElseIf EventGadget() = BDelete
IIndex = GetGadgetState(TreeGadget)
RemoveGadgetItem(TreeGadget, IIndex)
SetGadgetState(TreeGadget,IIndex)
SetGadgetText(ItemString,ItemText$)
SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(ItemText$))
SetActiveGadget(TreeGadget)
ElseIf EventGadget() = BSort
; Windows API has a sort function for treeview (#TVM_SORTCHILDREN message)
; but we can't use it because the PureBasic element index is not sorted with the elements.
; So, we recreate a complete sort function for PB treegadget.
lastitem = CountGadgetItems(TreeGadget)-1
maxlevel = 0
For clevel = 0 To maxlevel
For i=0 To lastitem-1
nlevel = GetGadgetItemAttribute(TreeGadget,i,#PB_Tree_SubLevel)
If nlevel>maxlevel : maxlevel = nlevel : EndIf
If nlevel = clevel
min=i
For j=i+1 To lastitem
If GetGadgetItemText(TreeGadget,j)<GetGadgetItemText(TreeGadget,min) And GetGadgetItemAttribute(TreeGadget,j,#PB_Tree_SubLevel)=clevel
min=j
EndIf
If GetGadgetItemAttribute(TreeGadget,j,#PB_Tree_SubLevel)<nlevel
j = lastitem
EndIf
Next
If min<>i
For b = 1 To 2
storeitems$ = ""
If b = 1
posd = i
Else
posd = min
EndIf
; Store the node content
ct = 1
While GetGadgetItemAttribute(TreeGadget,posd+ct,#PB_Tree_SubLevel)>clevel
storeitems$ + GetGadgetItemText(TreeGadget,posd+ct)+Chr(13)+Str(GetGadgetItemAttribute(TreeGadget,posd+ct,#PB_Tree_SubLevel))+Chr(13)+Str(GetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,posd+ct)))+Chr(13)
ct + 1
If b = 1 And min>i
min - 1
EndIf
If b = 2 And i>min
i - 1
EndIf
Wend
If b = 1
storeitems_i$ = storeitems$
Else
storeitems_min$ = storeitems$
EndIf
; Delete the node content
While GetGadgetItemAttribute(TreeGadget,posd+1,#PB_Tree_SubLevel)>clevel
RemoveGadgetItem(TreeGadget,posd+1)
Wend
Next
; recreate the node content at the right place
For b = 1 To 2
If b = 1
posi = min
storeitems$ = storeitems_i$
Else
posi = i
storeitems$ = storeitems_min$
EndIf
ct = 0
Repeat
ct + 1
itemtext$ = StringField(storeitems$,ct,Chr(13))
If itemtext$
ct + 1
level = Val(StringField(storeitems$,ct,Chr(13)))
ct + 1
iconindex = Val(StringField(storeitems$,ct,Chr(13)))
posi + 1
AddGadgetItem(TreeGadget,posi,itemtext$,0,level)
SetTreeItemIconIndex(TreeGadget,GadgetItemID(TreeGadget,posi),iconindex)
If b = 1 And i>min
i + 1
EndIf
If b = 2 And min>i
min + 1
EndIf
EndIf
Until itemtext$ = ""
Next
InvertTreeGadgetItems(TreeGadget,i,min)
EndIf
EndIf
Next
Next
SetGadgetState(TreeGadget,0)
SetGadgetText(ItemString,GetGadgetText(TreeGadget))
SendMessage_(GadgetID(ItemString), #EM_SETSEL, 0, Len(GetGadgetText(TreeGadget)))
SetActiveGadget(ItemString)
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
End
; -------------------------------------------------------------------------