Moin,
weil in der letzten Zeit so viel über Drag&Drop in ListViews diskutiert wurde, kommt hier eine "entsprechende Funktion" für ListBoxen. Vergleichbare Lösungen gibt es bereits im "großen" Forum, allerdings nicht so kompakt. Ich hoffe, das Beispiel und die Kommentare in der Funktion sind Erklärung genug:
Spoiler anzeigen
; *********************************************************
; Das untenstehende Beispiel funktioniert nur im 32Bit-Mode
; *********************************************************
#AutoIt3Wrapper_UseX64=n
; *********************************************************
#include <GUIConstantsEx.au3>
[/autoit] [autoit][/autoit] [autoit]$hGUI = GUICreate("ListBox Drag&Drop", 300, 400)
$idList = GUICtrlCreateList("", 20, 20, 260, 360)
GUICtrlSetData(-1, "List1|List2|List3|List4|List5|List6")
_DragListBox($idList, "Init", 0, 0)
[/autoit] [autoit][/autoit] [autoit]GUISetState()
[/autoit] [autoit][/autoit] [autoit]While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
; #FUNCTION# ====================================================================================================================
; Name...........: _DragListBox
; Description ...: ListBox-Einträge per Drag&Drop verschieben.
; Syntax.........: _DragListBox($hWnd, $iMsg, $wParam, $lParam)
; Parameters ....: $hWnd - HWND des Fensters - bei direktem Aufruf mit $iMsg = "Init" ID des List-Controls
; $iMsg - Nachrichtennummer - bei direktem Aufruf "Init"
; $wParam - WPARAM - bei direktem Aufruf 0 (wird ignoriert)
; $lParam - LPARAM - bei direktem Aufruf 0 (wird ignoriert)
; Return values .: Erfolg: - True
; Fehler: - False
; Author ........: Großvater (http://www.autoit.de)
; Modified.......:
; Remarks .......: Für jedes List-Control muss die Funktion einmal direkt mit den Parametern
; $hWnd = ID des List-Controls aus GuiCtrlCreateList()
; $iMsg = "Init"
; $wParam = egal
; $lParam = egal
; aufgerufen werden. Beim ersten direkten Aufruf wird die Funktion mit GUIRegisterMsg()
; als Messagehandler für die speziellen Drag&Drop-Nachrichten registriert.
; Related .......:
; Link ..........: http://msdn.microsoft.com/en-us/library/…28VS.85%29.aspx
; Example .......:
; ===============================================================================================================================
Func _DragListBox($hWnd, $iMsg, $wParam, $lParam)
Local Static $MSGINIT = "Init"
Local Static $DRAGLISTMSGSTRING = "commctrl_DragListMsg"
Local Static $DL_CURSORSET = 0
Local Static $DL_STOPCURSOR = 1
Local Static $DL_COPYCURSOR = 2
Local Static $DL_MOVECURSOR = 3
Local Static $DL_BEGINDRAG = 0x485
Local Static $DL_DRAGGING = 0x486
Local Static $DL_DROPPED = 0x487
Local Static $DL_CANCELDRAG = 0x488
Local Static $LB_INSERTSTRING = 0x181
Local Static $LB_DELETESTRING = 0x182
Local Static $LB_SETCURSEL = 0x186
Local Static $LB_GETTEXT = 0x189
Local Static $LB_GETTEXTLEN = 0x18A
Local Static $DLMSG = 0
Local Static $CTRLLIST = ""
Local Static $LBITEMB = -1
Local Static $LBITEME = -1
Local $aResult, $idCtrl, $hCtrl, $CURSOR, $DRAGLISTINFO, $LBITEM, $LBTEXT, $Len, $Pos, $Notification, $X, $Y
; INIT -----------------------------------------------------------------------------------------------------------------------
If $iMSG = $MSGINIT Then
$idCtrl = $hWnd
$hCtrl = GUICtrlGetHandle($hWnd)
$CTRLLIST &= $idCtrl & "|" & $hCtrl & @LF
$aResult = DllCall("Comctl32.dll", "BOOL", "MakeDragList", "HWND", $hCtrl)
If @error Or $aResult[0] = 0 Then Return False
If Not $DLMSG Then
$aResult = DllCall("User32.dll", "UINT", "RegisterWindowMessageW", "WStr", $DRAGLISTMSGSTRING)
If @error Or $aResult[0] = 0 Then Return False
$DLMSG = $aResult[0]
GUIRegisterMsg($DLMSG, "_DragListBox")
EndIf
Return True
EndIf
; DRAGLISTINFO (lParam) -----------------------------------------------------------------------------------------------------
$DRAGLISTINFO = DllStructCreate("UINT uNotification; HWND hWnd; LONG ptX; LONG ptY", $lParam)
$Notification = DllStructGetData($DRAGLISTINFO, "uNotification")
$hCtrl = HWnd(DllStructGetData($DRAGLISTINFO, "hWnd"))
$X = DllStructGetData($DRAGLISTINFO, "ptX")
$Y = DllStructGetData($DRAGLISTINFO, "ptY")
$aResult = StringRegExp($CTRLLIST, "(?i)(?m)^([0-9a-fx]+)\|(" & $hCtrl & ")$", 1)
If @error Then Return False
$idCtrl = $aResult[0]
$hCtrl = $aResult[1]
$aResult = DllCall("Comctl32.dll", "INT", "LBItemFromPt","HWND", $hCtrl, "LONG", $X, "LONG", $Y, "BOOL", 1)
If @error Then Return False
$LBITEM = $aResult[0]
; Notification --------------------------------------------------------------------------------------------------------------
Switch $Notification
Case $DL_BEGINDRAG
If $LBITEM = -1 Then Return False
$LBITEMB = $LBITEM
Return True
Case $DL_DRAGGING
$LBITEME = $LBITEM
DllCall("Comctl32.dll", "None", "DrawInsert", "HWND", $hWnd, "HWND", $hCtrl, "INT", $LBITEME)
If $LBITEME = -1 Then Return $DL_STOPCURSOR
Return $DL_MOVECURSOR
Case $DL_DROPPED
DllCall("Comctl32.dll", "None", "DrawInsert", "HWND", $hWnd, "HWND", $hCtrl, "INT", -1)
$LBITEME = $LBITEM
If $LBITEME = -1 Or $LBITEMB = $LBITEME Then Return
$Len = GUICtrlSendMsg($idCtrl, $LB_GETTEXTLEN, $LBITEMB, 0)
$LBTEXT = DllStructCreate("WChar [" & $Len+1 & "]")
GUICtrlSendMsg($idCtrl, $LB_GETTEXT, $LBITEMB, DllStructGetPtr($LBTEXT))
GUICtrlSendMsg($idCtrl, $LB_DELETESTRING, $LBITEMB, 0)
If $LBITEMB < $LBITEME Then $LBITEME -= 1
$Pos = GUICtrlSendMsg($idCtrl, $LB_INSERTSTRING, $LBITEME, DllStructGetPtr($LBTEXT))
GUICtrlSendMsg($idCtrl, $LB_SETCURSEL, $Pos, 0)
Case $DL_CANCELDRAG
DllCall("Comctl32.dll", "None", "DrawInsert", "HWND", $hWnd, "HWND", $hCtrl, "INT", -1)
EndSwitch
EndFunc