Jump to content

Drag and drop within ListView


Tin2tin
 Share

Recommended Posts

I've tried to rename the functions to get it to work with v3.2.10.0. From the thread I can see that you have been using the example code over the different AutoIt versions. Do you have a version which works with v3.2.10.0?

Sorry,

I don't update at time, because I worked with A3Lib for the treeview parts and I don't want to rename.

Perhabs someone else can give you an example.

best regards, Reinhard

Link to comment
Share on other sites

#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7
Opt("MustDeclareVars", 1)
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <GuiStatusbar.au3>
#include <Constants.au3>

Global Const $tagNMLVCUSTOMDRAW = "hwnd hWndFrom;int IDFrom;int Code;dword dwDrawStage;hwnd hdc;int Left;int Top;int Right;int Bottom;" & _
        "dword dwItemSpec;uint uItemState;long lItemlParam;int clrText;int clrTextBk;int iSubItem;dword dwItemType;int clrFace;int iIconEffect;" & _
        "int iIconPhase;int iPartId;int iStateId;int TextLeft;int TextTop;int TextRight;int TextBottom;uint uAlign"

Global Const $WM_LBUTTONUP = 0x202
Global Const $WM_MOUSEMOVE = 0x200

Global Const $CDDS_PREPAINT = 0x00000001
Global Const $CDDS_ITEMPREPAINT = 0x00010001
Global Const $CDRF_NEWFONT = 0x00000002
Global Const $CDRF_NOTIFYITEMDRAW = 0x00000020

#region Globals *************************************************************************
Global $hDragImageList, $h_ListView, $bDragging = False, $LV_Height, $StatusBar1
Global $a_index[2] ; from and to

Global Const $DebugIt = 1

#endregion End Global variables

Opt("WinTitleMatchMode", 2)

_TestDragItemWithImages()

Func _TestDragItemWithImages()
    Local Const $image_width = 20
    Local Const $image_height = 20
    Local $h_images, $main_GUI, $iIndex
    
    $main_GUI = GUICreate("GuiRegisterMsg Test", 225, 400)
    
    $h_ListView = _GUICtrlListView_Create($main_GUI, "Entry Name|Category", 5, 75, 220, 280, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
    $LV_Height = 280 - 75
    _GUICtrlListView_SetColumnWidth($h_ListView, 0, 100)
    _GUICtrlListView_SetColumnWidth($h_ListView, 1, 100)
    _GUICtrlListView_SetExtendedListViewStyle($h_ListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES))
    ;------------------------------------------------------
    ; Using subitem images
    ;------------------------------------------------------
    _GUICtrlListView_SetExtendedListViewStyle($h_ListView, BitOR($LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_SUBITEMIMAGES))

    $h_images = _GUIImageList_Create($image_width, $image_height, 5, 1)
    For $x = 1 To 21
        _GUIImageList_AddIcon($h_images, @SystemDir & "\shell32.dll", $x)
    Next

    _GUICtrlListView_SetImageList($h_ListView, $h_images, $LVSIL_SMALL)

    ;Register WM_NOTIFY  events
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP")
    GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE")
    GUIRegisterMsg($WM_SIZE, "WM_SIZE")

    ;------------------------------------------------------
    Local $y = 1
    For $x = 0 To 9
        $iIndex = _GUICtrlListView_AddItem($h_ListView, "Name " & $x + 1, $y) ; handle, string, image index
        _GUICtrlListView_AddSubItem($h_ListView, $iIndex, "Category " & $x + 1, 1, $y + 1) ; handle, index, string, subitem, image index
        $y += 2
    Next

    GUISetState()

    While 1

        Switch GUIGetMsg()

            ;-----------------------------------------------------------------------------------------
            ;This case statement exits and updates code if needed
            Case $GUI_EVENT_CLOSE
                ExitLoop
                ;-----------------------------------------------------------------------------------------
                ;put all the misc. stuff here
            Case Else
                ;;;
        EndSwitch
    WEnd
    ;------------------------------------------------------
    ;------------------------------------------------------
    ;------------------------------------------------------
    _GUIImageList_Destroy($h_images)
    ;------------------------------------------------------
    ;------------------------------------------------------
    ;------------------------------------------------------
    GUIDelete()
EndFunc   ;==>_TestDragItemWithImages

;~ #region Item Function(s) **********************************************************************************************
Func _LVInsertItem($i_FromItem, $i_ToItem)
    Local $struct_LVITEM = DllStructCreate($tagLVITEM)
    If @error Then Return SetError(-1, -1, -1)
    Local $struct_String = DllStructCreate("char Buffer[4096]")
    If @error Then Return SetError(-1, -1, -1)
    Local $sBuffer_pointer = DllStructGetPtr($struct_String)
    DllStructSetData($struct_LVITEM, "Mask", BitOR($LVIF_STATE, $LVIF_IMAGE, $LVIF_INDENT, $LVIF_PARAM, $LVIF_TEXT))
    DllStructSetData($struct_LVITEM, "StateMask", $LVIS_STATEIMAGEMASK)
    DllStructSetData($struct_LVITEM, "Item", $i_FromItem)
    DllStructSetData($struct_LVITEM, "SubItem", 0)
    DllStructSetData($struct_LVITEM, "TextMax", 4096)
    DllStructSetData($struct_LVITEM, "Text", $sBuffer_pointer)
    _GUICtrlListView_GetItemEx($h_ListView, $struct_LVITEM)
    If @error Then Return SetError(-1, -1, -1)
    Local $item_state = DllStructGetData($struct_LVITEM, "State")
    DllStructSetData($struct_LVITEM, "Item", $i_ToItem)
    Local $i_newIndex = _GUICtrlListView_InsertItem($h_ListView, DllStructGetData($struct_String, "Buffer"), $i_ToItem, DllStructGetData($struct_LVITEM, "Image"))
    If @error Then Return SetError(-1, -1, -1)
    If $DebugIt Then _DebugPrint("$i_newIndex = " & $i_newIndex)
    DllStructSetData($struct_LVITEM, "Mask", $LVIF_STATE)
    DllStructSetData($struct_LVITEM, "Item", $i_newIndex)
    DllStructSetData($struct_LVITEM, "State", $item_state)
    DllStructSetData($struct_LVITEM, "StateMask", $LVIS_STATEIMAGEMASK)
    _GUICtrlListView_SetItemState($h_ListView, $i_newIndex, $item_state, $LVIS_STATEIMAGEMASK)
    If @error Then Return SetError(-1, -1, -1)
    Return $i_newIndex
EndFunc   ;==>_LVInsertItem

Func _LVCopyItem($i_FromItem, $i_ToItem, $i_SubItem = 0)
    Local $struct_LVITEM = DllStructCreate($tagLVITEM)
    Local $struct_String = DllStructCreate("char Buffer[4096]")
    Local $sBuffer_pointer = DllStructGetPtr($struct_String)
    ; get from item info
    DllStructSetData($struct_LVITEM, "Mask", BitOR($LVIF_STATE, $LVIF_IMAGE, $LVIF_INDENT, $LVIF_PARAM, $LVIF_TEXT))
    DllStructSetData($struct_LVITEM, "StateMask", $LVIS_STATEIMAGEMASK)
    DllStructSetData($struct_LVITEM, "Item", $i_FromItem)
    DllStructSetData($struct_LVITEM, "SubItem", $i_SubItem)
    DllStructSetData($struct_LVITEM, "TextMax", 4096)
    DllStructSetData($struct_LVITEM, "Text", $sBuffer_pointer)
    _GUICtrlListView_GetItemEx($h_ListView, $struct_LVITEM)

    ; set to
    DllStructSetData($struct_LVITEM, "Item", $i_ToItem)
    ; set text
    DllStructSetData($struct_LVITEM, "Mask", $LVIF_TEXT)
    DllStructSetData($struct_LVITEM, "Text", $sBuffer_pointer)
    DllStructSetData($struct_LVITEM, "TextMax", 4096)
    _GUICtrlListView_SetItemEx($h_ListView, $struct_LVITEM)
    If @error Then Return SetError(@error, @error, @error)
    ; set status
    DllStructSetData($struct_LVITEM, "Mask", $LVIF_STATE)
    _GUICtrlListView_SetItemEx($h_ListView, $struct_LVITEM)
    ; set image
    DllStructSetData($struct_LVITEM, "Mask", $LVIF_IMAGE)
    DllStructSetData($struct_LVITEM, "State", $LVIF_IMAGE)
    _GUICtrlListView_SetItemEx($h_ListView, $struct_LVITEM)
    ; set state
    DllStructSetData($struct_LVITEM, "Mask", $LVIF_STATE)
    DllStructSetData($struct_LVITEM, "State", $LVIF_STATE)
    _GUICtrlListView_SetItemEx($h_ListView, $struct_LVITEM)
    ; set indent
    DllStructSetData($struct_LVITEM, "Mask", $LVIF_INDENT)
    DllStructSetData($struct_LVITEM, "State", $LVIF_INDENT)
    _GUICtrlListView_SetItemEx($h_ListView, $struct_LVITEM)
    ; set Param
    DllStructSetData($struct_LVITEM, "Mask", $LVIF_PARAM)
    DllStructSetData($struct_LVITEM, "State", $LVIF_PARAM)
    _GUICtrlListView_SetItemEx($h_ListView, $struct_LVITEM)
EndFunc   ;==>_LVCopyItem
#endregion Item Function(s) *******************************************************************************************

#region Event Function(s) **********************************************************************************************
;------------------------------------------------------
;------------------------------------------------------
;------------------------------------------------------
Func WM_SIZE()
    _GUICtrlStatusBar_Resize($StatusBar1)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE
;------------------------------------------------------
;------------------------------------------------------
;------------------------------------------------------
Func ListView_Click()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then
        _DebugPrint("$NM_CLICK")
        _GUICtrlStatusBar_SetText($StatusBar1, "$NM_CLICK: " & _GUICtrlListView_GetItemText($h_ListView, Int(_GUICtrlListView_GetSelectedIndices($h_ListView))), $SB_SIMPLEID)
    EndIf
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>ListView_Click
;------------------------------------------------------
;------------------------------------------------------
;------------------------------------------------------
Func ListView_DoubleClick()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then
        _DebugPrint("$NM_DBLCLK")
        _GUICtrlStatusBar_SetText($StatusBar1, "$NM_DBLCLK: " & _GUICtrlListView_GetItemText($h_ListView, Int(_GUICtrlListView_GetSelectedIndices($h_ListView))), $SB_SIMPLEID)
    EndIf
    ;----------------------------------------------------------------------------------------------
;~  MsgBox(0, "Double Clicked", _GUICtrlListView_GetItemText($h_ListView, _GUICtrlListView_GetSelectedIndices($h_ListView)))
EndFunc   ;==>ListView_DoubleClick
;------------------------------------------------------
;------------------------------------------------------
;------------------------------------------------------
Func WM_MOUSEMOVE($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $MsgID, $wParam
    If $bDragging = False Then Return $GUI_RUNDEFMSG
    Local $lpos = ControlGetPos($hWndGUI, "", $h_ListView)
    Local $x = BitAND($lParam, 0xFFFF) - $lpos[0]
    Local $y = BitShift($lParam, 16) - $lpos[1]
    If $y > $LV_Height - 20 Then
        _GUICtrlListView_Scroll($h_ListView, 0, $y)
    ElseIf $y < 20 Then
        _GUICtrlListView_Scroll($h_ListView, 0, $y * - 1)
    EndIf
    _GUIImageList_DragMove($x, $y)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOUSEMOVE
;------------------------------------------------------
;------------------------------------------------------
;------------------------------------------------------

Func WM_LBUTTONUP($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $MsgID, $wParam
    $bDragging = False
    Local $lpos = ControlGetPos($hWndGUI, "", $h_ListView)
    Local $x = BitAND($lParam, 0xFFFF) - $lpos[0]
    Local $y = BitShift($lParam, 16) - $lpos[1]
    If $DebugIt Then _DebugPrint("$x = " & $x)
    If $DebugIt Then _DebugPrint("$y = " & $y)
    _GUIImageList_DragLeave($h_ListView)
    _GUIImageList_EndDrag()
    _GUIImageList_Destroy($hDragImageList[0])
    _WinAPI_ReleaseCapture()
    Local $struct_LVHITTESTINFO = DllStructCreate($tagLVHITTESTINFO)
    
    DllStructSetData($struct_LVHITTESTINFO, "X", $x)
    DllStructSetData($struct_LVHITTESTINFO, "Y", $y)
    $a_index[1] = _SendMessage($h_ListView, $LVM_HITTEST, 0, DllStructGetPtr($struct_LVHITTESTINFO), 0, "wparam", "ptr")
    Local $flags = DllStructGetData($struct_LVHITTESTINFO, "Flags")
    If $DebugIt Then _DebugPrint("$flags: " & $flags)
;~  // Out of the ListView?
    If $a_index[1] == -1 Then Return $GUI_RUNDEFMSG
;~  // Not in an item?
    If BitAND($flags, $LVHT_ONITEMLABEL) == 0 And BitAND($flags, $LVHT_ONITEMSTATEICON) == 0 And BitAND($flags, $LVHT_ONITEMICON) = 0 Then Return $GUI_RUNDEFMSG
    If $a_index[0] < $a_index[1] - 1 Or $a_index[0] > $a_index[1] + 1 Then ; make sure insert is at least 2 items above or below, don't want to create a duplicate
        If $DebugIt Then _DebugPrint("To = " & $a_index[1])
        Local $i_newIndex = _LVInsertItem($a_index[0], $a_index[1])
        If @error Then Return SetError(-1, -1, $GUI_RUNDEFMSG)
        Local $From_index = $a_index[0]
        If $a_index[0] > $a_index[1] Then $From_index = $a_index[0] + 1
        For $x = 1 To _GUICtrlListView_GetColumnCount($h_ListView) - 1
            _LVCopyItem($From_index, $i_newIndex, $x)
            If @error Then Return SetError(-1, -1, $GUI_RUNDEFMSG)
        Next
        _GUICtrlListView_DeleteItem($h_ListView, $From_index)
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_LBUTTONUP
;
; WM_NOTIFY event handler
Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tNMHDR, $code, $x, $y, $tNMLISTVIEW, $hwndFrom, $tDraw, $dwDrawStage, $dwItemSpec
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam) ;NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $code = DllStructGetData($tNMHDR, "Code")
    $hwndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Switch $hwndFrom
        Case $h_ListView
            Switch $code
                Case $LVN_BEGINDRAG
                    If $DebugIt Then _DebugPrint("$LVN_BEGINDRAG")
                    $x = BitAND($lParam, 0xFFFF)
                    $y = BitShift($lParam, 16)
                    $tNMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $lParam)
                    $a_index[0] = DllStructGetData($tNMLISTVIEW, "Item")
                    $hDragImageList = _GUICtrlListView_CreateDragImage($h_ListView, $a_index[0])
                    If @error Then Return SetError(-1, -1, $GUI_RUNDEFMSG)
                    _GUIImageList_BeginDrag($hDragImageList[0], 0, 0, 0)
                    If @error Then Return SetError(-1, -1, $GUI_RUNDEFMSG)
                    If $DebugIt Then _DebugPrint("From = " & $a_index[0])
                    _GUIImageList_DragEnter($h_ListView, $x, $y)
                    _WinAPI_SetCapture($hWndGUI)
                    $bDragging = True
                Case $NM_CUSTOMDRAW
                    If $DebugIt Then _DebugPrint("$NM_CUSTOMDRAW")
                    $tDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    $dwDrawStage = DllStructGetData($tDraw, "dwDrawStage")
                    $dwItemSpec = DllStructGetData($tDraw, "dwItemSpec")
                    Switch $dwDrawStage
                        Case $CDDS_PREPAINT
                            If $DebugIt Then _DebugPrint("$CDDS_PREPAINT")
                            Return $CDRF_NOTIFYITEMDRAW
                        Case $CDDS_ITEMPREPAINT
                            If $DebugIt Then _DebugPrint("$CDDS_ITEMPREPAINT")
                            If BitAND($dwItemSpec, 1) = 1 Then
                                DllStructSetData($tDraw, "clrTextBk", $CLR_AQUA)
                            Else
                                DllStructSetData($tDraw, "clrTextBk", $CLR_WHITE)
                            EndIf
                            Return $CDRF_NEWFONT
                    EndSwitch
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
#endregion Event Function(s) ***********************************************************************************************

Func _DebugPrint($s_text)
    $s_text = StringReplace($s_text, @LF, @LF & "-->")
    ConsoleWrite("!===========================================================" & @LF & _
            "+===========================================================" & @LF & _
            "-->" & $s_text & @LF & _
            "+===========================================================" & @LF)
EndFunc   ;==>_DebugPrint

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

  • 1 month later...

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...