Sign in to follow this  
Followers 0
Tin2tin

Drag and drop within ListView

7 posts in this topic

#1 ·  Posted (edited)

Are there any examples on how to drag and drop inside a ListView to rearrange the order of the items?

(I have searched the forums, but not found any :) )

Edited by Tin2tin

Share this post


Link to post
Share on other sites



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?

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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.

 

Share this post


Link to post
Share on other sites

Thank you Gary!! That's a great example - and this is the first time I see a ListView with icons in the 2. colum.

There are a lot of things for me to learn in you example! :)

Share this post


Link to post
Share on other sites

Yes, Thanx!! I have been searching high and low for a listview/icon example..

Share this post


Link to post
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
Sign in to follow this  
Followers 0