Что нового

Drag Drop TreeView (перетаскивание элементов в дереве)

musicstashall

Знающий
Сообщения
322
Репутация
7
Следующий вариант на мой взгляд, самый удачный из всех, сколько я уже находил, но на x64 не работает этот способ. Кто поможет адаптировать под x64??? Очень хочется реализовать этот вариант в своем проекте:
[hide]
Код:
#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
[/hide]
И вот еще один момент, в данном способе очень не хватает автоскроллинга при перетаскивании, чтобы элемент можно было перетаскивать не только в видимом пространстве дерева, а по всему дереву. Такой способ реализован в следующем скрипте, но он имеет больше недостатков, в сравнении с этим. Было бы очень хорошо, если бы кто-то помог объединить эти два варианта и адаптировать для x64.

Скрипт с автоскроллингом:

[hide]
Код:
#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
[/hide]

Оба способа НЕ РАБОТАЮТ на x64.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
зачем х64 ?
каковы задачи?
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
musicstashall
Главная проблема - это функция _GUICtrlTreeView_DisplayRect, а точнее _GUICtrlTreeView_DisplayRectEx, которую она вызывает. Там в структуре $tRECT передаётся указатель на пункт дерева. Указатели в x64 имеют разрядность 64 бита, а структура создаётся из 32-битных INT. Ну и остальное по мелочи поправил: некорректное описание $tNMHDR, неправильный вызов WindowFromPoint, _GUICtrlTreeView_Delete не всегда удаляла пункт (опять же из-за размера указателя). Если дальше захотите продолжать, то изучайте исходники проблемных функций и обращайте внимание на описания структур: UINT - он везде 32 бита, а UINT_PTR уже зависит от системы (см. справку по DllStructCreate).

Вот исправленный первый пример. Работает в обеих разрядностях. Второй пример не смотрел (и, честно говоря, уже нет желания)
Код:
; #AutoIt3Wrapper_UseX64=Y

#include <WinAPIMisc.au3>
#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)
                              _SendMessage($hTree, $TVM_DELETEITEM, 0, $hDragItem, 0, "wparam", "handle", "hwnd")
                        EndIf
                  EndIf
            Case $GUI_EVENT_MOUSEMOVE
                  If $bTreeDrag = False Then ContinueCase
                  $tPos = _WinAPI_GetMousePos()
                  $Hwnd = _WinAPI_WindowFromPoint($tPos)
                  ;cancel drag in progress and cleanup if moved outside treeview:
                  If ($Hwnd <> $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_ptr;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

Func __GUICtrlTreeView_DisplayRect($hWnd, $hItem, $bTextOnly = False)
      Local $tRECT = DllStructCreate("int_ptr Left;int_ptr Top;int_ptr Right;int_ptr Bottom")
      DllStructSetData($tRECT, "Left", $hItem)
      _SendMessage($hWnd, $TVM_GETITEMRECT, $bTextOnly, $tRECT, 0, "wparam", "struct*")
      Local $aRect[4]
      $aRect[0] = DllStructGetData($tRECT, "Left")
      $aRect[1] = DllStructGetData($tRECT, "Top")
      $aRect[2] = DllStructGetData($tRECT, "Right")
      $aRect[3] = DllStructGetData($tRECT, "Bottom")
      If @AutoItX64 Then
        Local $aRect_ = $aRect
        $aRect[0] = _WinAPI_LoDWord($aRect_[0])
        $aRect[1] = _WinAPI_HiDWord($aRect_[0])
        $aRect[2] = _WinAPI_LoDWord($aRect_[1])
        $aRect[3] = _WinAPI_HiDWord($aRect_[1])
      EndIf
      Return $aRect
EndFunc   ;==>__GUICtrlTreeView_DisplayRect
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Спасибо от души) Учту эти нюансы.

OffTopic:
Есть еще один скрипт для выбора иконки из файлов, тот тоже на x64 не работает, попробую аналогично решить задачу.
 
Верх