Luigi Posted November 28, 2016 Share Posted November 28, 2016 Greetings! I found a great TreeView's example here, and adapt to work with two treeviews. But there are a issue and I have no idea to solve it. Open the example, and drag one item from a treeview to other. Sometimes in treeview origin does not show a item error/graphic error, but most of the time, there are a graphic error, it cannot delete a drag image of treeview. If you drag a item in the same treeview, no error, its work fine. If you drag from one to another, there are error. Somebody can help-me, how fix it? Best regards Luigi The code: expandcollapse popup; https://www.autoitscript.com/forum/topic/56411-treeview-drag-drop-reorder-and-edit-example/ #include-once #include <Array.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <GuiTreeView.au3> ;~ #include <GuiMenu.au3> #include <WinAPI.au3> ;~ #include <SQLite.au3> ;~ #include <SQLite.dll.au3> ;~ #include <File.au3> #include <FontConstants.au3> ;~ #include <GuiListView.au3> ;~ #include <EditConstants.au3> ;~ #include <ListViewConstants.au3> ;~ #include <GuiImageList.au3> ;~ #include <GuiComboBox.au3> ;~ #include <TreeViewConstants.au3> #include <WinAPIvkeysConstants.au3> ;~ #include <GuiCreateEx.au3> Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) Global $TVN_BEGINDRAG Global $TVN_BEGINLABELEDIT Global $TVN_SELCHANGED Global $TVM_EDITLABEL ;Required global constants: Global $bTreeDrag = False, $bTreeEdit = False, $hDragItem, $hTreeDragImage, $fWhere Global $hGui = GUICreate("@Tree", 800, 600, 0, 0) Global $label = GUICtrlCreateLabel("*", 10, 500, 780, 20, $SS_SUNKEN) Global $label2 = GUICtrlCreateLabel("", 10, 530, 780, 20, $SS_SUNKEN) Global Enum $eGID = 0, $eHANDLE, $eFOCUS, $ePARAM, $ePARENT Global $TREE1[6], $TREE2[6] Global $NODES[][5] = [ _ [0] _ ] $TREE1[$eGID] = GUICtrlCreateTreeView(10, 10, 320, 480, $TVS_HASBUTTONS + $TVS_HASLINES + $TVS_LINESATROOT + $TVS_EDITLABELS + $TVS_CHECKBOXES) GUICtrlSetFont($TREE1[$eGID], 12, 400, 0, "Courier New") $TREE1[$eHANDLE] = GUICtrlGetHandle($TREE1[$eGID]) GUICtrlSetState($TREE1[$eGID], $GUI_DROPACCEPTED) $TREE2[$eGID] = GUICtrlCreateTreeView(340, 10, 320, 480, $TVS_HASBUTTONS + $TVS_HASLINES + $TVS_LINESATROOT + $TVS_EDITLABELS + $TVS_CHECKBOXES) GUICtrlSetFont($TREE2[$eGID], 12, 400, 0, "Courier New") $TREE2[$eHANDLE] = GUICtrlGetHandle($TREE2[$eGID]) GUICtrlSetState($TREE2[$eGID], $GUI_DROPACCEPTED) Populate() Func Populate() Local $hItem, $hChild1, $hChild2, $tree_view Local $aCores[] = ["amarelo", "vermelho", "branco", "cinza", "azul", "verde", "laranja", "preto"] Local $aTons[] = ["claro", "médio", "escuro"] Local $aSabores[] = ["doce", "salgado", "azedo"] For $ii = 1 To 2 $tree_view = Eval("TREE" & $ii)[$eGID] _GUICtrlTreeView_BeginUpdate($tree_view) For $jj = 0 To UBound($aCores, 1) - 1 $hItem = _GUICtrlTreeView_Add($tree_view, 0, $aCores[$jj]) For $kk = 0 To UBound($aTons, 1) - 1 $hChild1 = _GUICtrlTreeView_AddChild($tree_view, $hItem, $aTons[$kk]) For $ll = 0 To UBound($aSabores, 1) - 1 $hChild2 = _GUICtrlTreeView_AddChild($tree_view, $hChild1, $aSabores[$ll]) Next Next Next _GUICtrlTreeView_EndUpdate($tree_view) Next EndFunc ;==>Populate GUISetOnEvent($GUI_EVENT_CLOSE, "SysEvents") GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SysEvents") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW, $hGui) While Sleep(25) ;add Enter, Esc, Delete and Insert key functionality to treeview edit: TreeKeyboardFunc() WEnd Func SysEvents() Local $hTree = $NODES[0][2] Local $hItem, $aHwnd, $hItemHover, $aRect, $iTreeY Switch @GUI_CtrlId Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_PRIMARYUP If $bTreeDrag Then _WinAPI_InvalidateRect($hTree) $bTreeDrag = False ;delete drag image _GUIImageList_Destroy($hTreeDragImage) ;remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove InsertMark _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) If (TreeItemFromPoint($hTree) = $hDragItem) Then ContinueCase ;move item $hItem = TreeItemCopy($hTree, $hDragItem, TreeItemFromPoint($hTree), $fWhere) If $hItem <> 0 Then _GUICtrlTreeView_SelectItem($hTree, $hItem) _GUICtrlTreeView_Delete($hTree, $hDragItem) EndIf EndIf Case $GUI_EVENT_MOUSEMOVE If $bTreeDrag = False Then ContinueCase $aHwnd = DllCall("user32.dll", "hwnd", "WindowFromPoint", "uint", MouseGetPos(0), "uint", MouseGetPos(1)) ;cancel drag in progress and cleanup if moved outside treeview: If ($aHwnd[0] <> $hTree) Then $bTreeDrag = False _WinAPI_InvalidateRect($hTree) ;delete drag image _GUIImageList_Destroy($hTreeDragImage) ;remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove InsertMark _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ContinueCase EndIf $hItemHover = TreeItemFromPoint($hTree) If $hItemHover = 0 Then ;meh Else $aRect = _GUICtrlTreeView_DisplayRect($hTree, $hItemHover) $iTreeY = _WinAPI_GetMousePosY(True, $hTree) Switch $iTreeY Case $aRect[1] To $aRect[1] + Int(($aRect[3] - $aRect[1]) / 4) ;remove DropTarget ConsoleWrite("remove DropTarget" & @LF) _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;add InsertMark before item _SendMessage($hTree, $TVM_SETINSERTMARK, 0, $hItemHover) $fWhere = -1 Case 1 + $aRect[1] + Int(($aRect[3] - $aRect[1]) / 3) To $aRect[1] + Int(($aRect[3] - $aRect[1]) * 2 / 3) ;remove InsertMark _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;add DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) $fWhere = 0 Case 1 + $aRect[1] + Int(($aRect[3] - $aRect[1]) * 2 / 3) To $aRect[3] ; remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;add InsertMark after item _SendMessage($hTree, $TVM_SETINSERTMARK, 1, $hItemHover) $fWhere = 1 EndSwitch EndIf DrawDragImage($hTree, $hTreeDragImage) EndSwitch EndFunc ;==>SysEvents ; TreeItemFromPoint() ; Returns handle of tree item under mouse: Func TreeItemFromPoint($hWnd) Local $tMPos = _WinAPI_GetMousePos(True, $hWnd) Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) EndFunc ;==>TreeItemFromPoint ; TreeItemCopy() ; Copies tree item $hItemSource and all its children to an item $hItemTarget, depending on $fDirection ; $fDirection: ; -1 = before $hItemTarget ; 0 = inside $hItemTarget ; 1 = after $hItemTarget Func TreeItemCopy($hWnd, $hItemSource, $hItemTarget, $fDirection) ;making sure parent can't be dropped onto one of its descendants: Local $hPrev, $hNew, $iChildCount, $hRecSource Local $hTest = $hItemTarget Do $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest) If $hTest = $hItemSource Then Return 0 Until $hTest = 0 ;create new item at determined position Local $sText = _GUICtrlTreeView_GetText($hWnd, $hItemSource) Local $hParent = _GUICtrlTreeView_GetParentHandle($hWnd, $hItemTarget) Switch $fDirection Case -1 $hPrev = _GUICtrlTreeView_GetPrevSibling($hWnd, $hItemTarget) If $hPrev = 0 Then $hNew = _GUICtrlTreeView_AddFirst($hWnd, $hItemTarget, $sText) Else $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hPrev) EndIf Case 0 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hItemTarget) Case 1 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hItemTarget) Case Else Return 0 EndSwitch ;save item state and checkbox image if there is such _GUICtrlTreeView_SetState($hWnd, $hNew, _GUICtrlTreeView_GetState($hWnd, $hItemSource)) If _GUICtrlTreeView_GetStateImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetStateImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItemSource)) EndIf ;save icon/selected image indexes If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetImageIndex($hWnd, $hItemSource)) _GUICtrlTreeView_SetSelectedImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hWnd, $hItemSource)) EndIf ;recurse through descendants: $iChildCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItemSource) If $iChildCount > 0 Then For $i = 0 To $iChildCount - 1 $hRecSource = _GUICtrlTreeView_GetItemByIndex($hWnd, $hItemSource, $i) TreeItemCopy($hWnd, $hRecSource, $hNew, 0) Next EndIf Return $hNew EndFunc ;==>TreeItemCopy Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) $NODES[0][1] = $wParam Switch $wParam Case $TREE1[$eGID] $NODES[0][2] = $TREE1[$eHANDLE] Local $tNMHDR = DllStructCreate("hwnd hTree;uint;int code", $lParam) Local $iCode = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $iCode Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW $bTreeDrag = True $hDragItem = TreeItemFromPoint($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hDragItem) _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem) DrawDragImage($hTree, $hTreeDragImage) Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case $TVN_ENDLABELEDITW, $TVN_ENDLABELEDITW $bTreeEdit = False Return 1 Case $TVN_SELCHANGED, $TVN_SELCHANGEDW ;~ ;Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ;~ Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ;~ Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") ;~ Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" ;~ GUICtrlSetData($label2, $sTxt) Case Else EndSwitch Case $TREE2[$eGID] $NODES[0][2] = $TREE2[$eHANDLE] Local $tNMHDR = DllStructCreate("hwnd hTree;uint;int code", $lParam) Local $iCode = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $iCode Case $NM_RCLICK ;~ SET_FOCUS($TREE2, 1) Local $hSel = _GUICtrlTreeView_GetSelection($TREE2[$eHANDLE]) ConsoleWrite("$hSel[" & $hSel & "]" & @LF) Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($TREE2[$eHANDLE], $hSel) & " (item handle " & $hSel & ")" GUICtrlSetData($label2, $sTxt) _SendMessage($TREE2[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hSel) Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW $bTreeDrag = True $hDragItem = TreeItemFromPoint($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hDragItem) _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem) DrawDragImage($hTree, $hTreeDragImage) Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case $TVN_ENDLABELEDITW, $TVN_ENDLABELEDITW $bTreeEdit = False Return 1 Case $TVN_SELCHANGED, $TVN_SELCHANGEDW ;~ ;Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ;~ Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ;~ Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") ;~ Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" ;~ GUICtrlSetData($label2, $sTxt) Case Else EndSwitch EndSwitch EndFunc ;==>WM_NOTIFY Func _GuiCtrlTreeView_GetItemFocus($hTreeView) Local $tMPos = _WinAPI_GetMousePos(True, $hTreeView) Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) $hItem = $hItem ? $hItem : 0 Return $hItem EndFunc ;==>_GuiCtrlTreeView_GetItemFocus Func SET_FOCUS(ByRef $ARR, $iMode = 0) Local $hItem = _GuiCtrlTreeView_GetItemFocus($ARR[$eHANDLE]) ConsoleWrite("$hItem[" & $hItem & "]" & @LF) If $iMode Then _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hItem) If $hItem Then If $hItem <> $ARR[$eFOCUS] Then $ARR[$eFOCUS] = $hItem $ARR[$ePARAM] = _GUICtrlTreeView_GetItemParam($ARR[$eHANDLE], $ARR[$eFOCUS]) $ARR[$ePARENT] = _GUICtrlTreeView_GetParentHandle($ARR[$eHANDLE], $ARR[$eFOCUS]) $ARR[$ePARENT] = $ARR[$ePARENT] ? $ARR[$ePARENT] : 0 ;~ _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hItem) EndIf Else $ARR[$eFOCUS] = -1 $ARR[$ePARAM] = -1 $ARR[$ePARENT] = -1 ;~ _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, 0) EndIf EndFunc ;==>SET_FOCUS Func KeyPressed($iHexKey) Local $aRet = DllCall("user32.dll", "int", "GetAsyncKeyState", "int", $iHexKey) ;~ If BitAND($aRet[0], 0x8000) Or BitAND($aRet[0], 1) Then Return 1 If BitAND($aRet[0], 1) Then Return 1 Return 0 EndFunc ;==>KeyPressed Func TreeKeyboardFunc() If $bTreeDrag Then Return Local $hWnd = $NODES[0][2] If $bTreeEdit Then If KeyPressed($VK_RETURN) Then ConsoleWrite("bTreeEdit $VK_RETURN" & @LF) _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 0, 0) EndIf If KeyPressed($VK_ESCAPE) Then ConsoleWrite("bTreeEdit $VK_ESCAPE" & @LF) _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 1, 0) EndIf EndIf Local $aRet = DllCall("user32.dll", "hwnd", "GetFocus") If $aRet[0] = $hWnd Then If KeyPressed($VK_INSERT) Then ConsoleWrite("($aRet[0] = $hWnd) $VK_INSERT" & @LF) _GUICtrlTreeView_Add($hWnd, _GUICtrlTreeView_GetSelection($hWnd), "New Item") EndIf If KeyPressed($VK_DELETE) Then ConsoleWrite("($aRet[0] = $hWnd) $VK_DELETE" & @LF) _GUICtrlTreeView_Delete($hWnd, _GUICtrlTreeView_GetSelection($hWnd)) EndIf If KeyPressed($VK_RETURN) Then ConsoleWrite("($aRet[0] = $hWnd) $VK_RETURN" & @LF) _SendMessage($hWnd, $TVM_EDITLABEL, 0, _GUICtrlTreeView_GetSelection($hWnd)) EndIf EndIf EndFunc ;==>TreeKeyboardFunc Func TreeCreateDragImage($hWnd, $hItem) ;if treeview has imagelist, use image from it If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then Return _GUICtrlTreeView_CreateDragImage($hWnd, $hItem) ;if not, create a bitmap of dragitem's text rectangle and put it into imagelist. Local $aItemRect = _GUICtrlTreeView_DisplayRect($hWnd, $hItem, True) Local $iImgW = $aItemRect[2] - $aItemRect[0] Local $iImgH = $aItemRect[3] - $aItemRect[1] Local $hTreeDC = _WinAPI_GetDC($hWnd) Local $hMemDC = _WinAPI_CreateCompatibleDC($hTreeDC) Local $hMemBmp = _WinAPI_CreateCompatibleBitmap($hTreeDC, $iImgW, $iImgH) Local $hMemBmpOld = _WinAPI_SelectObject($hMemDC, $hMemBmp) _WinAPI_BitBlt($hMemDC, 0, 0, $iImgW, $iImgH, $hTreeDC, $aItemRect[0], $aItemRect[1], $SRCCOPY) _WinAPI_SelectObject($hMemDC, $hMemBmpOld) _WinAPI_ReleaseDC($hWnd, $hTreeDC) _WinAPI_DeleteDC($hMemDC) Local $hImgList = _GUIImageList_Create($iImgW, $iImgH, 6) _GUIImageList_Add($hImgList, $hMemBmp) _WinAPI_DeleteObject($hMemBmp) Return $hImgList EndFunc ;==>TreeCreateDragImage ; Draw drag image ; by Gary Frost (gafrost) (?) Func DrawDragImage(ByRef $hControl, ByRef $hImage) Local $hDC = _WinAPI_GetWindowDC($hControl) Local $tPoint = _WinAPI_GetMousePos(True, $hControl) _WinAPI_InvalidateRect($hControl) _GUIImageList_Draw($hImage, 0, $hDC, DllStructGetData($tPoint, "X") - 10, DllStructGetData($tPoint, "Y") - 8) _WinAPI_ReleaseDC($hControl, $hDC) EndFunc ;==>DrawDragImage Func _GUISetFont_Ctrl($sFontName = "DOSLike", $iHeight = 14, $iWidth = 10) Local $hFont = _WinAPI_CreateFont( _ $iHeight, _ $iWidth, _ 0, _ 0, _ $FW_NORMAL, _ False, _ False, _ False, _ $DEFAULT_CHARSET, _ $OUT_OUTLINE_PRECIS, _ $CLIP_DEFAULT_PRECIS, _ $DEFAULT_QUALITY, _ $DEFAULT_PITCH, _ $sFontName) Return $hFont EndFunc ;==>_GUISetFont_Ctrl Func Function1() ConsoleWrite("Function1" & @LF) EndFunc ;==>Function1 Func Function2() ConsoleWrite("Function2" & @LF) EndFunc ;==>Function2 Func Function3() ConsoleWrite("Function3" & @LF) EndFunc ;==>Function3 Func Function4() ConsoleWrite("Function4" & @LF) EndFunc ;==>Function4 Func Function5() ConsoleWrite("Function5" & @LF) EndFunc ;==>Function5 Func Function6() ConsoleWrite("Function6" & @LF) EndFunc ;==>Function6 Func Function7() ConsoleWrite("Function7" & @LF) EndFunc ;==>Function7 Func Function8() ConsoleWrite("Function8" & @LF) EndFunc ;==>Function8 Visit my repository Link to comment Share on other sites More sharing options...
Luigi Posted November 29, 2016 Author Share Posted November 29, 2016 I re-write some lines. In this version, you can drag a item from TreeView A to TreeView B. Can you test? Do you found a bug? Leave your comment. expandcollapse popup; https://www.autoitscript.com/forum/topic/56411-treeview-drag-drop-reorder-and-edit-example/ #include-once #include <Array.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <GuiTreeView.au3> ;~ #include <GuiMenu.au3> #include <WinAPI.au3> ;~ #include <SQLite.au3> ;~ #include <SQLite.dll.au3> ;~ #include <File.au3> #include <FontConstants.au3> ;~ #include <GuiListView.au3> ;~ #include <EditConstants.au3> ;~ #include <ListViewConstants.au3> ;~ #include <GuiImageList.au3> ;~ #include <GuiComboBox.au3> ;~ #include <TreeViewConstants.au3> #include <WinAPIvkeysConstants.au3> ;~ #include <GuiCreateEx.au3> Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) Global $TVN_BEGINDRAG Global $TVN_BEGINLABELEDIT Global $TVN_SELCHANGED Global $TVM_EDITLABEL ;Required global constants: Global $bTreeDrag = False, $bTreeEdit = False, $hDragItem, $hTreeDragImage, $fWhere Global $FROM, $TO, $ORIGEM Global $hGui = GUICreate("@Tree", 800, 600, 0, 0) Global $label = GUICtrlCreateLabel("*", 10, 500, 780, 20, $SS_SUNKEN) Global $label2 = GUICtrlCreateLabel("", 10, 530, 780, 20, $SS_SUNKEN) Global Enum $eGID = 0, $eHANDLE, $eFOCUS, $ePARAM, $ePARENT Global $TREE1[6], $TREE2[6] Global $NODES[][5] = [ _ [0] _ ] $TREE1[$eGID] = GUICtrlCreateTreeView(10, 10, 320, 480, $TVS_HASBUTTONS + $TVS_HASLINES + $TVS_LINESATROOT + $TVS_EDITLABELS + $TVS_CHECKBOXES) GUICtrlSetFont($TREE1[$eGID], 12, 400, 0, "Courier New") $TREE1[$eHANDLE] = GUICtrlGetHandle($TREE1[$eGID]) GUICtrlSetState($TREE1[$eGID], $GUI_DROPACCEPTED) $TREE2[$eGID] = GUICtrlCreateTreeView(340, 10, 320, 480, $TVS_HASBUTTONS + $TVS_HASLINES + $TVS_LINESATROOT + $TVS_EDITLABELS + $TVS_CHECKBOXES) GUICtrlSetFont($TREE2[$eGID], 12, 400, 0, "Courier New") $TREE2[$eHANDLE] = GUICtrlGetHandle($TREE2[$eGID]) GUICtrlSetState($TREE2[$eGID], $GUI_DROPACCEPTED) Populate() Func Populate() Local $hItem, $hChild1, $hChild2, $tree_view Local $aCores[] = ["amarelo", "vermelho", "branco", "cinza", "azul", "verde", "laranja", "preto"] Local $aTons[] = ["claro", "médio", "escuro"] Local $aSabores[] = ["doce", "salgado", "azedo"] For $ii = 1 To 2 $tree_view = Eval("TREE" & $ii)[$eGID] _GUICtrlTreeView_BeginUpdate($tree_view) For $jj = 0 To 3 ;UBound($aCores, 1) - 1 $hItem = _GUICtrlTreeView_Add($tree_view, 0, $aCores[$jj]) For $kk = 0 To UBound($aTons, 1) - 1 $hChild1 = _GUICtrlTreeView_AddChild($tree_view, $hItem, $aTons[$kk]) For $ll = 0 To UBound($aSabores, 1) - 1 $hChild2 = _GUICtrlTreeView_AddChild($tree_view, $hChild1, $aSabores[$ll]) Next Next Next _GUICtrlTreeView_EndUpdate($tree_view) Next EndFunc ;==>Populate GUISetOnEvent($GUI_EVENT_CLOSE, "Quit") GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SysEvents") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW, $hGui) While Sleep(25) ;add Enter, Esc, Delete and Insert key functionality to treeview edit: TreeKeyboardFunc() WEnd Func SysEvents() Local $hTree = $NODES[0][2] Local $hItem, $hItemHover, $aRect, $iTreeY, $iSearch Switch @GUI_CtrlId Case $GUI_EVENT_PRIMARYUP If $bTreeDrag Then _WinAPI_InvalidateRect($hTree) $bTreeDrag = False ;delete drag image _GUIImageList_Destroy($hTreeDragImage) ;remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove InsertMark _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) If TreeItemFromPoint($hTree) = $hDragItem Then ContinueCase ConsoleWrite("ContinueCase" & @LF) ;move item $hItem = TreeItemCopy($FROM, $hDragItem, TreeItemFromPoint($hTree), $fWhere) If $hItem <> 0 Then _GUICtrlTreeView_SelectItem($hTree, $hItem) _GUICtrlTreeView_Delete($FROM, $hDragItem) EndIf $FROM = 0 EndIf Case $GUI_EVENT_MOUSEMOVE If Not $bTreeDrag Then ContinueCase If Not ($ORIGEM = $hTree) Then _WinAPI_InvalidateRect($ORIGEM) ;~ ;delete drag image _GUIImageList_Destroy($hTreeDragImage) ;~ ;remove DropTarget _SendMessage($ORIGEM, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;~ ;remove InsertMark _SendMessage($ORIGEM, $TVM_SETINSERTMARK, 0, 0) $hTreeDragImage = TreeCreateDragImage($ORIGEM, $hDragItem) $ORIGEM = $hTree EndIf $hItemHover = TreeItemFromPoint($hTree) If $hItemHover = 0 Then ConsoleWrite("$hItemHover = 0" & @LF) ;meh Else $aRect = _GUICtrlTreeView_DisplayRect($hTree, $hItemHover) $iTreeY = _WinAPI_GetMousePosY(True, $hTree) Switch $iTreeY Case $aRect[1] To $aRect[1] + Int(($aRect[3] - $aRect[1]) / 4) ;remove DropTarget ;~ ConsoleWrite("$fWhere = -1" & @LF) _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;add InsertMark before item _SendMessage($hTree, $TVM_SETINSERTMARK, 0, $hItemHover) $fWhere = -1 Case 1 + $aRect[1] + Int(($aRect[3] - $aRect[1]) / 3) To $aRect[1] + Int(($aRect[3] - $aRect[1]) * 2 / 3) ;remove InsertMark _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;add DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) $fWhere = 0 ;~ ConsoleWrite("$fWhere = 0" & @LF) Case 1 + $aRect[1] + Int(($aRect[3] - $aRect[1]) * 2 / 3) To $aRect[3] ; remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;add InsertMark after item _SendMessage($hTree, $TVM_SETINSERTMARK, 1, $hItemHover) $fWhere = 1 ;~ ConsoleWrite("$fWhere = 1" & @LF) EndSwitch EndIf DrawDragImage($hTree, $hTreeDragImage) EndSwitch EndFunc ;==>SysEvents ; TreeItemFromPoint() ; Returns handle of tree item under mouse: Func TreeItemFromPoint($hWnd) Local $tMPos = _WinAPI_GetMousePos(True, $hWnd) Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) EndFunc ;==>TreeItemFromPoint ; TreeItemCopy() ; Copies tree item $hItemSource and all its children to an item $hItemTarget, depending on $fDirection ; $fDirection: ; -1 = before $hItemTarget ; 0 = inside $hItemTarget ; 1 = after $hItemTarget Func TreeItemCopy($hWnd, $hItemSource, $hItemTarget, $fDirection) ;making sure parent can't be dropped onto one of its descendants: Local $hPrev, $hNew, $iChildCount, $hRecSource Local $hTest = $hItemTarget Do $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest) If $hTest = $hItemSource Then Return 0 Until $hTest = 0 ;create new item at determined position Local $sText = _GUICtrlTreeView_GetText($hWnd, $hItemSource) Local $hParent = _GUICtrlTreeView_GetParentHandle($hWnd, $hItemTarget) Switch $fDirection Case -1 $hPrev = _GUICtrlTreeView_GetPrevSibling($hWnd, $hItemTarget) If $hPrev = 0 Then $hNew = _GUICtrlTreeView_AddFirst($hWnd, $hItemTarget, $sText) Else $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hPrev) EndIf Case 0 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hItemTarget) Case 1 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hItemTarget) Case Else Return 0 EndSwitch ;save item state and checkbox image if there is such _GUICtrlTreeView_SetState($hWnd, $hNew, _GUICtrlTreeView_GetState($hWnd, $hItemSource)) If _GUICtrlTreeView_GetStateImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetStateImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItemSource)) EndIf ;save icon/selected image indexes If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetImageIndex($hWnd, $hItemSource)) _GUICtrlTreeView_SetSelectedImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hWnd, $hItemSource)) EndIf ;recurse through descendants: $iChildCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItemSource) If $iChildCount > 0 Then For $i = 0 To $iChildCount - 1 $hRecSource = _GUICtrlTreeView_GetItemByIndex($hWnd, $hItemSource, $i) TreeItemCopy($hWnd, $hRecSource, $hNew, 0) Next EndIf Return $hNew EndFunc ;==>TreeItemCopy Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) $NODES[0][1] = $wParam Switch $wParam Case $TREE1[$eGID] $NODES[0][2] = $TREE1[$eHANDLE] Local $tNMHDR = DllStructCreate("hwnd hTree;uint;int code", $lParam) Local $iCode = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $iCode Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW $ORIGEM = $TREE1[$eHANDLE] $FROM = $TREE1[$eHANDLE] $bTreeDrag = True $hDragItem = TreeItemFromPoint($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hDragItem) _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem) DrawDragImage($hTree, $hTreeDragImage) Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case $TVN_ENDLABELEDITW, $TVN_ENDLABELEDITW $bTreeEdit = False Return 1 Case $TVN_SELCHANGED, $TVN_SELCHANGEDW ;~ ;Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ;~ Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ;~ Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") ;~ Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" ;~ GUICtrlSetData($label2, $sTxt) Case Else EndSwitch Case $TREE2[$eGID] $NODES[0][2] = $TREE2[$eHANDLE] Local $tNMHDR = DllStructCreate("hwnd hTree;uint;int code", $lParam) Local $iCode = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $iCode Case $NM_RCLICK ;~ SET_FOCUS($TREE2, 1) Local $hSel = _GUICtrlTreeView_GetSelection($TREE2[$eHANDLE]) Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($TREE2[$eHANDLE], $hSel) & " (item handle " & $hSel & ")" GUICtrlSetData($label2, $sTxt) _SendMessage($TREE2[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hSel) Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW $ORIGEM = $TREE2[$eHANDLE] $FROM = $TREE2[$eHANDLE] $bTreeDrag = True $hDragItem = TreeItemFromPoint($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hDragItem) _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem) DrawDragImage($hTree, $hTreeDragImage) Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case $TVN_ENDLABELEDITW, $TVN_ENDLABELEDITW $bTreeEdit = False Return 1 Case $TVN_SELCHANGED, $TVN_SELCHANGEDW ;~ ;Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ;~ Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ;~ Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") ;~ Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" ;~ GUICtrlSetData($label2, $sTxt) Case Else EndSwitch EndSwitch EndFunc ;==>WM_NOTIFY Func _GuiCtrlTreeView_GetItemFocus($hTreeView) Local $tMPos = _WinAPI_GetMousePos(True, $hTreeView) Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) $hItem = $hItem ? $hItem : 0 Return $hItem EndFunc ;==>_GuiCtrlTreeView_GetItemFocus Func SET_FOCUS(ByRef $ARR, $iMode = 0) Local $hItem = _GuiCtrlTreeView_GetItemFocus($ARR[$eHANDLE]) ConsoleWrite("$hItem[" & $hItem & "]" & @LF) If $iMode Then _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hItem) If $hItem Then If $hItem <> $ARR[$eFOCUS] Then $ARR[$eFOCUS] = $hItem $ARR[$ePARAM] = _GUICtrlTreeView_GetItemParam($ARR[$eHANDLE], $ARR[$eFOCUS]) $ARR[$ePARENT] = _GUICtrlTreeView_GetParentHandle($ARR[$eHANDLE], $ARR[$eFOCUS]) $ARR[$ePARENT] = $ARR[$ePARENT] ? $ARR[$ePARENT] : 0 ;~ _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hItem) EndIf Else $ARR[$eFOCUS] = -1 $ARR[$ePARAM] = -1 $ARR[$ePARENT] = -1 ;~ _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, 0) EndIf EndFunc ;==>SET_FOCUS Func KeyPressed($iHexKey) Local $aRet = DllCall("user32.dll", "int", "GetAsyncKeyState", "int", $iHexKey) ;~ If BitAND($aRet[0], 0x8000) Or BitAND($aRet[0], 1) Then Return 1 If BitAND($aRet[0], 1) Then Return 1 Return 0 EndFunc ;==>KeyPressed Func TreeKeyboardFunc() If $bTreeDrag Then Return Local $hWnd = $NODES[0][2] If $bTreeEdit Then If KeyPressed($VK_RETURN) Then ConsoleWrite("bTreeEdit $VK_RETURN" & @LF) _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 0, 0) EndIf If KeyPressed($VK_ESCAPE) Then ConsoleWrite("bTreeEdit $VK_ESCAPE" & @LF) _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 1, 0) EndIf EndIf Local $aRet = DllCall("user32.dll", "hwnd", "GetFocus") If $aRet[0] = $hWnd Then If KeyPressed($VK_INSERT) Then ConsoleWrite("($aRet[0] = $hWnd) $VK_INSERT" & @LF) _GUICtrlTreeView_Add($hWnd, _GUICtrlTreeView_GetSelection($hWnd), "New Item") EndIf If KeyPressed($VK_DELETE) Then ConsoleWrite("($aRet[0] = $hWnd) $VK_DELETE" & @LF) _GUICtrlTreeView_Delete($hWnd, _GUICtrlTreeView_GetSelection($hWnd)) EndIf If KeyPressed($VK_RETURN) Then ConsoleWrite("($aRet[0] = $hWnd) $VK_RETURN" & @LF) _SendMessage($hWnd, $TVM_EDITLABEL, 0, _GUICtrlTreeView_GetSelection($hWnd)) EndIf EndIf EndFunc ;==>TreeKeyboardFunc Func TreeCreateDragImage($hWnd, $hItem) ConsoleWrite("TreeCreateDragImage( $hWnd=" & $hWnd & ", $hItem=" & $hItem & ")" & @LF) If Not $hWnd Or Not $hItem Then Return ;if treeview has imagelist, use image from it If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then Return _GUICtrlTreeView_CreateDragImage($hWnd, $hItem) ;if not, create a bitmap of dragitem's text rectangle and put it into imagelist. Local $aItemRect = _GUICtrlTreeView_DisplayRect($hWnd, $hItem, True) Local $iImgW = $aItemRect[2] - $aItemRect[0] Local $iImgH = $aItemRect[3] - $aItemRect[1] Local $hTreeDC = _WinAPI_GetDC($hWnd) Local $hMemDC = _WinAPI_CreateCompatibleDC($hTreeDC) Local $hMemBmp = _WinAPI_CreateCompatibleBitmap($hTreeDC, $iImgW, $iImgH) Local $hMemBmpOld = _WinAPI_SelectObject($hMemDC, $hMemBmp) _WinAPI_BitBlt($hMemDC, 0, 0, $iImgW, $iImgH, $hTreeDC, $aItemRect[0], $aItemRect[1], $SRCCOPY) _WinAPI_SelectObject($hMemDC, $hMemBmpOld) _WinAPI_ReleaseDC($hWnd, $hTreeDC) _WinAPI_DeleteDC($hMemDC) Local $hImgList = _GUIImageList_Create($iImgW, $iImgH, 6) _GUIImageList_Add($hImgList, $hMemBmp) _WinAPI_DeleteObject($hMemBmp) Return $hImgList EndFunc ;==>TreeCreateDragImage ; Draw drag image ; by Gary Frost (gafrost) (?) Func DrawDragImage(ByRef $hControl, ByRef $aDrag) Local $tPoint, $hDC $hDC = _WinAPI_GetWindowDC($hControl) $tPoint = _WinAPI_GetMousePos(True, $hControl) _WinAPI_InvalidateRect($hControl) _GUIImageList_Draw($aDrag, 0, $hDC, DllStructGetData($tPoint, "X") - 10, DllStructGetData($tPoint, "Y") - 8) _WinAPI_ReleaseDC($hControl, $hDC) EndFunc ;==>DrawDragImage Func _GUISetFont_Ctrl($sFontName = "DOSLike", $iHeight = 14, $iWidth = 10) Local $hFont = _WinAPI_CreateFont( _ $iHeight, _ $iWidth, _ 0, _ 0, _ $FW_NORMAL, _ False, _ False, _ False, _ $DEFAULT_CHARSET, _ $OUT_OUTLINE_PRECIS, _ $CLIP_DEFAULT_PRECIS, _ $DEFAULT_QUALITY, _ $DEFAULT_PITCH, _ $sFontName) Return $hFont EndFunc ;==>_GUISetFont_Ctrl Func Function1() ConsoleWrite("Function1" & @LF) EndFunc ;==>Function1 Func Function2() ConsoleWrite("Function2" & @LF) EndFunc ;==>Function2 Func Function3() ConsoleWrite("Function3" & @LF) EndFunc ;==>Function3 Func Function4() ConsoleWrite("Function4" & @LF) EndFunc ;==>Function4 Func Function5() ConsoleWrite("Function5" & @LF) EndFunc ;==>Function5 Func Function6() ConsoleWrite("Function6" & @LF) EndFunc ;==>Function6 Func Function7() ConsoleWrite("Function7" & @LF) EndFunc ;==>Function7 Func Function8() ConsoleWrite("Function8" & @LF) EndFunc ;==>Function8 Func OnExit() GUISetState($hGui, @SW_HIDE) GUIDelete($hGui) EndFunc ;==>OnExit Func Quit() Exit EndFunc ;==>Quit Visit my repository Link to comment Share on other sites More sharing options...
Danyfirex Posted November 30, 2016 Share Posted November 30, 2016 Hello Luigi. I tested yut code and sometimes treeview B does not redraw the items. the other issue is when you drag all items from A to B AutoIt script Crashes. I have not time to fix it. but I hope this answer helps. Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Luigi Posted November 30, 2016 Author Share Posted November 30, 2016 (edited) @Danyfirex, thank you for your reply. I fix some redraws (not all). And you can drag any item from one to another, and left on empty (root). Sometimes it expand the write item, sometimes not. If you begin drag a treeview item, from one to another treeview, if the item stay in the origem treeview, its show with correct name, when it moved to another treeview, the name its wrong, but, when you left, its fixed. This bug is only when you drag a item. I want implement: a] copy a node b] context menu (delete, rename, create) c] define a rule: you can drag(create a copy) from on treeview for another, not inverse This is a new code. expandcollapse popup; https://www.autoitscript.com/forum/topic/56411-treeview-drag-drop-reorder-and-edit-example/ #include-once #include <Array.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <GuiTreeView.au3> #include <WinAPI.au3> #include <GuiMenu.au3> #include <FontConstants.au3> #include <WinAPIvkeysConstants.au3> Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) Global $TVN_BEGINDRAG Global $TVN_BEGINLABELEDIT Global $TVN_SELCHANGED Global $TVM_EDITLABEL ;Required global constants: Global $bTreeDrag = False, $bTreeEdit = False, $hItemDrag, $hTreeDragImage, $fWhere Global $FROM, $ORIGEM, $TEXT = "" Global $hDummy, $hDummyContext, $hDummyContextMenu Global $hDummy2, $hDummyContext2, $hDummyContextMenu2 Global $hGui = GUICreate("TreeView", 800, 600, 0, 0) Global $label = GUICtrlCreateLabel("*", 10, 500, 780, 20, $SS_SUNKEN) Global $label2 = GUICtrlCreateLabel("", 10, 530, 780, 20, $SS_SUNKEN) #cs $NODES array is used to store graphics elements, as ID, HANDLE, item focus, param item and parent from item In the future, I use others graphic elemnts like listview, not only treeview $NODES id +-eGID-+---eHANDLE--+------eFOCUS--+---ePARAM--+---ePARENT--+ 0 | | |TREEVIEW_FOCUS | | | 1 | 5 | 0x00ABCDEF | | | | 2 | 6 | 0x00ABCDFF | | | | BUGS I use some function called Funcion1...8, becouse sometimes a random funcion is called when you use a keyboard arrows, in this version, that no more happens Context menu pops up, but does not work still, only call funcitions #ce Global Enum $eGID = 0, $eHANDLE, $eFOCUS, $ePARAM, $ePARENT Global $NODES[3][5] = [ _ [0] _ ] $NODES[1][$eGID] = GUICtrlCreateTreeView(10, 10, 320, 480, $TVS_HASBUTTONS + $TVS_HASLINES + $TVS_LINESATROOT + $TVS_EDITLABELS + $TVS_CHECKBOXES) GUICtrlSetFont($NODES[1][$eGID], 12, 400, 0, "Courier New") $NODES[1][$eHANDLE] = GUICtrlGetHandle($NODES[1][$eGID]) GUICtrlSetState($NODES[1][$eGID], $GUI_DROPACCEPTED) $NODES[2][$eGID] = GUICtrlCreateTreeView(340, 10, 320, 480, $TVS_HASBUTTONS + $TVS_HASLINES + $TVS_LINESATROOT + $TVS_EDITLABELS + $TVS_CHECKBOXES) GUICtrlSetFont($NODES[2][$eGID], 12, 400, 0, "Courier New") $NODES[2][$eHANDLE] = GUICtrlGetHandle($NODES[2][$eGID]) GUICtrlSetState($NODES[2][$eGID], $GUI_DROPACCEPTED) Populate() Func Populate() Local $hItem, $hChild1, $hChild2, $tree_view Local $aCores[] = ["amarelo", "vermelho", "branco", "cinza", "azul", "verde", "laranja", "preto"] Local $aTons[] = ["claro", "médio", "escuro"] Local $aSabores[] = ["doce", "salgado", "azedo"] Local $iNext = 1 For $ii = 1 To 2 $tree_view = $NODES[$ii][$eGID] _GUICtrlTreeView_BeginUpdate($tree_view) ConsoleWrite("TREE" & $ii & "[" & $tree_view & "][" & ($ii = 1 ? $NODES[1][$eHANDLE] : $NODES[2][$eHANDLE]) & "]" & @LF) For $jj = 0 To 1 ;UBound($aCores, 1) - 1 $hItem = _GUICtrlTreeView_Add($tree_view, 0, $ii & "." & $aCores[$jj] & "." & $iNext) $iNext += 1 For $kk = 0 To 1 ;UBound($aTons, 1) - 1 $hChild1 = _GUICtrlTreeView_AddChild($tree_view, $hItem, $ii & "." & $aTons[$kk] & "." & $iNext) $iNext += 1 For $ll = 0 To 1 ;UBound($aSabores, 1) - 1 $hChild2 = _GUICtrlTreeView_AddChild($tree_view, $hChild1, $ii & "." & $aSabores[$ll] & "." & $iNext) $iNext += 1 _GUICtrlTreeView_Expand($tree_view, $hChild2, True) Next Next Next _GUICtrlTreeView_EndUpdate($tree_view) Next EndFunc ;==>Populate GUISetOnEvent($GUI_EVENT_CLOSE, "Quit") GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SysEvents") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") _CreateDummy($hDummy, $hDummyContext, $hDummyContextMenu, "Add=Context_Add;Rename=Context_Update;Del=Context_Del;Copy=Context_Copy") _CreateDummy($hDummy2, $hDummyContext2, $hDummyContextMenu2, "AddRoot=Context_AddRoot") GUISetState(@SW_SHOW, $hGui) While Sleep(25) ;add Enter, Esc, Delete and Insert key functionality to treeview edit: TreeKeyboardFunc() WEnd Func SysEvents() Local $hTree = $NODES[0][2] Local $hItem, $hItemHover, $aRect, $iTreeY, $focus Switch @GUI_CtrlId Case $GUI_EVENT_PRIMARYUP If $bTreeDrag Then ; Adds a rectangle to the specified window's update region _WinAPI_InvalidateRect($hTree) $bTreeDrag = False ; delete drag image _GUIImageList_Destroy($hTreeDragImage) ; remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ; remove InsertMark _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ; move item $focus = _GuiCtrlTreeView_GetItemFocus($hTree) ; prevent a $hItemDrag copy to yourself If $hItemDrag <> $focus Then ; copy a treeview item from...to $hItem = TreeItemCopy($FROM, $hItemDrag, $hTree, $focus, $fWhere) If $hItem <> 0 Then ; collapse and expand the $hItem _GUICtrlTreeView_Expand($hTree, $hItem, False) _GUICtrlTreeView_Expand($hTree, $hItem, True) ; select the $hItem _GUICtrlTreeView_SelectItem($hTree, $hItem) ; delete $hItemDrag from $FROM _GUICtrlTreeView_Delete($FROM, $hItemDrag) EndIf EndIf $FROM = 0 EndIf Case $GUI_EVENT_MOUSEMOVE If Not $bTreeDrag Then ContinueCase ; detect drag from to another treeview and update $hTreeDragImage ; destroy some graphics elements from old treeview If Not ($ORIGEM = $hTree) Then _WinAPI_InvalidateRect($ORIGEM) ; delete drag image _GUIImageList_Destroy($hTreeDragImage) ; remove DropTarget _SendMessage($ORIGEM, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ; remove InsertMark _SendMessage($ORIGEM, $TVM_SETINSERTMARK, 0, 0) ;~ $hItemDrag = _GuiCtrlTreeView_GetItemFocus($hTree) $hTreeDragImage = TreeCreateDragImage($hTree, $hItemDrag) $ORIGEM = $hTree EndIf $hItemHover = _GuiCtrlTreeView_GetItemFocus($hTree) If $hItemHover = 0 Then ;meh Else $aRect = _GUICtrlTreeView_DisplayRect($hTree, $hItemHover) $iTreeY = _WinAPI_GetMousePosY(True, $hTree) Switch $iTreeY Case $aRect[1] To $aRect[1] + Int(($aRect[3] - $aRect[1]) / 4) ; remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ; add InsertMark before item _SendMessage($hTree, $TVM_SETINSERTMARK, 0, $hItemHover) $fWhere = -1 Case 1 + $aRect[1] + Int(($aRect[3] - $aRect[1]) / 3) To $aRect[1] + Int(($aRect[3] - $aRect[1]) * 2 / 3) ; remove InsertMark _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ; add DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) $fWhere = 0 Case 1 + $aRect[1] + Int(($aRect[3] - $aRect[1]) * 2 / 3) To $aRect[3] ; remove DropTarget _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ; add InsertMark after item _SendMessage($hTree, $TVM_SETINSERTMARK, 1, $hItemHover) $fWhere = 1 EndSwitch EndIf DrawDragImage($hTree, $hTreeDragImage) _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), True) EndSwitch EndFunc ;==>SysEvents ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GuiCtrlTreeView_GetItemFocus ; Description ...: ; Syntax ........: _GuiCtrlTreeView_GetItemFocus($hTreeView) ; Parameters ....: $hTreeView - a handle value. ; Return values .: None ; Author ........: Your Name ; Modified ......: ; Remarks .......: ; Related .......: Returns handle of tree item under mouse: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _GuiCtrlTreeView_GetItemFocus($hTreeView) Local $tMPos = _WinAPI_GetMousePos(True, $hTreeView) Return _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) EndFunc ;==>_GuiCtrlTreeView_GetItemFocus ; TreeItemCopy() ; Copies tree item $hItemSource and all its children to an item $hItemTarget, depending on $fDirection ; $fDirection: ; -1 = before $hItemTarget ; 0 = inside $hItemTarget ; 1 = after $hItemTarget Func TreeItemCopy($hTreeSource, $hItemSource, $hTreeTarget, $hItemTarget, $fDirection) ConsoleWrite("TreeItemCopy( $hTreeSource=" & $hTreeSource & ", $hItemSource=" & $hItemSource & ", $hTreeTarget=" & $hTreeTarget & ",$hItemTarget=" & $hItemTarget & ", $fDirection=" & $fDirection & " )" & @LF) ;making sure parent can't be dropped onto one of its descendants: Local $hPrev, $hNew, $iChildCount, $hRecSource ;create new item at determined position Local $sText = _GUICtrlTreeView_GetText($hTreeSource, $hItemSource) Local $hParent = _GUICtrlTreeView_GetParentHandle($hTreeSource, $hItemTarget) If $hItemTarget Then Switch $fDirection Case -1 $hPrev = _GUICtrlTreeView_GetPrevSibling($hTreeSource, $hItemTarget) If $hPrev = 0 Then $hNew = _GUICtrlTreeView_AddFirst($hTreeSource, $hItemTarget, $sText) Else $hNew = _GUICtrlTreeView_InsertItem($hTreeSource, $sText, $hParent, $hPrev) EndIf Case 0 $hNew = _GUICtrlTreeView_InsertItem($hTreeSource, $sText, $hItemTarget) Case 1 $hNew = _GUICtrlTreeView_InsertItem($hTreeSource, $sText, $hParent, $hItemTarget) Case Else ;~ Return 0 EndSwitch Else ; if $hItemTarget is 0, it is a root treeview $hNew = _GUICtrlTreeView_Add($hTreeTarget, 0, $sText) EndIf ;save item state and checkbox image if there is such _GUICtrlTreeView_SetState($hTreeSource, $hNew, _GUICtrlTreeView_GetState($hTreeSource, $hItemSource)) If _GUICtrlTreeView_GetStateImageList($hTreeSource) <> 0 Then _GUICtrlTreeView_SetStateImageIndex($hTreeSource, $hNew, _GUICtrlTreeView_GetStateImageIndex($hTreeSource, $hItemSource)) EndIf ;save icon/selected image indexes If _GUICtrlTreeView_GetNormalImageList($hTreeSource) <> 0 Then _GUICtrlTreeView_SetImageIndex($hTreeSource, $hNew, _GUICtrlTreeView_GetImageIndex($hTreeSource, $hItemSource)) _GUICtrlTreeView_SetSelectedImageIndex($hTreeSource, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hTreeSource, $hItemSource)) EndIf ;recurse through descendants: $iChildCount = _GUICtrlTreeView_GetChildCount($hTreeSource, $hItemSource) Local $arr[2] = [$hTreeSource, $hNew] If $iChildCount > 0 Then For $i = 0 To $iChildCount - 1 $hRecSource = _GUICtrlTreeView_GetItemByIndex($hTreeSource, $hItemSource, $i) TreeItemCopy($hTreeSource, $hRecSource, $hTreeTarget, $hNew, 0) Next EndIf Return $hNew EndFunc ;==>TreeItemCopy Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) $NODES[0][1] = $wParam Switch $wParam Case $NODES[1][$eGID] $NODES[0][2] = $NODES[1][$eHANDLE] Local $tNMHDR = DllStructCreate("hwnd hTree;uint;int code", $lParam) Local $iCode = DllStructGetData($tNMHDR, "code") Local $hTree = $NODES[1][$eHANDLE] ; HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $iCode Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW $ORIGEM = $NODES[1][$eHANDLE] $FROM = $NODES[1][$eHANDLE] $bTreeDrag = True $hItemDrag = _GuiCtrlTreeView_GetItemFocus($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hItemDrag) ;~ _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hItemDrag) DrawDragImage($hTree, $hTreeDragImage) Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case $TVN_ENDLABELEDITW, $TVN_ENDLABELEDITW $bTreeEdit = False Return 1 Case $TVN_SELCHANGED, $TVN_SELCHANGEDW ;~ ;Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ;~ Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ;~ Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") ;~ Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" ;~ GUICtrlSetData($label2, $sTxt) Case $NM_RCLICK ; set focus to treeview 1 SET_FOCUS(1, 1) Local $hSel = _GUICtrlTreeView_GetSelection($NODES[1][$eHANDLE]) _SendMessage($NODES[1][$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hSel) _GUICtrlMenu_TrackPopupMenu($NODES[1][$eFOCUS] = -1 ? $hDummyContextMenu2 : $hDummyContextMenu, $hGui) Return 0 ; zero to allow the default processing Case Else EndSwitch Case $NODES[2][$eGID] $NODES[0][2] = $NODES[2][$eHANDLE] Local $tNMHDR = DllStructCreate("hwnd hTree;uint;int code", $lParam) Local $iCode = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $iCode Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW $ORIGEM = $NODES[2][$eHANDLE] $FROM = $NODES[2][$eHANDLE] $bTreeDrag = True $hItemDrag = _GuiCtrlTreeView_GetItemFocus($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hItemDrag) ;~ _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hItemDrag) DrawDragImage($hTree, $hTreeDragImage) Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case $TVN_ENDLABELEDITW, $TVN_ENDLABELEDITW $bTreeEdit = False Return 1 Case $TVN_SELCHANGED, $TVN_SELCHANGEDW ;~ ;Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ;~ Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ;~ Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") ;~ Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" ;~ GUICtrlSetData($label2, $sTxt) Case $NM_RCLICK ; set focus to treeview 2 SET_FOCUS(2, 1) Local $hSel = _GUICtrlTreeView_GetSelection($NODES[2][$eHANDLE]) _SendMessage($NODES[2][$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hSel) _GUICtrlMenu_TrackPopupMenu($NODES[2][$eFOCUS] = -1 ? $hDummyContextMenu2 : $hDummyContextMenu, $hGui) Return 0 ; zero to allow the default processing Case Else EndSwitch EndSwitch EndFunc ;==>WM_NOTIFY ; #FUNCTION# ==================================================================================================================== ; Name ..........: SET_FOCUS ; Description ...: ; Syntax ........: SET_FOCUS($index[, $iMode = 0]) ; Parameters ....: $index - an integer value. The treeview's ID/line number in NODES array ; $iMode - [optional] an integer value. Default is 0. ; if 1, set focus in $hItem when conext menu is clicked ; Return values .: None ; Author ........: Luigi ; Modified ......: If you click any hItem inside treeview, some parameters (focus, parent and param) was catch en set in NODES ; If you click on empty/none item, all values are set with -1 ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func SET_FOCUS($index, $iMode = 0) Local $hItem = _GuiCtrlTreeView_GetItemFocus($NODES[$index][$eHANDLE]) ; set focus on treeview's item If $iMode Then _SendMessage($NODES[$index][$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hItem) If $hItem Then If $hItem <> $NODES[$index][$eFOCUS] Then $NODES[$index][$eFOCUS] = $hItem $NODES[$index][$ePARAM] = _GUICtrlTreeView_GetItemParam($NODES[$index][$eHANDLE], $NODES[$index][$eFOCUS]) $NODES[$index][$ePARENT] = _GUICtrlTreeView_GetParentHandle($NODES[$index][$eHANDLE], $NODES[$index][$eFOCUS]) $NODES[$index][$ePARENT] = $NODES[$index][$ePARENT] ? $NODES[$index][$ePARENT] : 0 ;~ _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, $hItem) EndIf Else $NODES[$index][$eFOCUS] = -1 $NODES[$index][$ePARAM] = -1 $NODES[$index][$ePARENT] = -1 ;~ _SendMessage($ARR[$eHANDLE], $TVM_SELECTITEM, $TVGN_CARET, 0) EndIf EndFunc ;==>SET_FOCUS Func KeyPressed($iHexKey) Local $aRet = DllCall("user32.dll", "int", "GetAsyncKeyState", "int", $iHexKey) ;~ If BitAND($aRet[0], 0x8000) Or BitAND($aRet[0], 1) Then Return 1 If BitAND($aRet[0], 1) Then Return 1 Return 0 EndFunc ;==>KeyPressed Func TreeKeyboardFunc() If $bTreeDrag Then Return Local $hWnd = $NODES[0][2] If $bTreeEdit Then If KeyPressed($VK_RETURN) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 0, 0) EndIf If KeyPressed($VK_ESCAPE) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 1, 0) EndIf EndIf Local $aRet = DllCall("user32.dll", "hwnd", "GetFocus") If $aRet[0] = $hWnd Then If KeyPressed($VK_INSERT) Then _GUICtrlTreeView_Add($hWnd, _GUICtrlTreeView_GetSelection($hWnd), "New Item") EndIf If KeyPressed($VK_DELETE) Then _GUICtrlTreeView_Delete($hWnd, _GUICtrlTreeView_GetSelection($hWnd)) EndIf If KeyPressed($VK_RETURN) Then _SendMessage($hWnd, $TVM_EDITLABEL, 0, _GUICtrlTreeView_GetSelection($hWnd)) EndIf EndIf EndFunc ;==>TreeKeyboardFunc Func TreeCreateDragImage($hWnd, $hItem) ConsoleWrite("TreeCreateDragImage( $hWnd=" & $hWnd & ", $hItem=" & $hItem & ")" & @LF) If Not $hWnd Or Not $hItem Then Return ;if treeview has imagelist, use image from it If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then Return _GUICtrlTreeView_CreateDragImage($hWnd, $hItem) EndIf ;if not, create a bitmap of dragitem's text rectangle and put it into imagelist. Local $aItemRect = _GUICtrlTreeView_DisplayRect($hWnd, $hItem, True) Local $iImgW = $aItemRect[2] - $aItemRect[0] Local $iImgH = $aItemRect[3] - $aItemRect[1] Local $hTreeDC = _WinAPI_GetDC($hWnd) Local $hMemDC = _WinAPI_CreateCompatibleDC($hTreeDC) Local $hMemBmp = _WinAPI_CreateCompatibleBitmap($hTreeDC, $iImgW, $iImgH) Local $hMemBmpOld = _WinAPI_SelectObject($hMemDC, $hMemBmp) _WinAPI_BitBlt($hMemDC, 0, 0, $iImgW, $iImgH, $hTreeDC, $aItemRect[0], $aItemRect[1], $SRCCOPY) _WinAPI_SelectObject($hMemDC, $hMemBmpOld) _WinAPI_ReleaseDC($hWnd, $hTreeDC) _WinAPI_DeleteDC($hMemDC) Local $hImgList = _GUIImageList_Create($iImgW, $iImgH, 6) _GUIImageList_Add($hImgList, $hMemBmp) _WinAPI_DeleteObject($hMemBmp) ConsoleWrite("TreeCreateDragImage.$hImgList=" & $hImgList & @LF) Return $hImgList EndFunc ;==>TreeCreateDragImage ; #FUNCTION# ==================================================================================================================== ; Name ..........: DrawDragImage ; Description ...: ; Syntax ........: DrawDragImage(Byref $hControl, Byref $aDrag) ; Parameters ....: $hControl - [in/out] a handle value. ; $aDrag - [in/out] an array of unknowns. ; Return values .: None ; Author ........: Gary Frost ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func DrawDragImage(ByRef $hControl, ByRef $hImageList) ConsoleWrite("DrawDragImage( $hControl=" & $hControl & ", $hImageList=" & $hImageList & ")" & @LF) Local $tPoint, $hDC $hDC = _WinAPI_GetWindowDC($hControl) $tPoint = _WinAPI_GetMousePos(True, $hControl) _WinAPI_InvalidateRect($hControl) _GUIImageList_Draw($hImageList, 0, $hDC, DllStructGetData($tPoint, "X") - 10, DllStructGetData($tPoint, "Y") - 8) _WinAPI_ReleaseDC($hControl, $hDC) EndFunc ;==>DrawDragImage ; sometimes I see a bug, the random function is called ; this function exist to detect this bug Func Function1() ConsoleWrite("Function1" & @LF) EndFunc ;==>Function1 Func Function2() ConsoleWrite("Function2" & @LF) EndFunc ;==>Function2 Func Function3() ConsoleWrite("Function3" & @LF) EndFunc ;==>Function3 Func Function4() ConsoleWrite("Function4" & @LF) EndFunc ;==>Function4 Func Function5() ConsoleWrite("Function5" & @LF) EndFunc ;==>Function5 Func Function6() ConsoleWrite("Function6" & @LF) EndFunc ;==>Function6 Func Function7() ConsoleWrite("Function7" & @LF) EndFunc ;==>Function7 Func Function8() ConsoleWrite("Function8" & @LF) EndFunc ;==>Function8 Func OnExit() GUISetState($hGui, @SW_HIDE) GUIDelete($hGui) EndFunc ;==>OnExit Func Quit() Exit EndFunc ;==>Quit #Region _DUMMY Func _CreateDummy(ByRef $dummy, ByRef $context, ByRef $menu, $cmd) Local $aDummy[1][3] _ArrayAdd($aDummy, $cmd, Default, "=", ";") $dummy = GUICtrlCreateDummy() $context = GUICtrlCreateContextMenu($dummy) $menu = GUICtrlGetHandle($context) For $ii = 1 To UBound($aDummy, 1) - 1 $aDummy[$ii][2] = GUICtrlCreateMenuItem($aDummy[$ii][0], $context) If $aDummy[$ii][1] Then GUICtrlSetOnEvent($aDummy[$ii][2], $aDummy[$ii][1]) Next EndFunc ;==>_CreateDummy #EndRegion _DUMMY Func Context_Add() ConsoleWrite("Context_Add" & @LF) EndFunc ;==>Context_Add Func Context_AddRoot() ConsoleWrite("Context_AddRoot" & @LF) EndFunc ;==>Context_AddRoot Func Context_Update() ConsoleWrite("Context_Update" & @LF) EndFunc ;==>Context_Update Func Context_Del() ConsoleWrite("Context_Del" & @LF) EndFunc ;==>Context_Del Func Context_Copy() ConsoleWrite("Context_Copy" & @LF) EndFunc ;==>Context_Copy Edited November 30, 2016 by Luigi Letraindusoir 1 Visit my repository Link to comment Share on other sites More sharing options...
Letraindusoir Posted September 10, 2019 Share Posted September 10, 2019 Why don't continue to improve it? it's a good extended application of a treeView. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now