Jump to content

Treeview with Edit and Drag 'n Drop whithin


ReFran
 Share

Recommended Posts

Hi,

attached an exampel of a treeview from sandin,

http://www.autoitscript.com/forum/index.php?showtopic=85846

where the items can be moved with drag and drop.

Unfortunately the items can only be moved within the visible tree - not autoscroll.

I looked into it for getting it autoscrolled, but without success.

Any help - or another working example - would be fine.

best regards, Reinhard

;; treeview edit items and move by drag 'n drop
;;written by sandin

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>
#include <Constants.au3>

DIM $TVN_BEGINDRAG
DIM $TVN_BEGINLABELEDIT
DIM $TVN_ENDLABELEDIT


Opt("PixelCoordMode", 2)
Global $Startx, $Starty, $Endx, $Endy, $aM_Mask, $aMask, $nc
Global Const $VK_F2 = 0x71
Global Const $VK_ESC = 0x1B
Global $just_edited = False, $fDragging = False, $hDragItem, $fWhere, $moving_txt, $item_above_drag, $item_below_drag
Opt("GUICloseOnESC", 0)
Global $iEditFlag = 0
$hGUI = GUICreate("Test GUI", 300, 200)
GUICtrlCreateLabel("F2 - Edit text, Enter - Set text, ESC - Cancel edit", 16, 10, 250, 16)
$hTreeView = _GUICtrlTreeView_Create($hGUI, 10, 40, 280, 140, _
BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVIS_DROPHILITED, 

$TVS_SHOWSELALWAYS, $WS_TABSTOP), $WS_EX_CLIENTEDGE)
For $i = 1 To 5
    $hItem = _GUICtrlTreeView_Add($hTreeView, $i, "Item" & $i)
    For $j = 1 To 5
        _GUICtrlTreeView_AddChild($hTreeView, $hItem, "SubItem" & $j)
    Next
Next
GUISetState(@SW_SHOW, $hGUI)
$position = WinGetPos($hGUI)
$client = WinGetClientSize($hGUI)
$light_border = ($position[2]-$client[0])/2
$thick_border = $position[3]-$client[1]-$light_border
$x_coord = $position[0]+$light_border
$y_coord = $position[1]+$thick_border
Global $gw = 16
Global $gh = 16
$drag_gui = GUICreate("Drag", $gw, $gh, $x_coord, $y_coord, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST), 

$hGUI)
$cursor_icon = GUICtrlCreateIcon("Shell32.dll", -147, 0, 0, 16, 16)
GUISetState(@SW_SHOW, $drag_gui)
setTrans()
GUISetState(@SW_HIDE, $drag_gui)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$wProcHandle = DllCallbackRegister("_WindowProc", "int", "hwnd;uint;wparam;lparam")
$wProcOld = _WinAPI_SetWindowLong($hTreeView, $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))
Func setTrans()
    $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 460, "long", 460)
    $rct = DllStructCreate("int;int;int;inr", $aM_Mask[0])
    $TestCol = PixelGetColor(0, 0)
    $Startx = -1
    $Starty = -1
    $Endx = 0
    $Endy = 0
    For $i = 0 To $gw
        For $j = 0 To $gh
            If PixelGetColor($i, $j) = $TestCol And $j < $gh Then
                If $Startx = -1 Then
                    $Startx = $i
                    $Starty = $j
                    $Endx = $i
                    $Endy = $j
                Else
                    $Endx = $i
                    $Endy = $j
                EndIf
            Else
                If $Startx <> -1 Then addRegion()
                $Startx = -1
                $Starty = -1
            EndIf
        Next
    Next
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $drag_gui, "long", $aM_Mask[0], "int", 1)
EndFunc
Func addRegion()
    $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $Startx, "long", $Starty, "long", $Endx + 1, "long", $Endy + 1)
    $nc += 1
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 3)
EndFunc
While 1
    if $fDragging = True then chase()
    if $just_edited = True Then
        $just_edited = False
        ConsoleWrite("New txt: " & _GUICtrlTreeView_GetText($hTreeView, _GUICtrlTreeView_GetSelection($hTreeView)) & @CRLF)
    EndIf
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            _WinAPI_SetWindowLong($hTreeView, $GWL_WNDPROC, $wProcOld)
            DllCallbackFree($wProcHandle)
            Exit
        case $GUI_EVENT_MOUSEMOVE
            If $fDragging = False Then ContinueCase
            $hItemHover = TreeItemFromPoint($hTreeView)
            If $hItemHover <> 0 Then
                $aRect = _GUICtrlTreeView_DisplayRect($hTreeView, $hItemHover)
                $iTreeY = _WinAPI_GetMousePosY(True, $hTreeView)
                Switch $iTreeY
                    Case $aRect[1] To $aRect[1]+Int(($aRect[3]-$aRect[1])/4)
                        if $fWhere <> -1 Then
                            _GUICtrlTreeView_SetInsertMark($hTreeView, $hItemHover, False)
                            $fWhere = -1
                        EndIf
                    Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3)
                        if $fWhere <> 0 Then
                            _SendMessage($hTreeView, $TVM_SETINSERTMARK, 0, 0)
                            $fWhere = 0
                        EndIf
                    Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3]
                        if $fWhere <> 1 Then
                            _GUICtrlTreeView_SetInsertMark($hTreeView, $hItemHover)
                            $fWhere = 1
                        EndIf
                EndSwitch
            EndIf
        Case $GUI_EVENT_PRIMARYUP   
            If $fDragging Then
                ToolTip("")
                _WinAPI_InvalidateRect($hTreeView)
                $fDragging = False
                GUISetState(@SW_HIDE, $drag_gui)
                _WinAPI_ShowCursor(True)
                _SendMessage($hTreeView, $TVM_SETINSERTMARK, 0, 0)
                If (TreeItemFromPoint($hTreeView) = $hDragItem) Then ContinueCase
                if TreeItemFromPoint($hTreeView) = $item_above_drag AND $fWhere = 1 then ContinueCase
                if TreeItemFromPoint($hTreeView) = $item_below_drag AND $fWhere = -1 then ContinueCase
                if $fWhere <> 0 then
                    $hItem = TreeItemCopy($hTreeView, $hDragItem, TreeItemFromPoint($hTreeView), $fWhere)
                    If $hItem <> 0 Then
                        _GUICtrlTreeView_SelectItem($hTreeView, $hItem)
                        _GUICtrlTreeView_Delete($hTreeView, $hDragItem)
                    EndIf
                EndIf
            EndIf
    EndSwitch
WEnd
Func TreeItemCopy($hWnd, $hItemSource, $hItemTarget, $fDirection)
    $hTest = $hItemTarget
    Do
        $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest)
        If $hTest = $hItemSource Then Return 0
    Until $hTest = 0
    $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
    _GUICtrlTreeView_SetState($hWnd, $hNew, _GUICtrlTreeView_GetState($hWnd, $hItemSource))
    If _GUICtrlTreeView_GetStateImageList($hWnd) <> 0 Then
        _GUICtrlTreeView_SetStateImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItemSource))
    EndIf
    If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then
        _GUICtrlTreeView_SetImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetImageIndex($hWnd, $hItemSource))
        _GUICtrlTreeView_SetSelectedImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hWnd, $hItemSource))
    EndIf
    $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 TreeItemFromPoint($hWnd)
    Local $tMPos = _WinAPI_GetMousePos(True, $hWnd)
    Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
EndFunc
func GetNeighbourItem($hWnd, $hItemTarget, $above = True)
    if $above = True Then
        Local $hPrev = _GUICtrlTreeView_GetPrevSibling($hWnd, $hItemTarget)
        Return $hPrev
    Else
        Local $hNext = _GUICtrlTreeView_GetNextSibling($hWnd, $hItemTarget)
        Return $hNext
    EndIf
EndFunc
Func chase()
    $mp = MouseGetPos()
    WinMove($drag_gui, "", $mp[0] + 1, $mp[1] + 0)
    tooltip($moving_txt, $mp[0]+18, $mp[1])
EndFunc
Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $HwndFrom, $iCode, $tInfo
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $HwndFrom = DllStructGetData($tNMHDR, "HwndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $HwndFrom
        Case $hTreeView
            Switch $iCode
                Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW
                    Local $tInfo = DllStructCreate($tagNMTREEVIEW, $lParam)
                    Local $hNewItem = DllStructGetData($tInfo, "NewhItem")
                    _GUICtrlTreeView_SelectItem($hTreeView, $hNewItem)
                    $fDragging = True
                    $moving_txt = "Moving: " & _GUICtrlTreeView_GetText($hTreeView, $hNewItem)
                    _WinAPI_ShowCursor(False)
                    GUISetState(@SW_SHOW, $drag_gui)
                    HotKeySet("{Esc}", "_cancel_dragging2")
                    tooltip($moving_txt, MouseGetPos(0)+18, MouseGetPos(1))
                    $hDragItem = TreeItemFromPoint($hTreeView)
                    $item_above_drag = GetNeighbourItem($hTreeView, $hDragItem)
                    $item_below_drag = GetNeighbourItem($hTreeView, $hDragItem, false)
                Case $NM_RCLICK
                    if $fDragging = True Then
                        _cancel_dragging()
                    Else
                        Local $tInfo = DllStructCreate($tagNMTREEVIEW, $lParam)
                        Local $hNewItem = DllStructGetData($tInfo, "NewParam")
                        ConsoleWrite(_GUICtrlTreeView_GetText($hTreeView, $hNewItem) & ", ")
                        _GUICtrlTreeView_SelectItem($hTreeView, $hNewItem)
                    EndIf
                Case $TVN_ENDLABELEDIT, $TVN_ENDLABELEDITW
                    HotKeySet("{Enter}")
                    HotKeySet("{Esc}")
                    If $iEditFlag Then
                        $iEditFlag = 0
                        Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
                        Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax") & "]")
                        If Not _GUICtrlTreeView_GetUnicodeFormat($HwndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
                        DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))
                        If StringLen(DllStructGetData($sBuffer, "Text")) Then
                            $just_edited = true
                            Return 1
                        EndIf
                    EndIf
                Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW
                    HotKeySet("{Enter}", "_TextSet")
                    HotKeySet("{Esc}", "_EditClose")
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc
Func _cancel_dragging2()
    if $fDragging = True then _cancel_dragging()
EndFunc
Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    Switch $hWnd
        Case $hTreeView
            Switch $Msg
                Case $WM_GETDLGCODE
                    Switch $wParam
                        case $VK_F2
                            _TextEdit()
                    EndSwitch
            EndSwitch
    EndSwitch
    Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $Msg, $wParam, $lParam)
EndFunc
func _cancel_dragging()
    HotKeySet("{Esc}")
    $fDragging = False
    GUISetState(@SW_HIDE, $drag_gui)
    _WinAPI_ShowCursor(True)
    ToolTip("")
    _WinAPI_InvalidateRect($hTreeView)
    _SendMessage($hTreeView, $TVM_SETINSERTMARK, 0, 0)
EndFunc
Func _TextEdit()
    Local $hItem = _GUICtrlTreeView_GetSelection($hTreeView)
    If $hItem Then _GUICtrlTreeView_EditText($hTreeView, $hItem)
EndFunc
Func _TextSet()
    $iEditFlag = 1
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc
Func _EditClose()
    $iEditFlag = 0
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc
Edited by ReFran
Link to comment
Share on other sites

Ok, done!

If you expand the tv-items, now it you can be moved with autoscroll to bottom or top.

Autoscroll become active during moving when you reach the visible end or top +25.

- and that without flickering!

Looks now real good and more important: now it can be used in the real world.

Perhabs I comment it a little bit more in the future.

Enjoy, Reinhard

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>
#include <Constants.au3>
#include <SendMessage.au3>
#include <StructureConstants.au3>
#include <TreeViewConstants.au3>
#include <WinAPI.au3>
#include <GUIScrollBars.au3>
#include <ScrollBarConstants.au3>


;;Main scripting from Sandin
;;http://www.autoitscript.com/forum/index.php?showtopic=85846

DIM $TVN_BEGINDRAG
DIM $TVN_BEGINLABELEDIT
DIM $TVN_ENDLABELEDIT
DIM $vAutoSbDnEnd ;for vertical autoscroll - defined under begindrag
DIM $vAutoSbUpEnd ;for vertical autoscroll - defined under begindrag
DIM $vAutoSbValue = 1

Opt("PixelCoordMode", 2)
Global $Startx, $Starty, $Endx, $Endy, $aM_Mask, $aMask, $nc
Global Const $VK_F2 = 0x71
Global Const $VK_ESC = 0x1B
Global $just_edited = False, $fDragging = False, $hDragItem, $fWhere, $moving_txt, $item_above_drag, $item_below_drag
Opt("GUICloseOnESC", 0)
Global $iEditFlag = 0
$hGUI = GUICreate("Test GUI", 300, 200)
GUICtrlCreateLabel("F2 - Edit text, Enter - Set text, ESC - Cancel edit", 16, 10, 250, 16)

DIM $tvTop=40, $tvHt=140
$hTreeView = _GUICtrlTreeView_Create($hGUI, 10, $tvtop, 280, $tvHt, _
BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVIS_DROPHILITED, $TVS_SHOWSELALWAYS, $WS_TABSTOP), $WS_EX_CLIENTEDGE)

For $i = 1 To 5
    $hItem = _GUICtrlTreeView_Add($hTreeView, $i, "Item" & $i)
    For $j = 1 To 5
        _GUICtrlTreeView_AddChild($hTreeView, $hItem, "SubItem" & $i&"."&$j)
    Next
Next
GUISetState(@SW_SHOW, $hGUI)

$position = WinGetPos($hGUI)
$client = WinGetClientSize($hGUI)
$light_border = ($position[2]-$client[0])/2
$thick_border = $position[3]-$client[1]-$light_border
$x_coord = $position[0]+$light_border
$y_coord = $position[1]+$thick_border
Global $gw = 16
Global $gh = 16
$drag_gui = GUICreate("Drag", $gw, $gh, $x_coord, $y_coord, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST), $hGUI)
$cursor_icon = GUICtrlCreateIcon("Shell32.dll", -147, 0, 0, 16, 16)
GUISetState(@SW_SHOW, $drag_gui)
setTrans() ; for cursor Icon
GUISetState(@SW_HIDE, $drag_gui)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$wProcHandle = DllCallbackRegister("_WindowProc", "int", "hwnd;uint;wparam;lparam")
$wProcOld = _WinAPI_SetWindowLong($hTreeView, $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))

Func setTrans()
    $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 460, "long", 460)
    $rct = DllStructCreate("int;int;int;inr", $aM_Mask[0])
    $TestCol = PixelGetColor(0, 0)
    $Startx = -1
    $Starty = -1
    $Endx = 0
    $Endy = 0
    For $i = 0 To $gw
        For $j = 0 To $gh
            If PixelGetColor($i, $j) = $TestCol And $j < $gh Then
                If $Startx = -1 Then
                    $Startx = $i
                    $Starty = $j
                    $Endx = $i
                    $Endy = $j
                Else
                    $Endx = $i
                    $Endy = $j
                EndIf
            Else
                If $Startx <> -1 Then addRegion()
                $Startx = -1
                $Starty = -1
            EndIf
        Next
    Next
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $drag_gui, "long", $aM_Mask[0], "int", 1)
EndFunc

Func addRegion()
    $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $Startx, "long", $Starty, "long", $Endx + 1, "long", $Endy + 1)
    $nc += 1
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 3)
EndFunc

While 1

    if $fDragging = True then
        chase() ;; moves cursor icon and drag-gui with mousemove
    endif
    if $just_edited = True Then
        $just_edited = False
        ConsoleWrite("New txt: " & _GUICtrlTreeView_GetText($hTreeView, _GUICtrlTreeView_GetSelection($hTreeView)) & @CRLF)
    EndIf
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            _WinAPI_SetWindowLong($hTreeView, $GWL_WNDPROC, $wProcOld)
            DllCallbackFree($wProcHandle)
            Exit
        case $GUI_EVENT_MOUSEMOVE
            If $fDragging = False Then ContinueCase
            $hItemHover = TreeItemFromPoint($hTreeView)
            If $hItemHover <> 0 Then
                $aRect = _GUICtrlTreeView_DisplayRect($hTreeView, $hItemHover)
                $iTreeY = _WinAPI_GetMousePosY(True, $hTreeView)
                Switch $iTreeY
                    Case $aRect[1] To $aRect[1]+Int(($aRect[3]-$aRect[1])/4)
                        if $fWhere <> -1 Then
                            _GUICtrlTreeView_SetInsertMark($hTreeView, $hItemHover, False)
                            $fWhere = -1
                        EndIf
                    Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3)
                        if $fWhere <> 0 Then
                            _SendMessage($hTreeView, $TVM_SETINSERTMARK, 0, 0)
                            $fWhere = 0
                        EndIf
                    Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3]
                        if $fWhere <> 1 Then
                            _GUICtrlTreeView_SetInsertMark($hTreeView, $hItemHover)
                            $fWhere = 1
                        EndIf
                EndSwitch

           EndIf


        Case $GUI_EVENT_PRIMARYUP
            If $fDragging Then
                ToolTip("")
                _WinAPI_InvalidateRect($hTreeView)
                $fDragging = False
                GUISetState(@SW_HIDE, $drag_gui)
                _WinAPI_ShowCursor(True)
                _SendMessage($hTreeView, $TVM_SETINSERTMARK, 0, 0)
                If (TreeItemFromPoint($hTreeView) = $hDragItem) Then ContinueCase
                if TreeItemFromPoint($hTreeView) = $item_above_drag AND $fWhere = 1 then ContinueCase
                if TreeItemFromPoint($hTreeView) = $item_below_drag AND $fWhere = -1 then ContinueCase
                if $fWhere <> 0 then
                    $hItem = TreeItemCopy($hTreeView, $hDragItem, TreeItemFromPoint($hTreeView), $fWhere)
                    If $hItem <> 0 Then
                        _GUICtrlTreeView_SelectItem($hTreeView, $hItem)
                        _GUICtrlTreeView_Delete($hTreeView, $hDragItem)
                    EndIf
                EndIf
            EndIf
    EndSwitch
WEnd

Func TreeItemCopy($hWnd, $hItemSource, $hItemTarget, $fDirection)
    $hTest = $hItemTarget
    Do
        $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest)
        If $hTest = $hItemSource Then Return 0
    Until $hTest = 0
    $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
    _GUICtrlTreeView_SetState($hWnd, $hNew, _GUICtrlTreeView_GetState($hWnd, $hItemSource))
    If _GUICtrlTreeView_GetStateImageList($hWnd) <> 0 Then
        _GUICtrlTreeView_SetStateImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItemSource))
    EndIf
    If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then
        _GUICtrlTreeView_SetImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetImageIndex($hWnd, $hItemSource))
        _GUICtrlTreeView_SetSelectedImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hWnd, $hItemSource))
    EndIf
    $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 TreeItemFromPoint($hWnd)
    Local $tMPos = _WinAPI_GetMousePos(True, $hWnd)
    Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
EndFunc

func GetNeighbourItem($hWnd, $hItemTarget, $above = True)
    if $above = True Then
        Local $hPrev = _GUICtrlTreeView_GetPrevSibling($hWnd, $hItemTarget)
        Return $hPrev
    Else
        Local $hNext = _GUICtrlTreeView_GetNextSibling($hWnd, $hItemTarget)
        Return $hNext
    EndIf
EndFunc

Func chase()
    $mp = MouseGetPos()
    WinMove($drag_gui, "", $mp[0] + 1, $mp[1] + 0)
    tooltip($moving_txt, $mp[0]+18, $mp[1])
    ;tooltip($vAutoSbUpEnd&"<>"&$vAutoSbdnEnd&@lf&$mp[1], $mp[0]+18, $mp[1])
    if $mp[1] < $vAutoSbUpEnd and $mp[1] > $vAutoSbUpEnd-25 then TvVScroll(-$vAutoSbValue)
    if $mp[1] > $vAutoSbdnEnd and $mp[1] < $vAutoSbdnEnd+25 then TvVScroll(+$vAutoSbValue)


EndFunc

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $HwndFrom, $iCode, $tInfo
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $HwndFrom = DllStructGetData($tNMHDR, "HwndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $HwndFrom
        Case $hTreeView
            Switch $iCode
                Case $TVN_BEGINDRAG, $TVN_BEGINDRAGW
                    Local $tInfo = DllStructCreate($tagNMTREEVIEW, $lParam)
                    Local $hNewItem = DllStructGetData($tInfo, "NewhItem")
                    _GUICtrlTreeView_SelectItem($hTreeView, $hNewItem)
                    $fDragging = True
                    $moving_txt = "Moving: " & _GUICtrlTreeView_GetText($hTreeView, $hNewItem) & _
                    "";;_WinAPI_ShowCursor(False)
                    GUISetState(@SW_SHOW, $drag_gui)
                    HotKeySet("{Esc}", "_cancel_dragging2")
                    tooltip($moving_txt, MouseGetPos(0)+18, MouseGetPos(1))
                    $hDragItem = TreeItemFromPoint($hTreeView)
                    $item_above_drag = GetNeighbourItem($hTreeView, $hDragItem)
                    $item_below_drag = GetNeighbourItem($hTreeView, $hDragItem, false)
                    ;; for auto-scroll
                    $aWinpos =  WingetPos($hGUI)
                    $vAutoSbUpEnd = $aWinpos[1] + $tvTop+30 ;;for Wintitle
                    $vAutoSbDnEnd = $aWinpos[1] +$tvTop+20 +$tvHt
                Case $NM_RCLICK
                    if $fDragging = True Then
                        _cancel_dragging()
                    Else
                        Local $tInfo = DllStructCreate($tagNMTREEVIEW, $lParam)
                        Local $hNewItem = DllStructGetData($tInfo, "NewParam")
                        ConsoleWrite(_GUICtrlTreeView_GetText($hTreeView, $hNewItem) & ", ")
                        _GUICtrlTreeView_SelectItem($hTreeView, $hNewItem)
                    EndIf
                Case $TVN_ENDLABELEDIT, $TVN_ENDLABELEDITW
                    HotKeySet("{Enter}")
                    HotKeySet("{Esc}")
                    If $iEditFlag Then
                        $iEditFlag = 0
                        Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
                        Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax") & "]")
                        If Not _GUICtrlTreeView_GetUnicodeFormat($HwndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
                        DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))
                        If StringLen(DllStructGetData($sBuffer, "Text")) Then
                            $just_edited = true
                            Return 1
                        EndIf
                    EndIf
                Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW
                    HotKeySet("{Enter}", "_TextSet")
                    HotKeySet("{Esc}", "_EditClose")
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func _cancel_dragging2()
    if $fDragging = True then _cancel_dragging()
EndFunc

Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    Switch $hWnd
        Case $hTreeView
            Switch $Msg
                Case $WM_GETDLGCODE
                    Switch $wParam
                        case $VK_F2
                            _TextEdit()
                    EndSwitch
            EndSwitch
    EndSwitch
    Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $Msg, $wParam, $lParam)
EndFunc

func _cancel_dragging()
    HotKeySet("{Esc}")
    $fDragging = False
    GUISetState(@SW_HIDE, $drag_gui)
    _WinAPI_ShowCursor(True)
    ToolTip("")
    _WinAPI_InvalidateRect($hTreeView)
    _SendMessage($hTreeView, $TVM_SETINSERTMARK, 0, 0)
EndFunc

Func _TextEdit()
    Local $hItem = _GUICtrlTreeView_GetSelection($hTreeView)
    If $hItem Then _GUICtrlTreeView_EditText($hTreeView, $hItem)
EndFunc

Func _TextSet()
    $iEditFlag = 1
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc

Func _EditClose()
    $iEditFlag = 0
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc


func TvVScroll($val)
    $tSBI = DllStructCreate($tagSCROLLINFO)
    DllStructSetData($tSBI, 'cbSize', DllStructGetSize($tSBI))
    DllStructSetData($tSBI, 'fMask', $SIF_ALL)

    If _GUIScrollBars_GetScrollInfo($hTreeview, $SB_VERT, $tSBI) Then
        $iMax = DllStructGetData($tSBI, 'nMax')
        $iPos = DllStructGetData($tSBI, 'nPos')
        ;consolewrite($ipos&" > "&$iMax&@lf)
        if $val <0 and $ipos = 0 then return
        if $val >0 and $ipos+7 >= $iMax then return

        _GUICtrlTreeView_BeginUpdate($hTreeview)
        DllStructSetData($tSBI, 'nPos', $ipos+$val)
        _GUIScrollBars_SetScrollInfo($hTreeview, $SB_VERT, $tSBI)
        _GUICtrlTreeView_EndUpdate($hTreeview)
    Else
        ConsoleWrite('Error' & @LF)
    EndIf

    $tSbi = 0
endfunc
Edited by ReFran
Link to comment
Share on other sites

  • Moderators

ReFran,

Very nice. Thanks for sharing! :mellow:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

By the way,

I tested the autoscroll with very simple Treeview/Listviews.

For this kind of views it is very simple to integrated an autoscroll

- means: scroll automatic up or down if your mouse 20px over or under the views.

To do that you need only

-the last function TvVScroll()

-and the 2 if statements from the function Chase()

This 2 statements put into the main while loop

and use it with GuiGetMsg(1).

That also work without flickering.

Best regards, Reinhard

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...