I am curious how you would copy a treeview from one tree to another. Since there was nothing on the board and I needed this, here is what I came up with... anything better?



CopyTree proc uses esi edi ebx SourceTree:DWORD, DestTree:DWORD
LOCAL tvi:TVITEM
LOCAL tvis:TV_INSERTSTRUCT
LOCAL RootText[50]:BYTE
LOCAL ChildText[50]:BYTE
LOCAL hNode:DWORD

GetRoot:
; Get root node handle
push 0
push TVGN_ROOT
push TVM_GETNEXTITEM
push SourceTree
call SendMessage
test eax, eax
jz Done ; Empty tree, leave

mov esi, eax ; esi = node handle
mov edi, eax ; edi = parent node handle

push esi
push TVGN_CHILD
push TVM_GETNEXTITEM
push SourceTree
call SendMessage
mov ebx, eax
test eax, eax
jz DeleteRoot ; No children, delete root and get next root node

; #######################################
; ###### Copy root node
mov tvi._mask, TVIF_TEXT
mov tvi.hItem, esi
mov tvi.cchTextMax, 50
lea ecx, RootText
mov tvi.pszText, ecx
lea eax, tvi
push eax
push 0
push TVM_GETITEM
push SourceTree
call SendMessage ; Get root text

mov tvis.hParent, TVI_ROOT
mov tvis.hInsertAfter, TVI_SORT
mov tvis.item._mask, TVIF_TEXT\
or TVIF_IMAGE\
or TVIF_SELECTEDIMAGE
mov tvis.item.iImage, ICON_FOLDER_CLOSED
mov tvis.item.iSelectedImage, ICON_FOLDER_OPEN
lea eax, RootText
mov tvis.item.pszText, eax
lea ecx, tvis
push ecx
push 0
push TVM_INSERTITEM
push DestTree
call SendMessage
mov hNode, eax

; #######################################
; ###### Copy 1st root child
mov tvi._mask, TVIF_TEXT or TVIF_PARAM
mov tvi.hItem, ebx
mov tvi.cchTextMax, 50
lea ecx, ChildText
mov tvi.pszText, ecx
lea eax, tvi
push eax
push 0
push TVM_GETITEM
push SourceTree
call SendMessage

push hNode
pop tvis.hParent
mov tvis.hInsertAfter, TVI_SORT
mov tvis.item._mask, TVIF_TEXT\
or TVIF_IMAGE\
or TVIF_SELECTEDIMAGE\
or TVIF_PARAM
mov tvis.item.iImage, ICON_ITEM
mov tvis.item.iSelectedImage, ICON_ITEM
lea eax, ChildText
mov tvis.item.pszText, eax
push tvi.lParam
pop tvis.item.lParam
lea ecx, tvis
push ecx
push 0
push TVM_INSERTITEM
push DestTree
call SendMessage

jmp GetRootChild

DeleteRoot:
push esi
push 0
push TVM_DELETEITEM
push hTVConfig
call SendMessage
jmp GetRoot

GetRootChild:
; #######################################
; ###### Loop through each root child and copy info
push ebx
push TVGN_NEXT
push TVM_GETNEXTITEM
push SourceTree
call SendMessage
mov ebx, eax
test eax, eax
jz GetNextParent ; Done with root children, get next parent

mov tvi._mask, TVIF_TEXT or TVIF_PARAM
mov tvi.hItem, ebx
mov tvi.cchTextMax, 50
lea ecx, ChildText
mov tvi.pszText, ecx
lea eax, tvi
push eax
push 0
push TVM_GETITEM
push SourceTree
call SendMessage
push hNode
pop tvis.hParent
mov tvis.hInsertAfter, TVI_SORT
mov tvis.item._mask, TVIF_TEXT\
or TVIF_IMAGE\
or TVIF_SELECTEDIMAGE\
or TVIF_PARAM
mov tvis.item.iImage, ICON_ITEM
mov tvis.item.iSelectedImage, ICON_ITEM
lea eax, ChildText
mov tvis.item.pszText, eax
push tvi.lParam
pop tvis.item.lParam
lea ecx, tvis
push ecx
push 0
push TVM_INSERTITEM
push DestTree
call SendMessage

jmp GetRootChild

GetNextParent:
; #######################################
; ###### Loop through tree and copy each non empty parent and child
push edi
push TVGN_NEXT
push TVM_GETNEXTITEM
push SourceTree
call SendMessage
mov esi, eax
test eax, eax
jz Done

push esi
push TVGN_CHILD
push TVM_GETNEXTITEM
push SourceTree
call SendMessage
mov ebx, eax
test eax, eax
jz DeleteParent

mov tvi._mask, TVIF_TEXT
mov tvi.hItem, esi
mov tvi.cchTextMax, 50
lea ecx, RootText
mov tvi.pszText, ecx
lea eax, tvi
push eax
push 0
push TVM_GETITEM
push SourceTree
call SendMessage

; #######################################
; ###### Copy current parent
mov tvis.hParent, TVI_ROOT
mov tvis.hInsertAfter, TVI_SORT
mov tvis.item._mask, TVIF_TEXT\
or TVIF_IMAGE\
or TVIF_SELECTEDIMAGE
mov tvis.item.iImage, ICON_FOLDER_CLOSED
mov tvis.item.iSelectedImage, ICON_FOLDER_OPEN
lea eax, RootText
mov tvis.item.pszText, eax
lea ecx, tvis
push ecx
push 0
push TVM_INSERTITEM
push DestTree
call SendMessage
mov hNode, eax

mov tvi._mask, TVIF_TEXT or TVIF_PARAM
mov tvi.hItem, ebx
mov tvi.cchTextMax, 50
lea ecx, ChildText
mov tvi.pszText, ecx
lea eax, tvi
push eax
push 0
push TVM_GETITEM
push SourceTree
call SendMessage

; #######################################
; ###### Copy current parents 1st child
push hNode
pop tvis.hParent
mov tvis.hInsertAfter, TVI_SORT
mov tvis.item._mask, TVIF_TEXT\
or TVIF_IMAGE\
or TVIF_SELECTEDIMAGE\
or TVIF_PARAM
mov tvis.item.iImage, ICON_ITEM
mov tvis.item.iSelectedImage, ICON_ITEM
lea eax, ChildText
mov tvis.item.pszText, eax
push tvi.lParam
pop tvis.item.lParam
lea ecx, tvis
push ecx
push 0
push TVM_INSERTITEM
push DestTree
call SendMessage

jmp GetChild

DeleteParent:
push esi
push 0
push TVM_DELETEITEM
push SourceTree
call SendMessage
jmp GetNextParent

GetChild:
; #######################################
; ###### Loop through each child of current parent and copy
push ebx
push TVGN_NEXT
push TVM_GETNEXTITEM
push SourceTree
call SendMessage
mov ebx, eax
test eax, eax
jz NoChildren

mov tvi._mask, TVIF_TEXT or TVIF_PARAM
mov tvi.hItem, ebx
mov tvi.cchTextMax, 50
lea ecx, ChildText
mov tvi.pszText, ecx
lea eax, tvi
push eax
push 0
push TVM_GETITEM
push SourceTree
call SendMessage

push hNode
pop tvis.hParent
mov tvis.hInsertAfter, TVI_SORT
mov tvis.item._mask, TVIF_TEXT\
or TVIF_IMAGE\
or TVIF_SELECTEDIMAGE\
or TVIF_PARAM
mov tvis.item.iImage, ICON_ITEM
mov tvis.item.iSelectedImage, ICON_ITEM
lea eax, ChildText
mov tvis.item.pszText, eax
push tvi.lParam
pop tvis.item.lParam
lea ecx, tvis
push ecx
push 0
push TVM_INSERTITEM
push DestTree
call SendMessage

jmp GetChild

NoChildren:
mov edi, esi
jmp GetNextParent

Done:
ret
CopyTree endp


Usage is simple:


push hTVMain
push hTVConfig
call CopyTree


Seems as if there is a lot of code to do this. But then again, you have to get the root first, check for children, get the first child handle then loop through the other children.... and do the same for each node
Posted on 2003-02-13 21:15:17 by Gunner