Siao Posted November 4, 2007 Share Posted November 4, 2007 (edited) Make sure you have v3.2.9.5 or later...Full drag and drop reordering of items, both with images and no images. Item will be moved to InsertMark position or into drop highlighted item.Label edit (either mouse or keyboard Enter/Esc).Keyboard Delete to delete selected item.Keyboard Insert to insert new item after selected item.expandcollapse popup#include <GuiTreeView.au3> Opt("GUICloseOnESC", 0) Opt("GUIOnEventMode", 1) $sTitle = "Treeview Drag & Drop Editing" ;Required global constants: Global $bTreeDrag = False, $bTreeEdit = False, $hDragItem, $hTreeDragImage, $fWhere $hGui = GUICreate($sTitle, 400, 300, -1, -1, -1, -1) $label = GUICtrlCreateLabel("Drag and drop separate items or branches to move them." & _ @LF & "To start edit selected item, LMB on item or press Enter." & _ @LF & "To end editing, LMB outside item (apply) or Esc (cancel) / Enter (apply)." & _ @LF & "To insert new item press Insert, to delete existing item press Delete.", 30, 10, 340, 60) $cTree = GUICtrlCreateTreeView(50,75,300,200,$TVS_HASBUTTONS+$TVS_HASLINES+$TVS_LINESATROOT+$TVS_EDITLABELS+$TVS_CHECKBOXES) GUICtrlSetState(-1, $GUI_DROPACCEPTED) $cTreeItemsStart = GUICtrlCreateDummy() $cTreeItem_1 = GUICtrlCreateTreeViewItem("item 1", $cTree) $cTreeItem_1a = GUICtrlCreateTreeViewItem("item 1a", $cTreeItem_1) $cTreeItem_1b = GUICtrlCreateTreeViewItem("item 1b", $cTreeItem_1) $cTreeItem_2 = GUICtrlCreateTreeViewItem("item 2", $cTree) $cTreeItem_2a = GUICtrlCreateTreeViewItem("item 2a", $cTreeItem_2) $cTreeItem_3 = GUICtrlCreateTreeViewItem("item 3", $cTree) $cTreeItem_3a = GUICtrlCreateTreeViewItem("item 3a", $cTreeItem_3) $cTreeItem_3a1 = GUICtrlCreateTreeViewItem("item 3a1", $cTreeItem_3a) $cTreeItem_4 = GUICtrlCreateTreeViewItem("item 4", $cTree) $cTreeItemsEnd = GUICtrlCreateDummy() ;treeview with images test: ;~ $hImgList = _GUIImageList_Create (16, 16) ;~ For $ii = 1 To $cTreeItemsEnd-$cTreeItemsStart ;~ _GUIImageList_AddIcon ($hImgList, "shell32.dll", 60+$ii*2) ;~ Next ;~ _GUICtrlTreeView_SetNormalImageList(GUICtrlGetHandle($cTree), $hImgList) ;~ $a = 0 ;~ For $i = $cTreeItemsStart+1 To $cTreeItemsEnd-1 ;~ _GUICtrlTreeView_SetImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a) ;~ _GUICtrlTreeView_SetSelectedImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a) ;~ $a += 1 ;~ Next $label2 = GUICtrlCreateLabel("", 50, 280, 300, 15) GUISetOnEvent($GUI_EVENT_CLOSE, "SysEvents") GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SysEvents") GUIRegisterMsg($WM_NOTIFY, "On_WM_NOTIFY") GUISetState() While 1 Sleep(200) ;add Enter, Esc, Delete and Insert key functionality to treeview edit: TreeKeyboardFunc($cTree) WEnd Func SysEvents() Local $hTree = GUICtrlGetHandle($cTree) Switch @GUI_CtrlId Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_PRIMARYUP If $bTreeDrag Then _WinAPI_InvalidateRect($hTree) $bTreeDrag = False _GUIImageList_Destroy($hTreeDragImage) ;delete drag image _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark 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) _GUIImageList_Destroy($hTreeDragImage) ;delete drag image _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark 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) _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, $hItemHover) ;add InsertMark before item $fWhere = -1 Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) ;add DropTarget $fWhere = 0 Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3] _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 1, $hItemHover) ;add InsertMark after item $fWhere = 1 EndSwitch EndIf DrawDragImage($hTree, $hTreeDragImage) EndSwitch EndFunc ; 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 ; 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: $hTest = $hItemTarget Do $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest) If $hTest = $hItemSource Then Return 0 Until $hTest = 0 ;create new item at determined position $sText = _GUICtrlTreeView_GetText($hWnd, $hItemSource) $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 Func On_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) ;wparam = cid, lparam = pnmh If $wParam = $cTree Then Local $tNMHDR = DllStructCreate("hwnd hTree;uint;int code", $lParam) Local $code = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $code 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 ; EndIf EndFunc 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 Func TreeKeyboardFunc($cID) Local $hWnd = GUICtrlGetHandle($cID) If $bTreeDrag Then Return If $bTreeEdit Then If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 0, 0) ;enter If KeyPressed(0x1b) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 1, 0) ;esc EndIf Local $aRet = DllCall('user32.dll', 'hwnd', 'GetFocus') If $aRet[0] = $hWnd Then If KeyPressed(0x2d) Then _GUICtrlTreeView_Add($hWnd, _GUICtrlTreeView_GetSelection($hWnd), "New Item") ;insert If KeyPressed(0x2e) Then _GUICtrlTreeView_Delete($hWnd, _GUICtrlTreeView_GetSelection($hWnd)) ;delete If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_EDITLABEL, 0, _GUICtrlTreeView_GetSelection($hWnd)) ;enter EndIf EndFunc 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 ; 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 Edited January 4, 2008 by Siao Letraindusoir 1 "be smart, drink your wine" Link to comment Share on other sites More sharing options...
XxXFaNtA Posted November 4, 2007 Share Posted November 4, 2007 >Running AU3Check (1.54.9.0) from:E:\Programme\AutoIt3 E:\Dokumente und Einstellungen\Fanta\Lokale Einstellungen\Temp\temp-37.au3(13,108) : WARNING: $TVS_EDITLABELS: possibly used before declaration. $cTree = GUICtrlCreateTreeView(50,50,300,200,$TVS_HASBUTTONS+$TVS_HASLINES+$TVS_LINESATROOT+$TVS_EDITLABELS+ Do I need the newest beta? /[center][/center] Link to comment Share on other sites More sharing options...
Siao Posted November 4, 2007 Author Share Posted November 4, 2007 (edited) Do I need the newest beta? If you want to avoid trouble fixing stuff like above, yes, using the latest beta is strongly recommended. I used v3.2.9.5 myself.Although if AU3Check gives you only one error which you posted, you can define that constant yourselfGlobal Const $TVS_EDITLABELS = 0x8 Edited November 4, 2007 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
JustinReno Posted November 4, 2007 Share Posted November 4, 2007 Isn't the latest beta 3.2.9.6? Link to comment Share on other sites More sharing options...
ken82m Posted January 12, 2009 Share Posted January 12, 2009 any idea how to do this in a list box? lol I've found examples on how to do one or the other but not both "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains." 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