Что нового

[Элементы GUI] Перетаскивание пунктов в списке ListView

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Имеется функция/пример для перетаскивания пунктов в ListView:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>
#include <GUIImageList.au3>
;

Global $iLast_Index = -1
Global $a_Index[2] ;From and to
Global $iLastLineTop, $iLastLineLeft

Global $iDragging = False
Global $iDrawing = False ;To ensure mousemove doesn't cause more than one line to be drawn
Global $iLButtonIsUp = False ;To ensure a correct redraw of ListView

$Main_GUI = GUICreate("Drag & Drop LV Item", 225, 400, -1, -1, BitOR($WS_THICKFRAME, $WS_SIZEBOX))

$ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280, 0)
$h_ListView = GUICtrlGetHandle($ListView)

_GUICtrlListView_SetColumnWidth($ListView, 0, 100)
_GUICtrlListView_SetColumnWidth($ListView, 1, 90)

$nExStyle = BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_CHECKBOXES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $nExStyle, $nExStyle)

$h_ImageList = _GUIImageList_Create(16, 16, 5, 1)

For $i = 0 To 10
	_GUIImageList_AddIcon($h_ImageList, @SystemDir & "\shell32.dll", $i)
Next

_GUICtrlListView_SetImageList($h_ListView, $h_ImageList, $LVSIL_SMALL)

For $i = 0 To 9
	GUICtrlCreateListViewItem("Name " & $i & "|Category " & $i, $ListView)
	_GUICtrlListView_SetItemImage($h_ListView, $i, $i, 0); listview handle, index, subitem, image index
Next

GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY_EVENTS")
GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP_EVENTS")
GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE_EVENTS")

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			_GUIImageList_Destroy($h_ImageList)
			Exit
	EndSwitch
	
	If $iLButtonIsUp Then
		$iLButtonIsUp = False
		DllCall("User32.dll", "int", "RedrawWindow", "hwnd", $h_ListView, "ptr", 0, "int", 0, "int", 5)
	EndIf
WEnd

Func WM_LBUTTONUP_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
	$iLButtonIsUp = True
	$iDragging = False
	$iDrawing = False
	
	$iLast_Index = -1
	
	Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)
	
	Local $iX = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
	Local $iY = BitShift($lParam, 16) - $aLV_Pos[1]
	
	Local $struct_LVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
	
	DllStructSetData($struct_LVHITTESTINFO, 1, $iX)
	DllStructSetData($struct_LVHITTESTINFO, 2, $iY)

	$a_Index[1] = GUICtrlSendMsg($ListView, $LVM_HITTEST, 0, DllStructGetPtr($struct_LVHITTESTINFO))
	Local $iFlags = DllStructGetData($struct_LVHITTESTINFO, 2)
	
	;// Out of the ListView?
	If $a_Index[1] = -1 Then $a_Index[1] = _GUICtrlListView_GetItemCount($h_ListView) ;Return $GUI_RUNDEFMSG
	
	;// Not in an item?
	;If BitAND($iFlags, $LVHT_ONITEMLABEL) = 0 And BitAND($iFlags, $LVHT_ONITEMSTATEICON) = 0 Then Return $GUI_RUNDEFMSG
	
	If $a_Index[0] < $a_Index[1] Then
		_GUICtrlListView_CopyItemsEx($h_ListView, $h_ListView, $a_Index[1] - 1, 1)
	ElseIf $a_Index[0] > $a_Index[1] Then
		_GUICtrlListView_CopyItemsEx($h_ListView, $h_ListView, $a_Index[1], 1)
	EndIf
	
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_LBUTTONUP_EVENTS

Func WM_MOUSEMOVE_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
	If Not $iDragging Or $iDrawing Then Return $GUI_RUNDEFMSG
	
	Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)
	
	Local $iX = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
	Local $iY = BitShift($lParam, 16) - $aLV_Pos[1]
	
	Local $struct_LVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
	
	DllStructSetData($struct_LVHITTESTINFO, 1, $iX)
	DllStructSetData($struct_LVHITTESTINFO, 2, $iY)
	
	Local $iItem = GUICtrlSendMsg($ListView, $LVM_HITTEST, 0, DllStructGetPtr($struct_LVHITTESTINFO))
	If $iItem = -1 Then $iItem = _GUICtrlListView_GetItemCount($h_ListView) ;Return $GUI_RUNDEFMSG
	
	If $iLast_Index = $iItem Then Return $GUI_RUNDEFMSG
	
	If $iLast_Index > $iItem Then ;Move up
		_GUICtrlListView_RedrawItems($h_ListView, $iItem, $iLast_Index)
	Else
		_GUICtrlListView_RedrawItems($h_ListView, $iLast_Index, $iItem - 1)
	EndIf
	
	$iLast_Index = $iItem
	
	Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)
	Local $iY = _GUICtrlListView_GetItemPositionY($h_ListView, $iItem)
	If $iY <= 0 Then Return $GUI_RUNDEFMSG
	
	_DrawLine($aLV_Pos[0], $iY, $aLV_Pos[2], 2.5, 0x000000, $h_ListView)
EndFunc   ;==>WM_MOUSEMOVE_EVENTS

Func WM_NOTIFY_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
	
	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
	If @error Then Return $GUI_RUNDEFMSG
	
	$iCode = DllStructGetData($tagNMHDR, 3)
	$iItem = DllStructGetData($tagNMHDR, 4)
	
	Switch $wParam
		Case $ListView
			Switch $iCode
				Case $LVN_BEGINDRAG
					$a_Index[0] = $iItem
					$iDragging = True
					
					;_GUICtrlListView_SetItemSelected($ListView, $iItem, False)
			EndSwitch
	EndSwitch
	
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY_EVENTS

;A try to make a multiple selection support for moved items
Func _GUICtrlListView_CopyItemsEx($hWnd_Source, $hWnd_Destination, $iDstIndex, $fDelFlag = False)
	Local $a_indices, $tItem = DllStructCreate($tagLVITEM), $iIndex
	Local $cols = _GUICtrlListView_GetColumnCount($hWnd_Source)
	Local $items = _GUICtrlListView_GetItemCount($hWnd_Source)
	
	_GUICtrlListView_BeginUpdate($hWnd_Source)
	_GUICtrlListView_BeginUpdate($hWnd_Destination)
	
	If BitAND(_GUICtrlListView_GetExtendedListViewStyle($hWnd_Source), $LVS_EX_CHECKBOXES) == $LVS_EX_CHECKBOXES Then
		For $i = 0 To $items - 1
			If _GUICtrlListView_GetItemChecked($hWnd_Source, $i) Then
				If IsArray($a_indices) Then
					ReDim $a_indices[UBound($a_indices) + 1]
				Else
					Local $a_indices[2]
				EndIf
				
				$a_indices[0] = $a_indices[0] + 1
				$a_indices[UBound($a_indices) - 1] = $i
			EndIf
		Next

		If UBound($a_indices) > 1 Then
			For $i = 1 To $a_indices[0]
				DllStructSetData($tItem, "Mask", BitOR($LVIF_GROUPID, $LVIF_IMAGE, $LVIF_INDENT, $LVIF_PARAM, $LVIF_STATE))
				DllStructSetData($tItem, "Item", $a_indices[$i])
				DllStructSetData($tItem, "SubItem", 0)
				DllStructSetData($tItem, "StateMask", -1)
				
				_GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
				$iIndex = _GUICtrlListView_InsertItem($hWnd_Destination, _
					_GUICtrlListView_GetItemText($hWnd_Source, $a_indices[$i], 0), $iDstIndex, DllStructGetData($tItem, "Image"))
				_GUICtrlListView_SetItemChecked($hWnd_Destination, $iIndex)
				
				$iDstIndex += 1
				
				For $x = 1 To $cols - 1
					DllStructSetData($tItem, "Item", $a_indices[$i])
					DllStructSetData($tItem, "SubItem", $x)
					
					_GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
					_GUICtrlListView_AddSubItem($hWnd_Destination, $iIndex, _
						_GUICtrlListView_GetItemText($hWnd_Source, $a_indices[$i], $x), $x, DllStructGetData($tItem, "Image"))
				Next
				
				_GUICtrlListView_SetItemSelected($hWnd_Source, $iIndex, True)
			Next
			
			If $fDelFlag Then
				For $i = $a_indices[0] To 1 Step -1
					_GUICtrlListView_DeleteItem($hWnd_Source, $a_indices[$i])
				Next
			EndIf
		EndIf
	EndIf
	
	If _GUICtrlListView_GetSelectedCount($hWnd_Source) Then
		$a_indices = _GUICtrlListView_GetSelectedIndices($hWnd_Source, 1)
		
		For $i = 1 To $a_indices[0]
			$i_Index = $a_indices[$i]
			
			DllStructSetData($tItem, "Mask", BitOR($LVIF_GROUPID, $LVIF_IMAGE, $LVIF_INDENT, $LVIF_PARAM, $LVIF_STATE))
			DllStructSetData($tItem, "Item", $i_Index)
			DllStructSetData($tItem, "SubItem", 0)
			DllStructSetData($tItem, "StateMask", -1)
			
			_GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
			$iIndex = _GUICtrlListView_InsertItem($hWnd_Destination, _
				_GUICtrlListView_GetItemText($hWnd_Source, $i_Index, 0), $iDstIndex, DllStructGetData($tItem, "Image"))
			
			$iDstIndex += 1
			
			For $x = 1 To $cols - 1
				DllStructSetData($tItem, "Item", $i_Index)
				DllStructSetData($tItem, "SubItem", $x)
				
				_GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
				_GUICtrlListView_AddSubItem($hWnd_Destination, $iIndex, _
					_GUICtrlListView_GetItemText($hWnd_Source, $i_Index, $x), $x, DllStructGetData($tItem, "Image"))
			Next
			
			_GUICtrlListView_SetItemSelected($hWnd_Source, $iIndex, True)
		Next
		
		If $fDelFlag Then
			For $i = $a_indices[0] To 1 Step -1
				_GUICtrlListView_DeleteItem($hWnd_Source, $a_indices[$i])
			Next
		EndIf
	EndIf
	
	_GUICtrlListView_EndUpdate($hWnd_Source)
	_GUICtrlListView_EndUpdate($hWnd_Destination)
EndFunc

Func _DrawLine($iLeft, $iTop, $iWidth, $iHeight, $sColor, $hWnd = 0)
	$iDrawing = True
	$sColor = Hex("0x" & BitAND(BitShift(String(Binary($sColor)), 8), 0xFFFFFF)) ;RGB2BGR
	
	Local $hDC = DllCall("User32.dll", "int", "GetDC", "hwnd", $hWnd)
	Local $aPen = DllCall("GDI32.dll", "int", "CreatePen", "int", 0, "int", $iHeight, "int", $sColor)
	
	DllCall("GDI32.dll", "int", "SelectObject", "int", $hDC[0], "int", $aPen[0])
	
	If $iLastLineTop > -1 And $iLastLineLeft > -1 Then
		If $iLastLineTop <> $iTop Then ; or $iLastLineLeft <> $iLeft Then
			;Local $strRect = DllStructCreate("int[4]")
			
			;DllStructSetData($strRect, 1, 5)
			;DllStructSetData($strRect, 2, 75)
			;DllStructSetData($strRect, 3, 198 + 5)
			;DllStructSetData($strRect, 4, 280 + 75)
			
			;Local $pRect = DllStructGetPtr($strRect)
			
			$iLastLineLeft = $iLeft
			$iLastLineTop = $iTop
			
			DllCall("user32.dll", "int", "InvalidateRect", "hwnd", $hWnd, "int", 0, "int", 1)
			Sleep(10) ;seems to be needed to ensure redrawn before line is drawn
		EndIf
	EndIf
	
	DllCall("GDI32.dll", "int", "MoveToEx", "hwnd", $hDC[0], "int", $iLeft, "int", $iTop, "int", 0)
	DllCall("GDI32.dll", "int", "LineTo", "hwnd", $hDC[0], "int", $iLeft + $iWidth, "int", $iTop)
	
	DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "int", $hDC[0])
	DllCall("GDI32.dll", "int", "DeleteObject", "int", $aPen[0])
	
	$iDrawing = False
EndFunc   ;==>_DrawLine


Но я никак не додумаю, как это заставить работать с более чем одним пунктом. На данный момент в этом примере корректно(?) перетаскивается только один выделенный пункт.
 

rollin

Новичок
Сообщения
15
Репутация
1
Привет!
Решение нашлось? Если нашлось, то, будь добр, опиши его - вопрос ведь интересный :smile:
А если нет, то я немного переписал твой код. Работает вроде правильно, но только если элементы выделять подряд.
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>
#include <GUIImageList.au3>

Global $iLast_Index = -1
Global $a_Index[2] ;From and to
Global $iLastLineTop, $iLastLineLeft

Global $iDragging = False
Global $iDrawing = False ;To ensure mousemove doesn't cause more than one line to be drawn
Global $iLButtonIsUp = False ;To ensure a correct redraw of ListView

$Main_GUI = GUICreate("Drag & Drop LV Item", 225, 400, -1, -1, BitOR($WS_THICKFRAME, $WS_SIZEBOX))

$ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280, 0)
$h_ListView = GUICtrlGetHandle($ListView)

_GUICtrlListView_SetColumnWidth($ListView, 0, 100)
_GUICtrlListView_SetColumnWidth($ListView, 1, 90)

$nExStyle = BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_CHECKBOXES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $nExStyle, $nExStyle)

$h_ImageList = _GUIImageList_Create(16, 16, 5, 1)

For $i = 0 To 10
    _GUIImageList_AddIcon($h_ImageList, @SystemDir & "\shell32.dll", $i)
Next

_GUICtrlListView_SetImageList($h_ListView, $h_ImageList, $LVSIL_SMALL)

For $i = 0 To 9
    GUICtrlCreateListViewItem("Name " & $i & "|Category " & $i, $ListView)
    _GUICtrlListView_SetItemImage($h_ListView, $i, $i, 0); listview handle, index, subitem, image index
Next

GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY_EVENTS")
GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP_EVENTS")
GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE_EVENTS")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GUIImageList_Destroy($h_ImageList)
            Exit
    EndSwitch

    If $iLButtonIsUp Then
        $iLButtonIsUp = False
        DllCall("User32.dll", "int", "RedrawWindow", "hwnd", $h_ListView, "ptr", 0, "int", 0, "int", 5)
    EndIf
WEnd

Func WM_LBUTTONUP_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
    If $iDragging = False Then Return $GUI_RUNDEFMSG
	$iLButtonIsUp = True
    $iDragging = False
    $iDrawing = False

    $iLast_Index = -1

    Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)

    Local $iX = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
    Local $iY = BitShift($lParam, 16) - $aLV_Pos[1]

    Local $struct_LVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")

    DllStructSetData($struct_LVHITTESTINFO, 1, $iX)
    DllStructSetData($struct_LVHITTESTINFO, 2, $iY)

    $a_Index[1] = GUICtrlSendMsg($ListView, $LVM_HITTEST, 0, DllStructGetPtr($struct_LVHITTESTINFO))
    Local $iFlags = DllStructGetData($struct_LVHITTESTINFO, 2)

    ;// Out of the ListView?
    If $a_Index[1] = -1 Then $a_Index[1] = _GUICtrlListView_GetItemCount($h_ListView) ;Return $GUI_RUNDEFMSG

    If $a_Index[0] < $a_Index[1] Then
        _GUICtrlListView_CopyItemsEx($h_ListView, $h_ListView, $a_Index[1], True)
    ElseIf $a_Index[0] > $a_Index[1] Then
        _GUICtrlListView_CopyItemsEx($h_ListView, $h_ListView, $a_Index[1], True,1)
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_LBUTTONUP_EVENTS

Func WM_MOUSEMOVE_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
    If Not $iDragging Or $iDrawing Then Return $GUI_RUNDEFMSG

    Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)

    Local $iX = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
    Local $iY = BitShift($lParam, 16) - $aLV_Pos[1]

    Local $struct_LVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")

    DllStructSetData($struct_LVHITTESTINFO, 1, $iX)
    DllStructSetData($struct_LVHITTESTINFO, 2, $iY)

    Local $iItem = GUICtrlSendMsg($ListView, $LVM_HITTEST, 0, DllStructGetPtr($struct_LVHITTESTINFO))
    If $iItem = -1 Then $iItem = _GUICtrlListView_GetItemCount($h_ListView) ;Return $GUI_RUNDEFMSG

    If $iLast_Index = $iItem Then Return $GUI_RUNDEFMSG

    If $iLast_Index > $iItem Then ;Move up
        _GUICtrlListView_RedrawItems($h_ListView, $iItem, $iLast_Index)
    Else
        _GUICtrlListView_RedrawItems($h_ListView, $iLast_Index, $iItem - 1)
    EndIf

    $iLast_Index = $iItem

    Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)
    Local $iY = _GUICtrlListView_GetItemPositionY($h_ListView, $iItem)
    If $iY <= 0 Then Return $GUI_RUNDEFMSG

    _DrawLine($aLV_Pos[0], $iY, $aLV_Pos[2], 2.5, 0x000000, $h_ListView)
EndFunc   ;==>WM_MOUSEMOVE_EVENTS

Func WM_NOTIFY_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
    Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
    $tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
    If @error Then Return $GUI_RUNDEFMSG

    $iCode = DllStructGetData($tagNMHDR, 3)
    $iItem = DllStructGetData($tagNMHDR, 4)

    Switch $wParam
        Case $ListView
            Switch $iCode
                Case $LVN_BEGINDRAG
                    $a_Index[0] = $iItem
                    $iDragging = True
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY_EVENTS

;A try to make a multiple selection support for moved items
Func _GUICtrlListView_CopyItemsEx($hWnd_Source, $hWnd_Destination, $iDstIndex, $fDelFlag = False,$ind_flag=0)
    Local $a_indices, $tItem = DllStructCreate($tagLVITEM), $iIndex, $movedInd = 0
    Local $cols = _GUICtrlListView_GetColumnCount($hWnd_Source)
    Local $items = _GUICtrlListView_GetItemCount($hWnd_Source)

    _GUICtrlListView_BeginUpdate($hWnd_Source)
    _GUICtrlListView_BeginUpdate($hWnd_Destination)

    If BitAND(_GUICtrlListView_GetExtendedListViewStyle($hWnd_Source), $LVS_EX_CHECKBOXES) == $LVS_EX_CHECKBOXES Then
        For $i = 0 To $items - 1
            If _GUICtrlListView_GetItemChecked($hWnd_Source, $i) Then
                If IsArray($a_indices) Then
                    ReDim $a_indices[UBound($a_indices) + 1]
                Else
                    Local $a_indices[2]
                EndIf

                $a_indices[0] = $a_indices[0] + 1
                $a_indices[UBound($a_indices) - 1] = $i
            EndIf
        Next

        If UBound($a_indices) > 1 Then
            For $i = 1 To $a_indices[0]
                DllStructSetData($tItem, "Mask", BitOR($LVIF_GROUPID, $LVIF_IMAGE, $LVIF_INDENT, $LVIF_PARAM, $LVIF_STATE))
                DllStructSetData($tItem, "Item", $a_indices[$i]+$movedInd*$ind_flag)
                DllStructSetData($tItem, "SubItem", 0)
                DllStructSetData($tItem, "StateMask", -1)

                _GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
                $iIndex = _GUICtrlListView_InsertItem($hWnd_Destination, _
                    _GUICtrlListView_GetItemText($hWnd_Source, $a_indices[$i]+$movedInd*$ind_flag, 0), $iDstIndex, DllStructGetData($tItem, "Image"))
                _GUICtrlListView_SetItemChecked($hWnd_Destination, $iIndex)

                $iDstIndex += 1
				$movedInd += 1

                For $x = 1 To $cols - 1
                    DllStructSetData($tItem, "Item", $a_indices[$i]+$movedInd*$ind_flag)
                    DllStructSetData($tItem, "SubItem", $x)
                    _GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
                    _GUICtrlListView_AddSubItem($hWnd_Destination, $iIndex, _
                        _GUICtrlListView_GetItemText($hWnd_Source, $a_indices[$i]+$movedInd*$ind_flag, $x), $x, DllStructGetData($tItem, "Image"))
                Next

                _GUICtrlListView_SetItemSelected($hWnd_Source, $iIndex, True)
				$movedInd += 1
            Next

            If $fDelFlag Then
                For $i = $a_indices[0] To 1 Step -1
                    _GUICtrlListView_DeleteItem($hWnd_Source, $a_indices[$i])
                Next
            EndIf
        EndIf
    EndIf

    If _GUICtrlListView_GetSelectedCount($hWnd_Source) Then
        $a_indices = _GUICtrlListView_GetSelectedIndices($hWnd_Source, 1)

        For $i = 1 To $a_indices[0]
            $i_Index = $a_indices[$i]+$movedInd*$ind_flag

            DllStructSetData($tItem, "Mask", BitOR($LVIF_GROUPID, $LVIF_IMAGE, $LVIF_INDENT, $LVIF_PARAM, $LVIF_STATE))
            DllStructSetData($tItem, "Item", $i_Index)
            DllStructSetData($tItem, "SubItem", 0)
            DllStructSetData($tItem, "StateMask", -1)

            _GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
            $iIndex = _GUICtrlListView_InsertItem($hWnd_Destination, _
                _GUICtrlListView_GetItemText($hWnd_Source, $i_Index, 0), $iDstIndex, DllStructGetData($tItem, "Image"))

            $iDstIndex += 1
			$movedInd += 1
			$i_Index = $a_indices[$i]+$movedInd*$ind_flag

            For $x = 1 To $cols - 1
                DllStructSetData($tItem, "Item", $i_Index)
                DllStructSetData($tItem, "SubItem", $x)
                _GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
                _GUICtrlListView_AddSubItem($hWnd_Destination, $iIndex, _
                    _GUICtrlListView_GetItemText($hWnd_Source, $i_Index, $x), $x, DllStructGetData($tItem, "Image"))
            Next

            _GUICtrlListView_SetItemSelected($hWnd_Source, $iIndex, True)
        Next

        If $fDelFlag Then
            For $i = $a_indices[0] To 1 Step -1
                _GUICtrlListView_DeleteItem($hWnd_Source, $a_indices[$i]+$ind_flag*$a_indices[0])
            Next
        EndIf
    EndIf

    _GUICtrlListView_EndUpdate($hWnd_Source)
    _GUICtrlListView_EndUpdate($hWnd_Destination)
EndFunc

Func _DrawLine($iLeft, $iTop, $iWidth, $iHeight, $sColor, $hWnd = 0)
    $iDrawing = True
    $sColor = Hex("0x" & BitAND(BitShift(String(Binary($sColor)), 8), 0xFFFFFF)) ;RGB2BGR

    Local $hDC = DllCall("User32.dll", "int", "GetDC", "hwnd", $hWnd)
    Local $aPen = DllCall("GDI32.dll", "int", "CreatePen", "int", 0, "int", $iHeight, "int", $sColor)

    DllCall("GDI32.dll", "int", "SelectObject", "int", $hDC[0], "int", $aPen[0])

    If $iLastLineTop > -1 And $iLastLineLeft > -1 Then
        If $iLastLineTop <> $iTop Then

            $iLastLineLeft = $iLeft
            $iLastLineTop = $iTop

            DllCall("user32.dll", "int", "InvalidateRect", "hwnd", $hWnd, "int", 0, "int", 1)
            Sleep(10) ;seems to be needed to ensure redrawn before line is drawn
        EndIf
    EndIf

    DllCall("GDI32.dll", "int", "MoveToEx", "hwnd", $hDC[0], "int", $iLeft, "int", $iTop, "int", 0)
    DllCall("GDI32.dll", "int", "LineTo", "hwnd", $hDC[0], "int", $iLeft + $iWidth, "int", $iTop)

    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "int", $hDC[0])
    DllCall("GDI32.dll", "int", "DeleteObject", "int", $aPen[0])

    $iDrawing = False
EndFunc   ;==>_DrawLine

А, да, еще не разобрал зачем перемещение и для выделенных, и для отмеченных галкой - можно ведь запутаться, что хочешь перемещать :smile:
 
Верх