Achilles Posted May 4, 2010 Share Posted May 4, 2010 I'm trying to make a list where you can drag and drop and pretty much arrange your list just by moving items yourself (no sort). However, so far I can't do any of that. Any listview I try creating doesn't allow me to do that.. I looked at all the other _GUICtrlListView_* functions but they don't seem to have the answer. I searched, but closest thing to what I wanted was this page... which is two years old and has a bunch of constants autoit no longer recognizes. Just try to starting with _GUICtrlListView_Create.. it has the constants I referred to above commented out.. My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list] Link to comment Share on other sites More sharing options...
GEOSoft Posted May 4, 2010 Share Posted May 4, 2010 I couldn't get that working either so i settled for a couple of buttons (Up and Down) to move an item. I wrote a function Named GUIListViewItem_Swap() to handle it. Here is some example code for it that I submited. Hope it's of some use to you. expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> GUICreate("ListView Item Swap", 300, 200) Global $hListView = GUICtrlCreateListView("Column1|Column2|Column3", 10, 10, 280, 140) For $i = 0 to 3 GUICtrlCreateListViewItem("Item " & $i & "|" & "SubItem " & $i & "-2|Subitem " & $i & "-3", $hListView) Next $Btn_Up = GUICtrlCreateButton("Up", 100, 160, 40, 30) GUICtrlSetState(-1, $GUI_DISABLE) $Btn_Dn = GUICtrlCreateButton("Down", 160, 160, 40, 30) GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() _GUICtrlListView_RegisterSortCallBack($hListView) While 1 $i_Item = Number(_GUICtrlListView_GetSelectedIndices($hListView)) If _GUICtrlListView_GetSelectedIndices($hListView) = "" Then If BitAND(GUICtrlGetState($Btn_Dn), $GUI_ENABLE) = $GUI_ENABLE Then GUICtrlSetState($Btn_Dn, $GUI_DISABLE) GUICtrlSetState($Btn_Up, $GUI_DISABLE) EndIf Else If BitAND(GUICtrlGetState($Btn_Dn), $GUI_DISABLE) = $GUI_DISABLE Then GUICtrlSetState($Btn_Dn, $GUI_ENABLE) GUICtrlSetState($Btn_Up, $GUI_ENABLE) EndIf EndIf $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE ExitLoop Case $hListView _GUICtrlListView_SortItems($hListView, GUICtrlGetState($hListView)) Case $Btn_Dn If $i_Item = _GUICtrlListView_GetItemCount($hListView) -1 Then ContinueLoop _GUICtrlListView_ItemSwap($hListView, $i_Item, $i_Item + 1) _GUICtrlListView_SetItemSelected($hListView, $i_Item + 1) GUICtrlSetState($hListView, $GUI_FOCUS) Case $Btn_Up If $i_Item = 0 Then ContinueLoop _GUICtrlListView_ItemSwap($hListView, $i_Item, $i_Item - 1) _GUICtrlListView_SetItemSelected($hListView, $i_Item - 1) GUICtrlSetState($hListView, $GUI_FOCUS) EndSwitch WEnd _GUICtrlListView_UnRegisterSortCallBack($hListView) GUIDelete() Func _GUICtrlListView_ItemSwap($hListView, $i_Index, $i_NewIndex) $i_Index = Number($i_Index) $i_NewIndex = Number($i_NewIndex) Local $aOrig = _GUICtrlListView_GetItemTextArray($hListView, $i_Index) Local $aSwap = _GUICtrlListView_GetItemTextArray($hListView, $i_NewIndex) For $i = 1 To UBound($aOrig) - 1 _GUICtrlListView_SetItemText($hListView, $i_NewIndex, $aOrig[$i], $i - 1) _GUICtrlListView_SetItemText($hListView, $i_Index, $aSwap[$i], $i - 1) Next EndFunc ;==>_GUICtrlListView_ItemSwap George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
Achilles Posted May 4, 2010 Author Share Posted May 4, 2010 I couldn't get that working either so i settled for a couple of buttons (Up and Down) to move an item. I wrote a function Named GUIListViewItem_Swap() to handle it. Here is some example code for it that I submited. Hope it's of some use to you. <code> Hmm, that will work... I still wish there was a nice simple way to drag them for order... Thanks for putting this together, I'll definitely use it if no knows how to do it using the mouse.. It's a fairly basic part of windows listviews so I figured it wouldn't be too complicated, but I guess I was wrong.. Well, on second thought maybe not... maybe I'm just use to foobar letting me move stuff how I want. My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list] Link to comment Share on other sites More sharing options...
picaxe Posted May 4, 2010 Share Posted May 4, 2010 Here's a quick hack of the _GUIImageList_Drag* help file example (with some small tweeks). You would probably want to remove the image list code.expandcollapse popupOpt("MustDeclareVars", 1) #include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <GuiImageList.au3> #include <WindowsConstants.au3> #include <Constants.au3> #Include <SendMessage.au3> Global $hDragImageList, $h_ListView, $bDragging = False, $LV_Height, $fNoImage Global $a_index[2] ; from and to Global Const $DebugIt = 0 Opt("WinTitleMatchMode", 2) Local Const $image_width = 20 Local Const $image_height = 20 Local $h_images, $main_GUI, $iIndex, $sTitle = "Listview Drag & Drop Rearrange" Switch MsgBox(262144 + 4, $sTitle, '"Yes" for listview with icons' & @LF & '"No" for standard listview') Case 6 $fNoImage = False Case 7 $fNoImage = True EndSwitch $main_GUI = GUICreate($sTitle, 350, 300) $h_ListView = _GUICtrlListView_Create($main_GUI, "Entry Name|Category", 5, 10, 340, 280, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE)) $LV_Height = 280 - 75 _GUICtrlListView_SetColumnWidth($h_ListView, 0, 160) _GUICtrlListView_SetColumnWidth($h_ListView, 1, 160) If $fNoImage Then _GUICtrlListView_SetExtendedListViewStyle($h_ListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) Else _GUICtrlListView_SetExtendedListViewStyle($h_ListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES)) _GUICtrlListView_SetExtendedListViewStyle($h_ListView, BitOR($LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_SUBITEMIMAGES)) EndIf ;------------------------------------------------------ ; Using subitem images ;------------------------------------------------------ If Not $fNoImage Then $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) EndIf ;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() 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 $aItemText = _GUICtrlListView_GetItem($h_ListView, $i_FromItem) ; DllStructGetData($struct_String, "Buffer") only gets first letter possible bug ? Local $i_newIndex = _GUICtrlListView_InsertItem($h_ListView, _GUICtrlListView_GetItemText($h_ListView, $i_FromItem), $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 Func ListView_Click() ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("$NM_CLICK") ;---------------------------------------------------------------------------------------------- EndFunc ;==>ListView_Click Func ListView_DoubleClick() ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("$NM_DBLCLK") ;---------------------------------------------------------------------------------------------- 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]) If IsArray($hDragImageList) Then _GUIImageList_Destroy($hDragImageList[0]) ; gw _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 $a_index[0] < $a_index[1] Or $a_index[0] > $a_index[1] Then 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) ; commenting out this shows dragged image ? _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 Func _DebugPrint($s_text) $s_text = StringReplace($s_text, @LF, @LF & "-->") ConsoleWrite("!===========================================================" & @LF & _ "+===========================================================" & @LF & _ "-->" & $s_text & @LF & _ "+===========================================================" & @LF) EndFunc ;==>_DebugPrint Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now