- Offizieller Beitrag
Irgendwie waren mir meine bisherigen Versuche zu dem Thema nicht "schön" genug. Jetzt habe ich mal ein Beispiel erstellt, dass mir schon viel besser gefällt.
Und weil die Frage gerade auch wieder in H&U aufgetaucht ist, wollte ich euch das nicht vorenthalten:
Spoiler anzeigen
; *********************************************************
; Das untenstehende Beispiel funktioniert nur im 32Bit-Mode
; *********************************************************
#AutoIt3Wrapper_UseX64=n
; *********************************************************
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>
Opt('GUIOnEventMode', 1)
[/autoit] [autoit][/autoit] [autoit]Global $iStartIndex, $iEndIndex, $fLVDrag = False
[/autoit] [autoit][/autoit] [autoit]$hGui = GUICreate('ListView Drag&Drop', 240, 280)
GUISetOnEvent($GUI_EVENT_CLOSE, '_End')
$hListView = GUICtrlCreateListView('AAA|BBB|CCC', 10, 10, 220, 260)
$hWndListView = GUICtrlGetHandle($hListView)
For $i = 0 To 9
GUICtrlCreateListViewItem(StringFormat('%s|%s|%s', Chr(Random(65, 90, 1)) & Chr(Random(65, 90, 1)), Chr(Random(65, 90, 1)), Random(0, 9, 1)), $hListView)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
WinWaitClose($hGui)
[/autoit] [autoit][/autoit] [autoit]Func _End()
Exit
EndFunc ;==>_End
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $tNMHDR, $hWndFrom, $iCode, $tNMLISTVIEW
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, 'hWndFrom'))
$iCode = DllStructGetData($tNMHDR, 'Code')
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $LVN_BEGINDRAG
If Not $fLVDrag Then
$tNMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iStartIndex = DllStructGetData($tNMLISTVIEW, 'Item')
$fLVDrag = True
GUIRegisterMsg($WM_MOUSEMOVE, 'WM_MOUSEMOVE')
EndIf
Case $LVN_HOTTRACK
If $fLVDrag Then
$tNMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iEndIndex = DllStructGetData($tNMLISTVIEW, 'Item')
$fLVDrag = False
GUIRegisterMsg($WM_MOUSEMOVE, '')
_GUICtrlListView_ChangeItemIndex($hListView, $iStartIndex, $iEndIndex)
_GUICtrlListView_SetItemSelected($hListView, $iEndIndex, True, True)
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func WM_MOUSEMOVE($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam, $ilParam
Local $aHit = _GUICtrlListView_HitTest($hWndListView)
If IsArray($aHit) Then _GUICtrlListView_SetItemFocused($hListView, $aHit[0])
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_MOUSEMOVE
Func _GUICtrlListView_ChangeItemIndex($hListView, $iStart, $iEnd)
Local $sTmp, $iCount = _GUICtrlListView_GetItemCount($hListView)
If $iCount = 0 Then Return
If $iStart = $iEnd Then Return
If $iStart < 0 Then $iStart = 0
If $iEnd = -1 Or $iEnd >= $iCount Then $iEnd = $iCount - 1
If $iStart < $iEnd Then
$sTmp = _GUICtrlListView_GetItemTextString($hListView, $iStart)
For $i = $iStart To $iEnd - 1
_GUICtrlListView_SetItemText($hListView, $i, _GUICtrlListView_GetItemTextString($hListView, $i + 1), -1)
Next
_GUICtrlListView_SetItemText($hListView, $iEnd, $sTmp, -1)
Else
$sTmp = _GUICtrlListView_GetItemTextString($hListView, $iStart)
For $i = $iStart To $iEnd + 1 Step -1
_GUICtrlListView_SetItemText($hListView, $i, _GUICtrlListView_GetItemTextString($hListView, $i - 1), -1)
Next
_GUICtrlListView_SetItemText($hListView, $iEnd, $sTmp, -1)
EndIf
EndFunc ;==>_GUICtrlListView_ChangeItemIndex
Von "Großvater" gestraffte Version:
Spoiler anzeigen
; *********************************************************
; Das untenstehende Beispiel funktioniert nur im 32Bit-Mode
; *********************************************************
#AutoIt3Wrapper_UseX64=n
; *********************************************************
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
Opt('GUIOnEventMode', 1)
[/autoit] [autoit][/autoit] [autoit]$hGui = GUICreate('ListView Drag&Drop', 240, 280)
GUISetOnEvent($GUI_EVENT_CLOSE, '_End')
$hListView = GUICtrlCreateListView('AAA|BBB|CCC', 10, 10, 220, 260)
$hWndListView = GUICtrlGetHandle($hListView)
For $i = 0 To 9
GUICtrlCreateListViewItem(StringFormat('%s|%s|%s', Chr(Random(65, 90, 1)) & Chr(Random(65, 90, 1)), Chr(Random(65, 90, 1)), Random(0, 9, 1)), $hListView)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, '_DragListView')
WinWaitClose($hGui)
[/autoit] [autoit][/autoit] [autoit]Func _End()
Exit
EndFunc ;==>_End
Func _DragListView($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iwParam
Local Static $iStartIndex = -1, $iEndIndex = -1, $sItemText = "", $fLVDrag = False
Switch $iMsg
Case $WM_MOUSEMOVE
Local $aHit = _GUICtrlListView_HitTest($hWndListView)
If IsArray($aHit) Then _GUICtrlListView_SetItemFocused($hWndListView, $aHit[0])
Case $WM_NOTIFY
Local $tNMHDR, $hWndFrom, $iCode, $iNewItem, $tNMLISTVIEW
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, 'hWndFrom'))
$iCode = DllStructGetData($tNMHDR, 'Code')
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $LVN_BEGINDRAG
If Not $fLVDrag Then
$tNMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iStartIndex = DllStructGetData($tNMLISTVIEW, 'Item')
$sItemText = _GUICtrlListView_GetItemTextString($hWndListView, $iStartIndex)
$fLVDrag = True
GUIRegisterMsg($WM_MOUSEMOVE, '_DragListView')
EndIf
Case $LVN_HOTTRACK
If $fLVDrag Then
$tNMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iEndIndex = DllStructGetData($tNMLISTVIEW, 'Item')
$fLVDrag = False
GUIRegisterMsg($WM_MOUSEMOVE, '')
Select
Case $iStartIndex < $iEndIndex
$iNewItem = _GUICtrlListView_InsertItem($hWndListView, "", $iEndIndex + 1)
_GUICtrlListView_SetItemText($hWndListView, $iNewItem, $sItemText, -1)
_GUICtrlListView_SetItemSelected($hWndListView, $iNewItem, True, True)
_GUICtrlListView_DeleteItem($hWndListView, $iStartIndex)
Case $iStartIndex > $iEndIndex
_GUICtrlListView_DeleteItem($hWndListView, $iStartIndex)
$iNewItem = _GUICtrlListView_InsertItem($hWndListView, "", $iEndIndex)
_GUICtrlListView_SetItemText($hWndListView, $iNewItem, $sItemText, -1)
_GUICtrlListView_SetItemSelected($hWndListView, $iNewItem, True, True)
EndSelect
EndIf
EndSwitch
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>_DragListView
Von "BugFix" angepasste Version mit Drag&Drop auch innerhalb einer Zeile:
Spoiler anzeigen
; *********************************************************
; Das untenstehende Beispiel funktioniert nur im 32Bit-Mode
; *********************************************************
#AutoIt3Wrapper_UseX64=n
; *********************************************************
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
Opt('GUIOnEventMode', 1)
[/autoit] [autoit][/autoit] [autoit]$hGui = GUICreate('ListView Drag&Drop', 240, 280)
GUISetOnEvent($GUI_EVENT_CLOSE, '_End')
$hListView = GUICtrlCreateListView('AAA|BBB|CCC', 10, 10, 220, 260)
$hWndListView = GUICtrlGetHandle($hListView)
For $i = 0 To 9
GUICtrlCreateListViewItem(StringFormat('%s|%s|%s', Chr(Random(65, 90, 1)) & Chr(Random(65, 90, 1)), Chr(Random(65, 90, 1)), Random(0, 9, 1)), $hListView)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, '_DragListView')
WinWaitClose($hGui)
[/autoit] [autoit][/autoit] [autoit]Func _End()
Exit
EndFunc ;==>_End
Func _DragListView($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iwParam
Local Static $iStartIndex = -1, $iEndIndex = -1, $sItemText = "", $fLVDrag = False
Local Static $txtStartSubItem, $txtEndSubItem, $iStartSubIndex, $iEndSubIndex
Switch $iMsg
Case $WM_MOUSEMOVE
Local $aHit = _GUICtrlListView_HitTest($hWndListView)
If IsArray($aHit) Then _GUICtrlListView_SetItemFocused($hWndListView, $aHit[0])
Case $WM_NOTIFY
Local $tNMHDR, $hWndFrom, $iCode, $iNewItem, $tNMLISTVIEW
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, 'hWndFrom'))
$iCode = DllStructGetData($tNMHDR, 'Code')
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $LVN_BEGINDRAG
If Not $fLVDrag Then
$tNMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iStartIndex = DllStructGetData($tNMLISTVIEW, 'Item')
$iStartSubIndex = DllStructGetData($tNMLISTVIEW, 'SubItem')
$txtStartSubItem = _GUICtrlListView_GetItemText($hWndListView, $iStartIndex, $iStartSubIndex)
$sItemText = _GUICtrlListView_GetItemTextString($hWndListView, $iStartIndex)
$fLVDrag = True
GUIRegisterMsg($WM_MOUSEMOVE, '_DragListView')
EndIf
Case $LVN_HOTTRACK
If $fLVDrag Then
$tNMLISTVIEW = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iEndIndex = DllStructGetData($tNMLISTVIEW, 'Item')
$iEndSubIndex = DllStructGetData($tNMLISTVIEW, 'SubItem')
$txtEndSubItem = _GUICtrlListView_GetItemText($hWndListView, $iEndIndex, $iEndSubIndex)
$fLVDrag = False
GUIRegisterMsg($WM_MOUSEMOVE, '')
Select
Case $iStartIndex < $iEndIndex
$iNewItem = _GUICtrlListView_InsertItem($hWndListView, "", $iEndIndex + 1)
_GUICtrlListView_SetItemText($hWndListView, $iNewItem, $sItemText, -1)
_GUICtrlListView_SetItemSelected($hWndListView, $iNewItem, True, True)
_GUICtrlListView_DeleteItem($hWndListView, $iStartIndex)
Case $iStartIndex > $iEndIndex
_GUICtrlListView_DeleteItem($hWndListView, $iStartIndex)
$iNewItem = _GUICtrlListView_InsertItem($hWndListView, "", $iEndIndex)
_GUICtrlListView_SetItemText($hWndListView, $iNewItem, $sItemText, -1)
_GUICtrlListView_SetItemSelected($hWndListView, $iNewItem, True, True)
Case ($iStartIndex = $iEndIndex) And ($iStartSubIndex <> $iEndSubIndex)
_GUICtrlListView_SetItemText($hWndListView, $iEndIndex, $txtEndSubItem, $iStartSubIndex)
_GUICtrlListView_SetItemText($hWndListView, $iEndIndex, $txtStartSubItem, $iEndSubIndex)
EndSelect
EndIf
EndSwitch
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>_DragListView