Что нового

Перемещение элементов по TreeView

Статус
Закрыто для дальнейших ответов.

over7

Новичок
Сообщения
11
Репутация
2
Доброго времени суток!

Пишу функцию для создания и изменения структуры по типу дерева.
Сейчас борюсь с перемещением элементов по дереву.

На основе примера уважаемого AZJIO >>http://autoit-script.ru/index.php/topic,12101.0.html
составил код привожу ниже.

Вопрос первый.
Я перемещаю элементы переименованием и переносом дочерних ветвей элементов.
Есть ли другой более простой, более правильный способ?

Вопрос второй.
Скрипт работает для всех элементов кроме верхнего базового и нижнего базового.
(под базовыми элементами имею ввиду элементы, у которых "родитель" =0).
Как определить самый верхний и самый нижний в дереве базовые элементы?

Для демонстрации проблемы
замените строчку
Код:
$FirstLevel = GUICtrlCreateTreeViewItem($LngItm &  $i, $Root)

на
Код:
$FirstLevel = GUICtrlCreateTreeViewItem($LngItm &  $i, $iTreeView)

и закомментируйте строку
Код:
If $hParent=  0 Then Return

в функции _TreeViewItemMove

Код:
Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>

; En
$LngTitle = 'TreeView'
$LngPath  = 'Path'
$LngInd   = 'Index'
$LngDel   = 'Delete'
$LngItm   = 'Item'
$LngUP    = 'Item Up'
$LngDown  = 'Item Down'

; Ru
If @OSLang = 0419 Then
   $LngTitle = 'TreeView'
   $LngPath  = 'Путь из имён'
   $LngInd   = 'Путь из индексов'
   $LngDel   = 'Удалить'
   $LngItm   = 'П.'
   $LngUP    = 'Вверх'
   $LngDown  = 'Вниз'
EndIf

$hGui = GUICreate($LngTitle, 350, 375, -1, -1, $WS_OVERLAPPEDWINDOW)
Global $iTreeView = GUICtrlCreateTreeView(1, 1, 350, 375) 
GUICtrlSetFont(-1, 12, 400, 0, "Verdana")
GUICtrlSetResizing(-1, 2 +4 + 32 + 64 + 256)
Global $hTreeView = GUICtrlGetHandle(-1)

; Создаём пункты дерева
Global $Root = GUICtrlCreateTreeViewItem("\", $iTreeView)
For $i = 0 To 9
    $FirstLevel = GUICtrlCreateTreeViewItem($LngItm &  $i, $Root)
    For $j = 0 To 3
        $SndLevel = GUICtrlCreateTreeViewItem($LngItm &  $i & "." & $j, $FirstLevel)
	    For $k = 0 To 9
           GUICtrlCreateTreeViewItem($LngItm & $i & "."& $j & "." & $k, $SndLevel)
	    Next
    Next
Next



$iDummy = GUICtrlCreateDummy()

$ContMenu = GUICtrlCreateContextMenu($iDummy)
$hMenu = GUICtrlGetHandle($ContMenu)
$iCM_Up = GUICtrlCreateMenuItem($LngUP & @TAB & 'Shift+UP', $ContMenu)
$iCM_Down = GUICtrlCreateMenuItem($LngDown& @TAB & 'Shift+Down', $ContMenu)
$iCM_Path = GUICtrlCreateMenuItem($LngPath & @TAB & 'Enter', $ContMenu)
$iCM_Ind = GUICtrlCreateMenuItem($LngInd & @TAB & 'Ctrl+Enter', $ContMenu)
$iCM_Del = GUICtrlCreateMenuItem($LngDel & @TAB & 'Ctrl+Del', $ContMenu)

; установка горячих клавиш на пункты контекстного меню
Dim $AccelKeys[5][2] = 	 [  ["+{UP}"   	, $iCM_Up    ], _
						    ["+{DOWN}" 	, $iCM_Down  ], _
						    ["{Enter}" 	, $iDummy    ], _
						    ["^{DEL}"  	, $iCM_Del   ], _
						    ["^{Enter}"	, $iCM_Ind   ]  ] 
GUISetAccelerators($AccelKeys)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState()
GUICtrlSetState($Root, $GUI_EXPAND)


While 1
    Switch GUIGetMsg()
		 Case  $iCM_Up
			_TreeViewItemMove($hTreeView,1)
		 Case  $iCM_Down
			_TreeViewItemMove($hTreeView,-1)
         Case $iCM_Path
            _OpenExplorer()
         Case $iCM_Del
            $hItem = _GUICtrlTreeView_GetSelection($hTreeView)
            _GUICtrlTreeView_Delete($hTreeView, $hItem)
         Case $iCM_Ind
			MsgBox(0, 'Сообщение', ControlTreeView($hGui, '', 'SysTreeView321', 'GetSelected', 1), 0, $hGui)
         Case $iDummy ; Событие по кнопке Enter, и действие взависимости от того, какой элемент в фокусе
            MsgBox(0, 'Сообщение', ControlTreeView($hGui, '', 'SysTreeView321', 'GetSelected'), 0, $hGui)
         Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

Exit ;==>MainProgram

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hTreeView
            Switch $iCode
                Case $NM_RCLICK ; Вызов контекстного меню правой кнопкой мыши
                    Local $tMPos = _WinAPI_GetMousePos(True, $hWndFrom) ; координаты относительно элемента
                    Local $hItem = _GUICtrlTreeView_HitTestItem($hWndFrom, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) ; получаем дескриптор пункта
                    If $hItem > 0 Then ; проверка, чтобы вызов был на пункте
                        $x = MouseGetPos(0)
                        $y = MouseGetPos(1)
                        _GUICtrlTreeView_SelectItem($hTreeView, $hItem)
						; заставляет появится меню в указанных координатах
                        DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hGui, "ptr", 0) 
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
 EndFunc   ;==>WM_NOTIFY
 
Func _TreeViewItemMove($hWnd,$way)
	; "двигаем" выделенный элемент TreeView вверх ($way =1) или вниз($way= -1)
	
   $hItem = _GUICtrlTreeView_GetSelection($hWnd) ; получаем выделенный элемент
   $sItem = _GUICtrlTreeView_GetText($hWnd ,$hItem) 
   $hParent =_GUICtrlTreeView_GetParentHandle($hWnd ,$hItem)
   If $hParent=  0 Then Return
	
   If $way > 0 Then
	  ; направление вверх
	  If $hItem =  _GUICtrlTreeView_GetFirstChild($hWnd, $hParent) Then Return ; если первый ребенок
	  $hItemBro=  _GUICtrlTreeView_GetPrev($hWnd, $hItem) 
	  While $hParent <> _GUICtrlTreeView_GetParentHandle($hWnd, $hItemBro); ищу старшего брата по общему предку
		 $hItemBro=  _GUICtrlTreeView_GetPrev($hWnd, $hItemBro)
	  WEnd 
   Else
	  ; направление вниз
	  If $hItem =  _GUICtrlTreeView_GetLastChild($hWnd, $hParent) Then Return ; если последний ребенок 
		 $hItemBro =  _GUICtrlTreeView_GetNext($hWnd, $hItem) 
		 While $hParent <> _GUICtrlTreeView_GetParentHandle($hWnd, $hItemBro); ищу младшего брата по общему предку
			$hItemBro =  _GUICtrlTreeView_GetNext($hWnd, $hItemBro)
		 WEnd 
   EndIf
   $sItemBro = _GUICtrlTreeView_GetText($hWnd ,$hItemBro) ; имя брата
	
	_GUICtrlTreeView_SetText($hWnd ,$hItemBro, $sItem ) ; становлюсь на место брата
	_GUICtrlTreeView_SetText($hWnd ,$hItem, $sItemBro) 
	
   ;  обмен детьми
   $nChildrenItemBro =  _GUICtrlTreeView_GetChildCount($hWnd, $sItemBro) 
   If $nChildrenItemBro Then
	  $hTMP = _GUICtrlTreeView_AddChild($hWnd, $hParent, "") ; времянка для детей брата
	  _MoveTreeChildern($hWnd, $hItemBro, $hTMP)
   EndIf
	
   If _GUICtrlTreeView_GetChildCount($hWnd, $hItem) Then
	  _MoveTreeChildern($hWnd, $hItem , $hItemBro)
   EndIf
	
   If $nChildrenItemBro Then
	  _MoveTreeChildern($hWnd, $hTMP , $hItem)
	  _GUICtrlTreeView_Delete($hWnd, $hTMP)
   EndIf
	 
   ;перемещаю выделение
   _GUICtrlTreeView_SetState($hWnd, $hItem    , $TVIS_SELECTED,0) 
   _GUICtrlTreeView_SetState($hWnd, $hItemBro , $TVIS_SELECTED,1) 
   _GUICtrlTreeView_ClickItem($hWnd, $hItemBro)
	
EndFunc ;==>_TreeViewItemMove

Func _MoveTreeChildern($hWnd, $hItemA , $hItemB)
   ; переносим дерево с дочерними элементами из $hItemA в $hItemB
   If _GUICtrlTreeView_GetChildCount($hWnd, $hItemA) Then
	  For $i = 1 To _GUICtrlTreeView_GetChildCount($hWnd, $hItemA)
		 $hChildItem = _GUICtrlTreeView_GetLastChild($hWnd, $hItemA)
		 $hChildMove = _GUICtrlTreeView_AddChildFirst($hWnd, $hItemB, _GUICtrlTreeView_GetText($hWnd ,$hChildItem))
		 _MoveTreeChildern($hWnd,$hChildItem,$hChildMove)
		 _GUICtrlTreeView_Delete($hWnd , $hChildItem)
	  Next
   Else
	  _GUICtrlTreeView_AddChildFirst($hWnd, $hItemB, _GUICtrlTreeView_GetText($hWnd ,$hItemA))
	  _GUICtrlTreeView_Delete($hWnd, $hItemA)
   EndIf
EndFunc ;==>_MoveTreeChildern
 

erlik

Продвинутый
Сообщения
317
Репутация
84
Скрипт вышеприведенный не разбирал, но я так получил и базовый верхний и базовый нижний элемент:
Код:
Local $hFirstVisible = _SendMessage($hTreeViewDll, $TVM_GETNEXTITEM, $TVGN_FIRSTVISIBLE, 0, 0, "wparam", "lparam", "handle"); самый первый - он же первый базовый
Local $hLastVisible  = _SendMessage($hTreeViewDll, $TVM_GETNEXTITEM, $TVGN_LASTVISIBLE, 0, 0, "wparam", "lparam", "handle"); самый последний элемент в дереве - получаем его родителя - это есть последний базовый элемент.
Local $hLastBase=_GUICtrlTreeView_GetParentHandle($hTreeViewDll, $hLastVisible)

-------------------------------
$TVGN_FIRSTVISIBLE можно заменить на $TVGN_ROOT - хотя разницы никакой.
А функцию _GUICtrlTreeView_GetParentHandle на
Код:
_SendMessage($hTreeViewDll, $TVM_GETNEXTITEM, $TVGN_PARENT, $hLastVisible, 0, "wparam", "handle", "handle")
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Исправленный пример с оф. сайта (перемещение пунктов через Dragp & Drop):

Код:
#include <GUITreeView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.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_BEGINDRAGA, $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_BEGINLABELEDITA, $TVN_BEGINLABELEDITW
                $bTreeEdit = True
;~              $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0)
            Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW
                $bTreeEdit = False
                Return 1
            Case $TVN_SELCHANGEDA, $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_EDITLABELA, 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
 
Автор
O

over7

Новичок
Сообщения
11
Репутация
2
Крутяк :laugh:

CreatoR, Большое спасибо!!)
erlik, Спасибо за участие))

:IL_AutoIt_1:
 

MishkaS

Новичок
Сообщения
2
Репутация
0
Re: Перемещение элементов по TreeView (ручная сортировка)

Здравствуйте, подскажите, пожалуйста, как упростить код до одноуровнего списка и можно ли вместо пунктов списка использовать изображения?
п.с. :smile: и можно ли из проводника винды затащить туда название файла?

CreatoR сказал(а):
Исправленный пример с оф. сайта (перемещение пунктов через Dragp & Drop):
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
MishkaS

Предупреждение За нарушение общих правил (пункт В.4):
Не лепите несколько вопросов разной тематики в один пост. По типу "Ребят, а ещё такой вопрос...". Каждый вопрос в свою тему.


С уважением, ваш Глобальный модератор.
 
Статус
Закрыто для дальнейших ответов.
Верх