WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Dialog Editor version 6.X
plus
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Recursive Treeview UDFs

Keywords: 

This is a set of udfs to create and handle a treeview inside a dialog. The script contains the udfs and an example.
;TreeView Control
;Guido 12/02
;Reference: http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/treeview/reflist.asp

;TREE VIEW API CONSTANTS
;Styles
TVS_HASBUTTONS=1
TVS_HASLINES=2 
TVS_LINESATROOT=4
TVS_SHOWSELALWAYS=32

TVI_FIRST=-65535
TVI_LAST=-65534
TVI_ROOT=-65536
TVI_SORT=-65533

;--------------------------------------------------------------------------------;
;TreeCreate : Creates a treeview control.                                        ;
;--------------------------------------------------------------------------------;
;x      : pixels from left                                                       ;
;y      : pixels from top                                                        ;
;w      : width in pixels                                                        ;
;h      : height in pixels                                                       ;
;style  : style flags , see API constants                                        ;
;handle : dialog handle returned by the dialog procedure                         ;
;--------------------------------------------------------------------------------;
;Returns: treeview handle if succesful , 0 otherwise                             ;
;--------------------------------------------------------------------------------;
;API EXStyle : WS_EX_CLIENTEDGE                                                  ;
;    Style   : WS_CHILD|WS_VISIBLE                                               ;
;--------------------------------------------------------------------------------;
#definefunction TreeCreate(x,y,w,h,style,handle)
user32=strcat(dirwindows(1),"user32.dll")
hinst=dllhinst("")
return dllcall(user32,long:"CreateWindowExA",long:512,lpstr:"SysTreeView32",lpstr:"",long:1073741824|268435456|style,long:x,long:y,long:w,long:h,long:handle,long:0,long:hinst,long:0)
#endfunction

;--------------------------------------------------------------------------------;
;TreeDestroy : Destroys a treeview control.                                      ;
;--------------------------------------------------------------------------------;                                      ;
;htree       : treeview handle returned by TreeCreate()                          ;
;--------------------------------------------------------------------------------;
;Returns: 0                                                                      ;
;--------------------------------------------------------------------------------;
#definefunction TreeDestroy(htree)
user32=StrCat(DirWindows(1),"user32.dll")
DllCall(user32,long:"DestroyWindow",long:htree)
return 0
#endfunction

;--------------------------------------------------------------------------------;
;TreeInsertItem : Inserts an item in a treeview control.                         ;
;--------------------------------------------------------------------------------;
;htree       : treeview handle returned by TreeCreate()                          ;
;insertafter : item handle after wich the new item will be inserted , or:        ;
;              TVI_FIRST : Inserts the item at the beginning of the list         ;
;              TVI_LAST  : Inserts the item at the end of the list               ;
;              TVI_ROOT  : Add the item as a root item                           ;
;              TVI_SORT  : Inserts the item into the list in alphabetical order  ;
;text        : item text                                                         ;
;hparent     : handle of parent item , if this member is the TVI_ROOT value or 0 ;
;              the item is inserted at the root of the tree-view control.        ;
;--------------------------------------------------------------------------------;
;Returns     : handle to the new item if successful, or 0 otherwise.             ;
;--------------------------------------------------------------------------------;
#definefunction treeinsertitem(htree,insertafter,text,hparent)
user32=strcat(dirwindows(1),"user32.dll")
TV_FIRST=4352
TVIF_TEXT=1
TVIF_CHILDREN=64
TVIF_HANDLE=16
TVM_INSERTITEM=TV_FIRST+0
TVM_GETNEXTITEM=TV_FIRST+10
TVM_SETITEM=TV_FIRST+13

if hparent
  TVITEM=binaryalloc(40) 
  mask=TVIF_CHILDREN|TVIF_HANDLE
  binarypoke4(TVITEM,0,mask)    ;mask
  binarypoke4(TVITEM,4,hparent) ;hItem
  binarypoke4(TVITEM,32,1)      ;cChildren
  dllcall(user32,long:"SendMessageA",long:htree,long:TVM_SETITEM,long:0,lpbinary:TVITEM)
  binaryfree(TVITEM)
endif

TVINSERTSTRUCT=binaryalloc(48)
binarypoke4(TVINSERTSTRUCT,0,hparent)    ;hParent 
binarypoke4(TVINSERTSTRUCT,4,insertafter);hInsertAfter

binarypoke4(TVINSERTSTRUCT,8,TVIF_TEXT)   ;mask 

textlen=strlen(text)
textbuf=binaryalloc(textlen+1)
binarypokestr(textbuf,0,text)
binarypoke4(TVINSERTSTRUCT,24,intcontrol(42,textbuf,0,0,0)) ;pszText 

binarypoke4(TVINSERTSTRUCT,28,textlen) ;cchTextMax 

ret=dllcall(user32,long:"SendMessageA",long:htree,long:TVM_INSERTITEM,long:0,lpbinary:TVINSERTSTRUCT)
binaryfree(textbuf)
binaryfree(TVINSERTSTRUCT)
return ret
#endfunction

;----------------------------------------------------------------------------------;
;TreeGetCount : Retrieves a count of the items in a tree-view control.             ;
;----------------------------------------------------------------------------------;
;htree : treeview handle                                                           ;
;----------------------------------------------------------------------------------;
;Returns : the count of items                                                      ;
;----------------------------------------------------------------------------------;
#definefunction TreeGetCount(htree)
user32=strcat(dirwindows(1),"user32.dll")
TVM_GETCOUNT=4352+5 
return dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETCOUNT,long:0,long:0) 
#endfunction

;------------------------------------------------------------------------------;
;TreeDeleteItem : Removes an item(or all) from the tree view.                  ;
;------------------------------------------------------------------------------;
;htree : treeview handle                                                       ;
;hitem : handle to the item to delete. If hitem is set to TVI_ROOT all items   ;
;        are deleted                                                           ;
;------------------------------------------------------------------------------;
;Returns: TRUE if successful, or FALSE otherwise.                              ;
;------------------------------------------------------------------------------;
#definefunction TreeDeleteItem(htree,hitem)
user32=strcat(dirwindows(1),"user32.dll")
TVM_DELETEITEM=4352+1
return dllcall(user32,long:"SendMessageA",long:htree,long:TVM_DELETEITEM,long:0,long:hitem)
#endfunction 

;------------------------------------------------------------------------------;
;TreeSetItemText : Changes an item text.                                       ;
;------------------------------------------------------------------------------;
;htree : treeview handle                                                       ;
;hitem : handle of item to change                                              ;
;text  : item text                                                             ;
;------------------------------------------------------------------------------;
;Returns : TRUE if successful, or FALSE otherwise                              ;
;------------------------------------------------------------------------------;
#definefunction TreeSetItemText(htree,hitem,text)
user32=strcat(dirwindows(1),"user32.dll")
TVIF_TEXT=1
TVIF_HANDLE=16
TVM_SETITEM=4352+13

TVITEM=binaryalloc(40) 
mask=TVIF_TEXT|TVIF_HANDLE
binarypoke4(TVITEM,0,mask) ;mask
binarypoke4(TVITEM,4,hitem);hItem

txtlen=strlen(text)
textbuf=binaryalloc(txtlen+1)
binarypokestr(textbuf,0,text)
binarypoke4(TVITEM,16,intcontrol(42,textbuf,0,0,0)) ;pszText
binarypoke4(TVITEM,20,txtlen) ;cchTextMax

ret=dllcall(user32,long:"SendMessageA",long:htree,long:TVM_SETITEM,long:0,lpbinary:TVITEM)
binaryfree(TVITEM)
binaryfree(textbuf)
return ret
#endfunction

;------------------------------------------------------------------------------;
;TreeGetSelectedItem : Retrieves the selected item text.                       ;
;------------------------------------------------------------------------------;
;htree : treeview handle                                                       ;
;------------------------------------------------------------------------------;
;Returns : Selected item. If the item is a child item returns a tab delimited  ;
;          list representing the item hierarchy.                               ;
;Note    : The max item text is set to 500 , change it for bigger item text.   ;
;------------------------------------------------------------------------------;
#definefunction TreeGetSelectedItem(htree)
user32=strcat(dirwindows(1),"user32.dll")
TVM_GETNEXTITEM=4352+10
TVM_GETITEM=4352+12
TVGN_CARET=9
TVGN_PARENT=3
TVIF_HANDLE=16
TVIF_TEXT=1

MAXTEXT=500 ;change this for bigger text
hitem=dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETNEXTITEM,long:TVGN_CARET,long:0) 
if hitem
  TVITEM=binaryalloc(40) 
  mask=TVIF_TEXT|TVIF_HANDLE
  binarypoke4(TVITEM,0,mask) ;mask
  binarypoke4(TVITEM,4,hitem);hItem

  bufsize=MAXTEXT+1
  textbuf=binaryalloc(bufsize)
  binarypoke4(TVITEM,16,intcontrol(42,textbuf,0,0,0)) ;pszText
  binarypoke4(TVITEM,20,MAXTEXT) ;cchTextMax

  dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETITEM,long:0,lpbinary:TVITEM) 
  binaryeodset(textbuf,bufsize)

  item=binarypeekstr(textbuf,0,bufsize) ;selected item
  
  ;search for parent items
  while hitem !=0
    hitem=dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETNEXTITEM,long:TVGN_PARENT,long:hitem) 
    if hitem
      binarypoke4(TVITEM,4,hitem) ;hItem
      dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETITEM,long:0,lpbinary:TVITEM) 
      item=iteminsert(binarypeekstr(textbuf,0,bufsize),0,item,@tab)
    endif
  endwhile

  binaryfree(TVITEM)
  binaryfree(textbuf)
  return item
else
  return ""
endif
#endfunction


;------------------------------------------------------------------------------;
;TEST                                                                          ;
;------------------------------------------------------------------------------;
#definesubroutine dlgproc(handle,msg,id,p4,p5)
select msg
  case 0 ;Init
    DialogProcOptions(handle,2,1) ;BUTTONS
    
    ;create treeview
    htree=TreeCreate(0,0,200,200,TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS,handle)
    
    ;root item
    TreeInsertItem(htree,0,"hello",0)
    
    ;open node 1
    hparent1=TreeInsertItem(htree,TVI_LAST,"world",0)
    TreeInsertItem(htree,TVI_LAST,"world1",hparent1) ;insert in node 1
    
    ;open node 2
    hparent2=TreeInsertItem(htree,TVI_LAST,"world2",hparent1)
    TreeInsertItem(htree,TVI_LAST,"world3",hparent2) ;insert in node 2

    ;insert in node 1
    TreeInsertItem(htree,TVI_LAST,"world4",hparent1)

    ;root item
    TreeInsertItem(htree,0,"hello1",0)

  case 2 ;Button pushed
    select id
      case 1 ;Ok get item
        item=TreeGetSelectedItem(htree)
        message("",item)
        return -2

      case 0 ;exit
        return -1
    endselect
endselect
return -1
#endsubroutine


MyDialogFormat=`WWWDLGED,6.1`

MyDialogCaption=`Tree Control`
MyDialogX=-1
MyDialogY=-1
MyDialogWidth=122
MyDialogHeight=136
MyDialogNumControls=002
MyDialogProcedure=`dlgproc`
MyDialogFont=`DEFAULT`
MyDialogTextColor=`DEFAULT`
MyDialogBackground=`DEFAULT,DEFAULT`

MyDialog001=`009,111,036,012,PUSHBUTTON,DEFAULT,"OK",1,1,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
MyDialog002=`071,111,036,012,PUSHBUTTON,DEFAULT,"Cancel",0,2,DEFAULT,DEFAULT,DEFAULT,DEFAULT`

ButtonPushed=Dialog("MyDialog")


TreeGetItemHandle(htree,index) : returns the item handle of the specified item.

This is a complex function , there are 2 nested functions, one using recursion. I tried to make this function as fast as possible.

Additional Functions:

TreeGetItemText(htree,hitem) : retrieves the text of the specified item.

These functions can be used by the previous ones.

TreeGetItemHandle() is very useful because you can manipulate any item by its position in the tree, you can pass the returned item handle to the rest of functions.

;TreeView functions
;Guido 12/02

;-------------------------------------------------------------------------------;
;TreeGetItems : Function used by TreeGetItemHandle()                            ;
;-------------------------------------------------------------------------------;
#definefunction TreeGetItems(htree,hitem,index,TVITEM,user32)
;start search from root
if hitem==0 
  hitem=dllcall(user32,long:"SendMessageA",long:htree,long:4362,long:0,long:0) ;TVM_GETNEXTITEM TVGN_ROOT
  if hitem 
    if BinaryIncr4(TVITEM,40)==index 
      binarypoke4(TVITEM,44,hitem)
      return
    endif
  endif
endif

while hitem !=0
  
  binarypoke4(TVITEM,4,hitem) ;hItem

  dllcall(user32,long:"SendMessageA",long:htree,long:4364,long:0,lpbinary:TVITEM) ;TVM_GETITEM

  ;Check whether we have child items
  if binarypeek4(TVITEM,32) ;cChildren

    ;Recursively traverse child items
    hItemChild=dllcall(user32,long:"SendMessageA",long:htree,long:4362,long:4,long:hitem) ;TVM_GETNEXTITEM TVGN_CHILD

    if hItemChild
      if BinaryIncr4(TVITEM,40)==index 
        binarypoke4(TVITEM,44,hItemChild)
        return
      endif
      TreeGetItems(htree,hItemChild,index,TVITEM,user32)
    endif

  endif

  ;Go to next sibling item
  hitem=dllcall(user32,long:"SendMessageA",long:htree,long:4362,long:1,long:hitem) ;TVM_GETNEXTITEM TVGN_NEXT
  if hitem 
    if BinaryIncr4(TVITEM,40)==index 
      binarypoke4(TVITEM,44,hitem)
      return
    endif
  endif
endwhile
#endfunction

;-----------------------------------------------------------------------------;
;TreeGetItemHandle : Retrieves an item handle.                                ;
;-----------------------------------------------------------------------------;
;htree : treeview handle                                                      ;
;index : 1 based index(position) of item to retrieve                          ;
;-----------------------------------------------------------------------------;
;Returns : item handle if succesful , 0 otherwise                             ;
;-----------------------------------------------------------------------------;
#definefunction TreeGetItemHandle(htree,index)
user32=dllload(strcat(dirwindows(1),"user32.dll"))
TVITEM=binaryalloc(48) ;TVITEM(40) + counter(4) + hitem(4)
binarypoke4(TVITEM,0,64|16) ;mask TVIF_CHILDREN|TVIF_HANDLE
TreeGetItems(htree,0,index,TVITEM,user32)
hitem=binarypeek4(TVITEM,44)
binaryfree(TVITEM)
dllfree(user32)
return hitem
#endfunction

;------------------------------------------------------------------------------;
;TreeGetItemText : Retrieves an item text.                                     ;
;------------------------------------------------------------------------------;
;htree : treeview handle                                                       ;
;hitem : item handle                                                           ;
;------------------------------------------------------------------------------;
;Returns : Item text. If the item is a child item returns a tab delimited list ;
;          representing the item hierarchy.                                    ;
;Note    : The max item text is set to 500 , change it for bigger text.        ;
;------------------------------------------------------------------------------;
#definefunction TreeGetItemText(htree,hitem)
user32=strcat(dirwindows(1),"user32.dll")
TVIF_TEXT=1
TVIF_HANDLE=16
TVGN_PARENT=3
TVM_GETNEXTITEM=4352+10
TVM_GETITEM=4352+12

MAXTEXT=500 ;change this to retrieve bigger text

TVITEM=binaryalloc(40) 
mask=TVIF_TEXT|TVIF_HANDLE
binarypoke4(TVITEM,0,mask) ;mask
binarypoke4(TVITEM,4,hitem);hItem

bufsize=MAXTEXT+1
textbuf=binaryalloc(bufsize)
binarypoke4(TVITEM,16,intcontrol(42,textbuf,0,0,0)) ;pszText
binarypoke4(TVITEM,20,MAXTEXT) ;cchTextMax

dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETITEM,long:0,lpbinary:TVITEM)
binaryeodset(textbuf,bufsize)
item=binarypeekstr(textbuf,0,bufsize)

;search for parent items
while hitem !=0
  hitem=dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETNEXTITEM,long:TVGN_PARENT,long:hitem) 
  if hitem
    binarypoke4(TVITEM,4,hitem) ;hItem
    dllcall(user32,long:"SendMessageA",long:htree,long:TVM_GETITEM,long:0,lpbinary:TVITEM) 
    item=iteminsert(binarypeekstr(textbuf,0,bufsize),0,item,@tab)
  endif
endwhile

binaryfree(TVITEM)
binaryfree(textbuf)
return item
#endfunction

Article ID:   W15481
File Created: 2004:08:30:07:54:10
Last Updated: 2004:08:30:07:54:10