Всем доброго времени суток.
Сделал Drag-and-drop так:
1. Начало Drag&Drop отслеживаю в сообщении WM_NOTIFY, LVN_BEGINDRAG
2. Там же (LVN_BEGINDRAG) отслеживаю отжатие левой кнопки мыши
3. Определяю выделенную строку и делаю перемещение
Работает - перемещает строку выше указанной мышкой строки
Но это как-то "топорно" выглядит
Хотелось бы при зажатой кнопки мыши и перемещению по ListView видеть полоску разделителя и вставлять строку именно туда.
Как это можно реализовать?
Сделал Drag-and-drop так:
1. Начало Drag&Drop отслеживаю в сообщении WM_NOTIFY, LVN_BEGINDRAG
2. Там же (LVN_BEGINDRAG) отслеживаю отжатие левой кнопки мыши
3. Определяю выделенную строку и делаю перемещение
Работает - перемещает строку выше указанной мышкой строки
Но это как-то "топорно" выглядит
Хотелось бы при зажатой кнопки мыши и перемещению по ListView видеть полоску разделителя и вставлять строку именно туда.
Как это можно реализовать?
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <Misc.au3>
#include <Array.au3>
#include <GuiImageList.au3>
Global $aItems[0]
Global $AlertDrag=0, $IndexDragItem=-1
AutoItSetOption ('MouseCoordMode',2)
$Form1 = GUICreate("Form1", 420, 449, 192, 114)
; ListView
$hListView = GUICtrlCreateListView("", 10, 30, 400, 410, BitOR($LVS_REPORT,$LVS_SHOWSELALWAYS))
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_AddColumn($hListView, "Название",400)
For $i=1 To 10
_ArrayAdd($aItems,'Название '&$i)
Next
; Заполнить ListView
FillListView()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)
While 1
Alert()
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
; Заполнить ListView
Func FillListView()
_GUICtrlListView_DeleteAllItems($hListView) ; Удалить все строки
For $i=0 To UBound($aItems)-1
GUICtrlCreateListViewItem($aItems[$i], $hListView)
Next
EndFunc
Func Alert()
; Если Drag&Drop
If $AlertDrag<>0 Then
$IndexListView=Number(_GUICtrlListView_GetSelectedIndices($hListView)) ; Индекс выделенных строк
If $IndexListView<>$IndexDragItem Then
$Text=_GUICtrlListView_GetItemText($hListView,$IndexListView)
If $IndexDragItem =-1 Then
ConsoleWrite(@CRLF&' выделен: '&$IndexListView&' заменить индекс: '&$IndexDragItem)
_ArrayAdd($aItems,$Text)
_ArrayDelete($aItems,$IndexListView)
ElseIf $IndexListView=0 And $IndexDragItem=1 Then
_ArraySwap($aItems,0,1)
ElseIf $IndexListView>$IndexDragItem Then
_ArrayDelete($aItems,$IndexListView)
_ArrayInsert($aItems,$IndexDragItem, $Text )
Else
ConsoleWrite(@CRLF&' выделен: '&$IndexListView&' заменить индекс: '&$IndexDragItem)
_ArrayInsert($aItems,$IndexDragItem, $Text )
_ArrayDelete($aItems,$IndexListView)
EndIf
FillListView()
EndIf
;~ ConsoleWrite(@CRLF&'Отпуск')
$AlertDrag=0
Return
EndIf
EndFunc
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
$hWndListView = $hListView
If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
Switch $hWndFrom
; ListView
Case $hWndListView
Switch $iCode
Case $LVN_HOTTRACK ; Перемещение мыши
$aMousePos=MouseGetPos()
$aItem=_GUICtrlListView_SubItemHitTest($hListView,$aMousePos[0],$aMousePos[1]-30)
If Not @error Then ConsoleWrite(@CRLF&$aMousePos[0]&'x'&$aMousePos[1]&' Индекс строки = '&$aItem[0])
Case $LVN_BEGINDRAG
; Отследить отжатие левой клавиши мыши
While _IsPressed('01')
Sleep(5)
WEnd
$IndexDragItem=_GUICtrlListView_GetHotItem($hListView)
$AlertDrag=1
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc