Jump to content

Recommended Posts

Posted (edited)

Hi guys, i have this script:

include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiEdit.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>

Global $hEdit, $hDC, $hBrush, $Item = -1, $SubItem = 0, $Number = 0, $hMenu
Global Enum $idMoveUp = 1000, $idMoveDown, $idDelete
Global $Style = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)

$hGUI = GUICreate("_GUICtrlListView_Example", 262, 351, -1, -1)
$cListview = GUICtrlCreateListView("N°|Test|Test2", 5, 5, 250, 272, $LVS_REPORT)
$hListview = GUICtrlGetHandle($cListview)
_GUICtrlListView_SetExtendedListViewStyle($hListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_BORDERSELECT))
_GUICtrlListView_SetColumnWidth($hListview, 0, 35)
_GUICtrlListView_SetColumnWidth($hListview, 1, 107)
_GUICtrlListView_SetColumnWidth($hListview, 2, 108)
$Label = GUICtrlCreateLabel("Name", 13, 290, 67, 17)
$c_Button_Add = GUICtrlCreateButton("Add", 90, 315, 80, 25)
$Info = GUICtrlCreateInput("Value", 88, 286, 83, 21)
$c_Button_Save = GUICtrlCreateButton("Save", 174, 284, 80, 25)

$hMenu = _GUICtrlMenu_CreatePopup()
_GUICtrlMenu_InsertMenuItem($hMenu, 0, "Move Up", $idMoveUp)
_GUICtrlMenu_InsertMenuItem($hMenu, 1, "Move Down", $idMoveDown)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "Delete", $idDelete)

$c_Dummy_Down = GUICtrlCreateDummy()
$c_Dummy_Up = GUICtrlCreateDummy()
$c_Dummy_Delete = GUICtrlCreateDummy()
$c_Dummy_Enter = GUICtrlCreateDummy()

Local $AccelKeys[4][2] = [["{DELETE}", $c_Dummy_Delete],["{UP}", $c_Dummy_Up],["{DOWN}", $c_Dummy_Down],["{ENTER}", $c_Dummy_Enter]]
 
GUISetAccelerators($AccelKeys, $hGUI)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListview)]
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $c_Button_Add
            Add_Item()
        Case $c_Button_Save
            Save_List()
        Case $c_Dummy_Delete
            Delete_Item()
        Case $c_Dummy_Down
            Move_Down()
        Case $c_Dummy_Up
            Move_Up()
        Case $c_Dummy_Enter
            If _WinAPI_GetFocus() = $hEdit Then _WinAPI_SetFocus($hListview) ; fires $EN_KILLFOCUS in WM_COMMAND
        Case $cListview
            _GUICtrlListView_SimpleSort($hListview, $B_DESCENDING, GUICtrlGetState($cListview))
    EndSwitch
WEnd

Func Add_Item()
    $Number += 1
    _GUICtrlListView_AddItem($hListview, $Number, -1, 9999 + $Number) ; add lparam value, is used for sorting as far as I remember
    _GUICtrlListView_AddSubItem($hListview, $Number - 1, GUICtrlRead($Label), 1)
    _GUICtrlListView_AddSubItem($hListview, $Number - 1, GUICtrlRead($Info), 2)
EndFunc   ;==>Add_Item
Func Delete_Item()
    _GUICtrlListView_DeleteItemsSelected($hListview)
    _Arrange_Numbers()
EndFunc   ;==>Delete_Item
Func _Arrange_Numbers()
    Dim $iCount = 0
    $Total_Number = _GUICtrlListView_GetItemCount($hListview) - 1
    For $i = 0 To $Total_Number
        $iCount += 1
        _GUICtrlListView_SetItemText($hListview, $i, $iCount)
    Next
EndFunc   ;==>_Arrange_Numbers

Func Save_List()
    Local $Save = FileSaveDialog("Save", @WorkingDir, "Txt Files (*.txt)", 2, "Test_File_" & @MDAY & "-" & @MON & "-" & @YEAR & "_" & @HOUR & "-" & @MIN)
    If @error Then
        ConsoleWrite("Abort")
    Else
        $List = FileOpen($Save & ".txt", 2)
        $Number_items = _GUICtrlListView_GetItemCount($hListview)
        For $i = 0 To $Number_items - 1 Step +1
            $output = StringReplace(_GUICtrlListView_GetItemTextString($hListview, $i), "|", " - ")
            FileWriteLine($List, $output)
        Next
        FileClose($List)
    EndIf
EndFunc   ;==>Save_List

Func Move_Up()
    Local $Sel, $aArrayListView
    $aArrayListView = _GUICtrlListView_CreateArray($hListview)
    $Sel = _GUICtrlListView_GetNextItem($hListview)
    If $Sel > 0 Then
        Local $SelItem, $NxtItem
        $SelItem = _GUICtrlListView_GetItemTextArray($hListview, $Sel)
        $PrvItem = _GUICtrlListView_GetItemTextArray($hListview, $Sel - 1)
        For $i = 1 To $SelItem[0]
            $aArrayListView[$Sel][$i - 1] = $PrvItem[$i]
            $aArrayListView[$Sel - 1][$i - 1] = $SelItem[$i]
            _GUICtrlListView_SetItemText($hListview, $Sel, $PrvItem[$i], $i - 1)
            _GUICtrlListView_SetItemText($hListview, $Sel - 1, $SelItem[$i], $i - 1)
            _GUICtrlListView_SetItemSelected($hListview, $Sel, 0)
            _GUICtrlListView_SetItemSelected($hListview, $Sel - 1)
        Next
    EndIf
    _Arrange_Numbers()
EndFunc   ;==>Move_Up

Func Move_Down()
    Local $Sel, $Lst, $aArrayListView
    $aArrayListView = _GUICtrlListView_CreateArray($hListview)
    $Sel = _GUICtrlListView_GetNextItem($hListview)
    $Lst = _GUICtrlListView_GetItemCount($hListview) - 1
    If $Sel < $Lst And $Sel <> -1 Then
        Local $SelItem, $NxtItem
        $SelItem = _GUICtrlListView_GetItemTextArray($hListview, $Sel)
        $NxtItem = _GUICtrlListView_GetItemTextArray($hListview, $Sel + 1)
        For $i = 1 To $SelItem[0]
            $aArrayListView[$Sel][$i - 1] = $NxtItem[$i]
            $aArrayListView[$Sel + 1][$i - 1] = $SelItem[$i]
            _GUICtrlListView_SetItemText($hListview, $Sel, $NxtItem[$i], $i - 1)
            _GUICtrlListView_SetItemText($hListview, $Sel + 1, $SelItem[$i], $i - 1)
            _GUICtrlListView_SetItemSelected($hListview, $Sel, 0)
            _GUICtrlListView_SetItemSelected($hListview, $Sel + 1)
        Next
    EndIf
    _Arrange_Numbers()
EndFunc   ;==>Move_Down

Func _GUICtrlListView_CreateArray($hListview, $sDelimeter = '|')
    Local $iColumnCount = _GUICtrlListView_GetColumnCount($hListview), $iDim = 0, $iItemCount = _GUICtrlListView_GetItemCount($hListview)
    If $iColumnCount < 3 Then
        $iDim = 3 - $iColumnCount
    EndIf
    If $sDelimeter = Default Then
        $sDelimeter = '|'
    EndIf
    Local $aColumns = 0, $aReturn[$iItemCount + 1][$iColumnCount + $iDim] = [[$iItemCount, $iColumnCount, '']]
    For $i = 0 To $iColumnCount - 1
        $aColumns = _GUICtrlListView_GetColumn($hListview, $i)
        $aReturn[0][2] &= $aColumns[5] & $sDelimeter
    Next
    $aReturn[0][2] = StringTrimRight($aReturn[0][2], StringLen($sDelimeter))
    For $i = 0 To $iItemCount - 1
        For $j = 0 To $iColumnCount - 1
            $aReturn[$i + 1][$j] = _GUICtrlListView_GetItemText($hListview, $i, $j)
        Next
    Next
    Return SetError(Number($aReturn[0][0] = 0), 0, $aReturn)
EndFunc   ;==>_GUICtrlListView_CreateArray

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tNMHDR, $hWndFrom, $iCode
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListview
            Switch $iCode
                Case $NM_DBLCLK
                    Local $aHit = _GUICtrlListView_SubItemHitTest($hListview)
                    If ($aHit[0] <> -1) And ($aHit[1] = 0) Then
                        $Item = $aHit[0]
                        $SubItem = 0
                        Local $aRect = _GUICtrlListView_GetItemRect($hListview, $Item)
                    ElseIf ($aHit[0] <> -1) And ($aHit[1] > 0) Then
                        $Item = $aHit[0]
                        $SubItem = $aHit[1]
                        Local $aRect = _GUICtrlListView_GetSubItemRect($hListview, $Item, $SubItem)
                    Else
                        Return $GUI_RUNDEFMSG
                    EndIf
                    Local $iItemText = _GUICtrlListView_GetItemText($hListview, $Item, $SubItem)
                    Local $iLen = _GUICtrlListView_GetStringWidth($hListview, $iItemText)
                    $hEdit = _GUICtrlEdit_Create($hGUI, $iItemText, $aRect[0] + 8, $aRect[1] + 7, $iLen + 10, 17, $Style)
                    _GUICtrlEdit_SetSel($hEdit, 0, -1)
                    _WinAPI_SetFocus($hEdit)
                    $hDC = _WinAPI_GetWindowDC($hEdit)
                    $hBrush = _WinAPI_CreateSolidBrush(0x0000FF)
                    FrameRect($hDC, 0, 0, $iLen + 10, 17, $hBrush)
                Case $NM_RCLICK
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    If DllStructGetData($tInfo, "Item") > -1 Then
                        _GUICtrlMenu_TrackPopupMenu($hMenu, $hGUI)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func FrameRect($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBrush)
    Local $stRect = DllStructCreate("int;int;int;int")
    DllStructSetData($stRect, 1, $nLeft)
    DllStructSetData($stRect, 2, $nTop)
    DllStructSetData($stRect, 3, $nRight)
    DllStructSetData($stRect, 4, $nBottom)
    DllCall("user32.dll", "int", "FrameRect", "hwnd", $hDC, "ptr", DllStructGetPtr($stRect), "hwnd", $hBrush)
EndFunc   ;==>FrameRect

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iCode = BitShift($wParam, 16)
    Switch $lParam
        Case $hEdit
            Switch $iCode
                Case $EN_KILLFOCUS
                    Local $iText = _GUICtrlEdit_GetText($hEdit)
                    _GUICtrlListView_SetItemText($hListview, $Item, $iText, $SubItem)
                    _WinAPI_DeleteObject($hBrush)
                    _WinAPI_ReleaseDC($hEdit, $hDC)
                    _WinAPI_DestroyWindow($hEdit)
                    $Item = -1
                    $SubItem = 0
            EndSwitch
    EndSwitch
    Switch $wParam
        Case $idMoveUp
            Move_Up()
        Case $idMoveDown
            Move_Down()
        Case $idDelete
            Delete_Item()
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

I can sort item with ARROW_UP and ARROW_DOWN on the keyboard, move in one position

Work if i select ONE item, not work with multiple items ( CTRL + Click )

How i can manage multiple item selecting and Move_Func?

Thanks for any help

Edited by johnmcloud
  • Moderators
Posted (edited)

johnmcloud,

Look inside my GUIListViewEx UDF and you will see how I did it. ;)

M23

Edit: Although I now notice that I only move multiple items by dragging, the principle should be transferable. Let me know if you run into problems and we can work on it together later in the week. :)

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted (edited)

Hi Melba, you don't want to make my life easier? :D

If you have time

Many func of your UDF to check how it work:

_GUIListViewEx_Up ( Down )

_GUIListViewEx_Array_Swap

_GUIListViewEx_Data_Change

_GUIListViewEx_Highlight

_GUIListViewEx_Return_Array

Edited by johnmcloud
  • Moderators
Posted

johnmcloud,

I know how it works! :D

Let me look into seeing how we might get your script to do something similar - but I am off to London soon to see a concert with my son (the wonderful Steven Wilson at the Royal Festival Hall) and I will not be able to work on it until I return late tomorrow. So please be patient. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted

johnmcloud,

I know how it works! :D

I was referring to me :D

Let me look into seeing how we might get your script to do something similar - but I am off to London soon to see a concert with my son (the wonderful Steven Wilson at the Royal Festival Hall) and I will not be able to work on it until I return late tomorrow. So please be patient. :)

M23

Ok, don't worry. Have fun ;)

Posted (edited)

Where did you get _GUICtrlListView_CreateArray from? I'm not looking for my name to be there, but a link would be useful just in case I update that function in the future, you understand?

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Posted

guinness, is yours? i don't have idea, really, i have find it somewhere on another site many time ago, 7-8 month i think. I don't remember the site anyway

Posted (edited)

guinness, is yours? i don't have idea, really, i have find it somewhere on another site many time ago, 7-8 month i think. I don't remember the site anyway

Sigh! That's why people should post a back reference, not out of courtesy, but out of common sense for if the developer updates the UDF. Are you sure it's 7-8 months? As the code above was created 4 months ago. Oh well, never mind. Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

  • Moderators
Posted

johnmcloud,

The concert was suitably epic and I had a splendid evening. :thumbsup:

To give you a flavour, this is taken from the last tour - but it was the opener last night:

Now to work on your problem. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted (edited)

I'm glad you have enjoyed the concert ;)

And you don't have forget about me, thanks for your time/help

EDIT: Cool video :D

Edited by johnmcloud
  • Moderators
Posted (edited)

johnmcloud,

I have now got my UDF to move multiple items both dragged and via a button - now to get your script to do it. :)

M23

Edit:

Here is a version of your script which uses the UDF:

#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiEdit.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>

#include "GUIListViewEx_Mod.au3"

Global $hEdit, $hDC, $hBrush, $Item = -1, $SubItem = 0, $Number = 0, $hMenu
Global Enum $idMoveUp = 1000, $idMoveDown, $idDelete
Global $Style = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)

$hGUI = GUICreate("_GUICtrlListView_Example", 262, 351, -1, -1)
$cListview = GUICtrlCreateListView("N°|Test|Test2", 5, 5, 250, 272, $LVS_REPORT)
$hListview = GUICtrlGetHandle($cListview)
_GUICtrlListView_SetExtendedListViewStyle($hListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_BORDERSELECT))
_GUICtrlListView_SetColumnWidth($hListview, 0, 35)
_GUICtrlListView_SetColumnWidth($hListview, 1, 107)
_GUICtrlListView_SetColumnWidth($hListview, 2, 108)

$iLV_Index = _GUIListViewEx_Init($hListview, "", 0, 0, True)

$Label = GUICtrlCreateLabel("Name", 13, 290, 67, 17)
$c_Button_Add = GUICtrlCreateButton("Add", 90, 315, 80, 25)
$Info = GUICtrlCreateInput("Value", 88, 286, 83, 21)
$c_Button_Save = GUICtrlCreateButton("Save", 174, 284, 80, 25)

$hMenu = _GUICtrlMenu_CreatePopup()
_GUICtrlMenu_InsertMenuItem($hMenu, 0, "Move Up", $idMoveUp)
_GUICtrlMenu_InsertMenuItem($hMenu, 1, "Move Down", $idMoveDown)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "Delete", $idDelete)

$c_Dummy_Down = GUICtrlCreateDummy()
$c_Dummy_Up = GUICtrlCreateDummy()
$c_Dummy_Delete = GUICtrlCreateDummy()
$c_Dummy_Enter = GUICtrlCreateDummy()

Local $AccelKeys[4][2] = [["{DELETE}", $c_Dummy_Delete],["{UP}", $c_Dummy_Up],["{DOWN}", $c_Dummy_Down],["{ENTER}", $c_Dummy_Enter]]
GUISetAccelerators($AccelKeys, $hGUI)

Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListview)]

GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $c_Button_Add
            Add_Item()
        Case $c_Button_Save
            Save_List()
        Case $c_Dummy_Delete
            Delete_Item()
        Case $c_Dummy_Down
            Move_Down()
        Case $c_Dummy_Up
            Move_Up()
        Case $c_Dummy_Enter
            If _WinAPI_GetFocus() = $hEdit Then _WinAPI_SetFocus($hListview) ; fires $EN_KILLFOCUS in WM_COMMAND
            ;Case $cListview
            ;    _GUICtrlListView_SimpleSort($hListview, $B_DESCENDING, GUICtrlGetState($cListview))
    EndSwitch
WEnd

Func Add_Item()
    $Number += 1
    $vData = $Number & "|" & GUICtrlRead($Label) & "|" & GUICtrlRead($Info)
    _GUIListViewEx_Insert($vData)
EndFunc   ;==>Add_Item

Func Delete_Item()
    _GUIListViewEx_Delete()
EndFunc   ;==>Delete_Item

Func Save_List()
    Local $Save = FileSaveDialog("Save", @WorkingDir, "Txt Files (*.txt)", 2, "Test_File_" & @MDAY & "-" & @MON & "-" & @YEAR & "_" & @HOUR & "-" & @MIN)
    If @error Then
        ConsoleWrite("Abort")
    Else
        $List = FileOpen($Save & ".txt", 2)
        $Number_items = _GUICtrlListView_GetItemCount($hListview)
        For $i = 0 To $Number_items - 1 Step +1
            $output = StringReplace(_GUICtrlListView_GetItemTextString($hListview, $i), "|", " - ")
            FileWriteLine($List, $output)
        Next
        FileClose($List)
    EndIf
EndFunc   ;==>Save_List

Func Move_Up()
    _GUIListViewEx_Up()
EndFunc   ;==>Move_Up

Func Move_Down()
    _GUIListViewEx_Down()
EndFunc   ;==>Move_Down


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)

    _GUIListViewEx_WM_NOTIFY_Handler($hWnd, $iMsg, $iwParam, $ilParam)

    Local $tNMHDR, $hWndFrom, $iCode
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListview
            Switch $iCode
                Case $NM_DBLCLK
                    Local $aHit = _GUICtrlListView_SubItemHitTest($hListview)
                    If ($aHit[0] <> -1) And ($aHit[1] = 0) Then
                        $Item = $aHit[0]
                        $SubItem = 0
                        Local $aRect = _GUICtrlListView_GetItemRect($hListview, $Item)
                    ElseIf ($aHit[0] <> -1) And ($aHit[1] > 0) Then
                        $Item = $aHit[0]
                        $SubItem = $aHit[1]
                        Local $aRect = _GUICtrlListView_GetSubItemRect($hListview, $Item, $SubItem)
                    Else
                        Return $GUI_RUNDEFMSG
                    EndIf
                    Local $iItemText = _GUICtrlListView_GetItemText($hListview, $Item, $SubItem)
                    Local $iLen = _GUICtrlListView_GetStringWidth($hListview, $iItemText)
                    $hEdit = _GUICtrlEdit_Create($hGUI, $iItemText, $aRect[0] + 8, $aRect[1] + 7, $iLen + 10, 17, $Style)
                    _GUICtrlEdit_SetSel($hEdit, 0, -1)
                    _WinAPI_SetFocus($hEdit)
                    $hDC = _WinAPI_GetWindowDC($hEdit)
                    $hBrush = _WinAPI_CreateSolidBrush(0x0000FF)
                    FrameRect($hDC, 0, 0, $iLen + 10, 17, $hBrush)
                Case $NM_RCLICK
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    If DllStructGetData($tInfo, "Item") > -1 Then
                        _GUICtrlMenu_TrackPopupMenu($hMenu, $hGUI)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func FrameRect($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBrush)
    Local $stRect = DllStructCreate("int;int;int;int")
    DllStructSetData($stRect, 1, $nLeft)
    DllStructSetData($stRect, 2, $nTop)
    DllStructSetData($stRect, 3, $nRight)
    DllStructSetData($stRect, 4, $nBottom)
    DllCall("user32.dll", "int", "FrameRect", "hwnd", $hDC, "ptr", DllStructGetPtr($stRect), "hwnd", $hBrush)
EndFunc   ;==>FrameRect

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iCode = BitShift($wParam, 16)
    Switch $lParam
        Case $hEdit
            Switch $iCode
                Case $EN_KILLFOCUS
                    Local $iText = _GUICtrlEdit_GetText($hEdit)
                    _GUICtrlListView_SetItemText($hListview, $Item, $iText, $SubItem)
                    _WinAPI_DeleteObject($hBrush)
                    _WinAPI_ReleaseDC($hEdit, $hDC)
                    _WinAPI_DestroyWindow($hEdit)
                    $Item = -1
                    $SubItem = 0
            EndSwitch
    EndSwitch
    Switch $wParam
        Case $idMoveUp
            Move_Up()
        Case $idMoveDown
            Move_Down()
        Case $idDelete
            Delete_Item()
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

And here is a beta version of the UDF which does the multiple selection move you wanted - save as GUIListViewEx_Mod.au3:

#include-once

; #INDEX# ============================================================================================================
; Title .........: GUIListViewEx
; AutoIt Version : 3.3 +
; Language ......: English
; Description ...: Permits insertion, deletion, moving, dragging and sorting of items within activated ListViews
; Remarks .......: - It is important to use _GUIListViewEx_Close when a enabled ListView is deleted to free the memory used
;                    by the $aGLVEx_Data array which shadows the ListView contents.
;                  - If the script already has WM_NOTIFY, WM_MOUSEMOVE or WM_LBUTTONUP handlers then only set the
;                    unregistered messages in _GUIListViewEx_DragRegister and call the relevant _GUIListViewEx_WM_#####_Handler from
;                    within the existing handler
;                  - Uses 2 undocumented function within GUIListView UDF to set and colour insert mark (thanks rover)
; Author ........: Melba23 - credit to martin (basic drag code), Array.au3 authors (original array functions)
; Modified ......;
; ====================================================================================================================

;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

; #INCLUDES# =========================================================================================================
#include <GuiListView.au3>
#include <GUIImageList.au3>

; #GLOBAL VARIABLES# =================================================================================================
; Array to hold registered ListView data
Global $aGLVEx_Data[1][7] = [[0, 0]]
; [0][0] = Count            [n][0] = ListView handle
; [0][1] = Active Index        [n][1] = Native ListView ControlID / 0
;                             [n][2] = Content array
;                             [n][3] = [0] element is count
;                           [n][4] = Sorting array
;                           [n][5] = Drag image
;                             [n][6] = Checkbox array
; Variables for all UDF functions
Global $hGLVEx_Handle, $hGLVEx_CID, $aGLVEx_Array
; Variables for UDF dragging handlers
Global $iGLVEx_Dragging = 0, $iGLVExDragged_Index, $hGLVExDragged_Image = 0, $iGLVExInsert_Index = -1, $iGLVExLast_Y
Global $fGLVEx_Bar_Under, $fGLVEx_MultipleDrag, $aGLVExDragCheck_Array

; #CURRENT# ==========================================================================================================
; _GUIListViewEx_Init:                 Enables UDF button functions for the ListView and sets insert mark colour
; _GUIListViewEx_Close:                Disables all UDF functions for the specified ListView and clears all memory used
; _GUIListViewEx_SetActive:            Set specified ListView as active for UDF functions
; _GUIListViewEx_GetActive:            Get index number of ListView active for UDF functions
; _GUIListViewEx_Return_Array:         Returns an array reflecting the current state of the ListView
; _GUIListViewEx_Insert:               Inserts data just below selected item in active ListView
; _GUIListViewEx_Delete:               Deletes selected item in active ListView
; _GUIListViewEx_Up:                   Moves selected item in active ListView up 1 place
; _GUIListViewEx_Down                  Moves selected item in active ListView down 1 place
; _GUIListViewEx_DragRegister:         Registers Windows messages to enable item dragging for listed ListViews
; _GUIListViewEx_WM_NOTIFY_Handler:    Windows message handler for WM_NOTIFY
; _GUIListViewEx_WM_MOUSEMOVE_Handler: Windows message handler for WM_MOUSEMOVE
; _GUIListViewEx_WM_LBUTTONUP_Handler: Windows message handler for WM_LBUTTONUP
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _GUIListViewEx_HighLight:    Highlights specified ListView item and ensures it is visible
; _GUIListViewEx_Data_Change:  Resets ListView items within a defined range to the current values in the stored array
; _GUIListViewEx_Array_Add:    Adds a specified value at the end of an array
; _GUIListViewEx_Array_Insert: Adds a value at the specified index of an array
; _GUIListViewEx_Array_Delete: Deletes a specified index from an array
; _GUIListViewEx_Array_Swap:   Swaps specified elements within an array
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Init
; Description ...: Enables UDF button functions for the ListView and sets insert mark colour for drag function
; Syntax.........: _GUIListViewEx_Init($hLV, [$aArray = "", [$iStart = 0, [$iColour, [$fSort, $fImage]]]]])
; Parameters ....: $hLV     - Handle or ControlID of ListView
;                  $a Array - Name of array used to fill ListView.  "" = empty ListView
;                  $iStart  - 0 (default) = ListView data starts in [0] element of array, 1 = Count in [0] element
;                  $iColour - RGB colour for insert mark (default = black)
;                  $fSort   - True = ListView can be sorted by click on column header - (Default = False)
;                  $fImage  - True = Shadow image of dragged item when dragging
; Requirement(s).: v3.3 +
; Return values .: Index number of ListView for use in other GUIListViewEx functions
; Author ........: Melba23
; Modified ......:
; Remarks .......: - If the ListView is the only one enabled, it is automatically set as active
;                  - If no array is passed a shadow array is created automatically - if the ListView has more than
;                  1 column this array is 2D with the second dimension set to the number of columns
;                  - The shadow array has a count in element [0] added if it does not exist. However, if the $iStart
;                  parameter is set to 0 this count element will not be returned by other GUIListViewEx functions
;                  - Only first item of a multiple selection is shadow imaged when dragging (API limitation)
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Init($hLV, $aArray = "", $iStart = 0, $iColour = 0, $fSort = False, $fImage = False)

    Local $iIndex = 0

    ; See if there is a blank line available in the array
    For $i = 1 To $aGLVEx_Data[0][0]
        If $aGLVEx_Data[$i][0] = 0 Then
            $iIndex = $i
            ExitLoop
        EndIf
    Next
    ; If no blank line found then increase array size
    If $iIndex = 0 Then
        $aGLVEx_Data[0][0] += 1
        ReDim $aGLVEx_Data[$aGLVEx_Data[0][0] + 1][7]
        $iIndex = $aGLVEx_Data[0][0]
    EndIf

    ; Store ListView handle and ControlID
    If IsHWnd($hLV) Then
        $aGLVEx_Data[$iIndex][0] = $hLV
        $aGLVEx_Data[$iIndex][1] = 0
    Else
        $aGLVEx_Data[$iIndex][0] = GUICtrlGetHandle($hLV)
        $aGLVEx_Data[$iIndex][1] = $hLV
    EndIf

    ; Create a shadow array if needed
    If $aArray = "" Then
        Local $iCols = _GUICtrlListView_GetColumnCount($aGLVEx_Data[$iIndex][0])
        Switch $iCols
            Case 1
                Local $aReplacement[1] = [0]
            Case Else
                Local $aReplacement[1][$iCols] = [[0]]
        EndSwitch
        $aArray = $aReplacement
    Else
        ; Add count element to shadow array if required
        If $iStart = 0 Then _GUIListViewEx_Array_Insert($aArray, 0, UBound($aArray))
    EndIf
    ; Store array
    $aGLVEx_Data[$iIndex][2] = $aArray

    ; Store [0] = count data
    $aGLVEx_Data[$iIndex][3] = $iStart
    ; If sortable, store sort array
    If $fSort Then
        Local $aLVSortState[_GUICtrlListView_GetColumnCount($hLV)]
        $aGLVEx_Data[$iIndex][4] = $aLVSortState
    Else
        $aGLVEx_Data[$iIndex][4] = 0
    EndIf
    ; If image required
    If $fImage Then
        $aGLVEx_Data[$iIndex][5] = 1
    EndIf
    ;  If checkbox extended style
    If BitAnd(_GUICtrlListView_GetExtendedListViewStyle($hLV), 4) Then ; $LVS_EX_CHECKBOXES
        $aGLVEx_Data[$iIndex][6] = 1
    EndIf

    ; Set insert mark colour after conversion to BGR
    _GUICtrlListView_SetInsertMarkColor($hLV, BitOR(BitShift(BitAND($iColour, 0x000000FF), -16), BitAND($iColour, 0x0000FF00), BitShift(BitAND($iColour, 0x00FF0000), 16)))

    ; If only 1 current ListView then activate
    Local $iListView_Count = 0
    For $i = 1 To $iIndex
        If $aGLVEx_Data[$i][0] Then $iListView_Count += 1
    Next
    If $iListView_Count = 1 Then _GUIListViewEx_SetActive($iIndex)

    ; Return ListView index
    Return $iIndex

EndFunc   ;==>_GUIListViewEx_Init

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Close
; Description ...: Disables all UDF functions for the specified ListView and clears all memory used
; Syntax.........: _GUIListViewEx_Close($iIndex)
; Parameters ....: $iIndex - Index number of ListView to close as returned by _GUIListViewEx_Init
;                            0 (default) = Closes all ListViews
; Requirement(s).: v3.3 +
; Return values .: Success: 1
;                  Failure: 0 and @error set to 1 - Invalid index number
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Close($iIndex = 0)

    ; Check valid index
    If $iIndex < 0 Or $iIndex > $aGLVEx_Data[0][0] Then Return SetError(1, 0, 0)

    If $iIndex = 0 Then
        ; Remove all ListView data
        Global $aGLVEx_Data[1][7] = [[0, 0]]
    Else
        ; Reset all data for ListView
        For $i = 0 To 6
            $aGLVEx_Data[$iIndex][$i] = 0
        Next

        ; Cancel active index if set to this ListView
        If $aGLVEx_Data[0][1] = $iIndex Then $aGLVEx_Data[0][1] = 0
    EndIf

    Return 1

EndFunc   ;==>_GUIListViewEx_Close

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_SetActive
; Description ...: Set specified ListView as active for UDF functions
; Syntax.........: _GUIListViewEx_SetActive($iIndex)
; Parameters ....: $iIndex - Index number of ListView as returned by _GUIListViewEx_Init
;                  An index of 0 clears any current setting
; Requirement(s).: v3.3 +
; Return values .: Success: Returns previous active index number, 0 = no previously active ListView
;                  Failure: -1 and @error set to 1 - Invalid index number
; Author ........: Melba23
; Modified ......:
; Remarks .......: ListViews can also be activated by clicking on them
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_SetActive($iIndex)

    ; Check valid index
    If $iIndex < 0 Or $iIndex > $aGLVEx_Data[0][0] Then Return SetError(1, 0, -1)

    Local $iCurr_Index = $aGLVEx_Data[0][1]

    If $iIndex Then
        ; Store index of specified ListView
        $aGLVEx_Data[0][1] = $iIndex
        ; Set values for specified ListView
        $hGLVEx_Handle = $aGLVEx_Data[$iIndex][0]
        $hGLVEx_CID = $aGLVEx_Data[$iIndex][1]
    Else
        ; Clear active index
        $aGLVEx_Data[0][1] = 0
    EndIf

    Return $iCurr_Index

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_GetActive
; Description ...: Get index number of ListView active for UDF functions
; Syntax.........: _GUIListViewEx_GetActive()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Index number as returned by _GUIListViewEx_Init, 0 = no active ListView
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_GetActive()

    Return $aGLVEx_Data[0][1]

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Return_Array
; Description ...: Returns an array reflecting the current state of the ListView
; Syntax.........: _GUIListViewEx_Return_Array($iIndex)
; Parameters ....: $iIndex - Index number of ListView as returned by _GUIListViewEx_Init
;                  $iCheck - If non-zero then the state of the checkboxes is returned (Default = 0)
; Requirement(s).: v3.3 +
; Return values .: Success: Array of current ListView - presence of count in [0] element determined by _GUIListViewEx_Init
;                  Failure: Empty array returns null string and sets @error as follows:
;                           1 = Invalid index number
;                           2 = Empty array (no items in ListView)
;                           3 = $iCheck set to True but ListView does not have checkbox style
; Author ........: Melba23
; Modified ......:
; Remarks .......: The $iStart parameter from GUIListViewEx_Init determines whether the [0] element is a count
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Return_Array($iIndex, $iCheck = 0)

    ; Check valid index
    If $iIndex < 1 Or $iIndex > $aGLVEx_Data[0][0] Then Return SetError(1, 0, "")

    ; Copy current array
    Local $aRetArray = $aGLVEx_Data[$iIndex][2]

    ; Check if checkbox array
    If $iCheck Then
        If $aGLVEx_Data[$iIndex][6] Then
            Local $aCheck_Array[UBound($aRetArray)]
            For $i = 1 To UBound($aRetArray) - 1
                $aCheck_Array[$i] = _GUICtrlListView_GetItemChecked($aGLVEx_Data[$iIndex][0], $i - 1)
            Next
            ; Remove count element if required
            If $aGLVEx_Data[$iIndex][3] = 0 Then
                ; Check at least one entry in 1D/2D array
                Switch UBound($aRetArray, 0)
                    Case 1
                        If $aRetArray[0] = 0 Then Return SetError(2, 0, "")
                    Case 2
                        If $aRetArray[0][0] = 0 Then Return SetError(2, 0, "")
                EndSwitch
                ; Delete count element
                _GUIListViewEx_Array_Delete($aCheck_Array, 0)
            EndIf
            Return $aCheck_Array
        Else
            Return SetError(3, 0, "")
        EndIf
    EndIf

    ; Remove count element of array if required
    If $aGLVEx_Data[$iIndex][3] = 0 Then
        ; Check at least one entry in 1D/2D array
        Switch UBound($aRetArray, 0)
            Case 1
                If $aRetArray[0] = 0 Then Return SetError(2, 0, "")
            Case 2
                If $aRetArray[0][0] = 0 Then Return SetError(2, 0, "")
        EndSwitch
        ; Delete count element
        _GUIListViewEx_Array_Delete($aRetArray, 0)
    EndIf

    ; Return array
    Return $aRetArray

EndFunc   ;==>_GUIListViewEx_Return_Array

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Insert
; Description ...: Inserts data just below selected item in active ListView
;                  If no selection, data added at end
; Syntax.........: _GUIListViewEx_Insert($vData)
; Parameters ....: $vData - Data to insert, can be in array or delimited string format
; Requirement(s).: v3.3 +
; Return values .: Success: Array of current ListView with count in [0] element
;                  Failure: If no ListView active then returns "" and sets @error to 1
; Author ........: Melba23
; Modified ......:
; Remarks .......: - New data is inserted after the selected item.  If no item is selected then the datat is added at
;                  the end of the ListView.  If multiple items are selected, the data is inserted after the first
;                  - $vData can be passed in string or array format - it is automatically transformed if required
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Insert($vData)

    Local $vInsert

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, "")

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Get selected item in ListView
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    Local $iInsert_Index = $iIndex
    ; If no selection
    If $iIndex = "" Then $iInsert_Index = -1
    ; Check for multiple selections
    If StringInStr($iIndex, "|") Then
        Local $aIndex = StringSplit($iIndex, "|")
        ; Use first selection
        $iIndex = $aIndex[1]
        ; Cancel all other selections
        For $i = 2 To $aIndex[0]
            _GUICtrlListView_SetItemSelected($hGLVEx_Handle, $aIndex[$i], False)
        Next
    EndIf

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Create Local array for checkboxes if required
    If $aGLVEx_Data[$iArray_Index][6] Then
        Local $aCheck_Array[UBound($aGLVEx_Array)]
        For $i = 1 To UBound($aCheck_Array) - 1
            $aCheck_Array[$i] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $i - 1)
        Next
    EndIf

    ; Check if 1D/2D array
    Switch UBound($aGLVEx_Array, 0)
        Case 1
            ; If empty array insert at 0
            If $aGLVEx_Array[0] = 0 Then $iInsert_Index = 0
            ; Get data into string format for insert
            If IsArray($vData) Then
                $vInsert = ""
                For $i = 0 To UBound($vData) - 1
                    $vInsert &= $vData[$i] & "|"
                Next
                $vInsert = StringTrimRight($vInsert, 1)
            Else
                $vInsert = $vData
            EndIf
            ; Increase count
            $aGLVEx_Array[0] += 1
        Case 2
            ; If empty array insert at 0
            If $aGLVEx_Array[0][0] = 0 Then $iInsert_Index = 0
            ; Get data into array format for insert
            If IsArray($vData) Then
                $vInsert = $vData
            Else
                Local $aData = StringSplit($vData, "|")
                Switch $aData[0]
                    Case 1
                        $vInsert = $aData[1]
                    Case Else
                        Local $vInsert[$aData[0]]
                        For $i = 0 To $aData[0] - 1
                            $vInsert[$i] = $aData[$i + 1]
                        Next
                EndSwitch
            EndIf
            ; Increase count
            $aGLVEx_Array[0][0] += 1
    EndSwitch

    ; Insert data into array
    If $iIndex = "" Then
        _GUIListViewEx_Array_Add($aGLVEx_Array, $vInsert)
    Else
        _GUIListViewEx_Array_Insert($aGLVEx_Array, $iInsert_Index + 2, $vInsert)
        If $aGLVEx_Data[$iArray_Index][6] Then
            _GUIListViewEx_Array_Insert($aCheck_Array, $iInsert_Index + 2, False)
            ; Reset all checkboxes
            For $i = 1 To UBound($aCheck_Array) - 1
                _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $i - 1, $aCheck_Array[$i])
            Next
        EndIf
    EndIf

    ; Check if Native or UDF
    If $hGLVEx_CID Then
        ; Add new item at ListView end
        If IsArray($vInsert) Then
            If IsArray($vData) Then
                $vInsert = ""
                For $i = 0 To UBound($vData) - 1
                    $vInsert &= $vData[$i] & "|"
                Next
                $vInsert = StringTrimRight($vInsert, 1)
                GUICtrlCreateListViewItem($vInsert, $hGLVEx_CID)
            Else
                GUICtrlCreateListViewItem($vData, $hGLVEx_CID)
            EndIf
        Else
            GUICtrlCreateListViewItem($vInsert, $hGLVEx_CID)
        EndIf
    Else
        ; Add new item at ListView end
        Local $iNewItem
        If IsArray($vInsert) Then
            $iNewItem = _GUICtrlListView_AddItem($hGLVEx_Handle, $vInsert[0])
            ; Add new subitems
            For $i = 1 To UBound($vInsert) - 1
                _GUICtrlListView_AddSubItem($hGLVEx_Handle, $iNewItem, $vInsert[$i], $i)
            Next
        Else
            $iNewItem = _GUICtrlListView_AddItem($hGLVEx_Handle, $vInsert)
        EndIf
    EndIf
    ; Check where item was to be inserted
    If $iIndex = "" Then
        _GUIListViewEx_Data_Change($iInsert_Index, $iInsert_Index)
        ; No moves required so set highlight
        _GUIListViewEx_Highlight(_GUICtrlListView_GetItemCount($hGLVEx_Handle) - 1)
    Else
        ; Reset item contents below insert position
        _GUIListViewEx_Data_Change($iInsert_Index, _GUICtrlListView_GetItemCount($hGLVEx_Handle) - 1)
        ; Set highlight
        _GUIListViewEx_Highlight($iInsert_Index + 1, $iInsert_Index)
    EndIf

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Insert

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Delete
; Description ...: Deletes selected item in active ListView
; Syntax.........: _GUIListViewEx_Delete()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Array of active ListView with count in [0] element
;                  Failure: Returns "" and sets @error as follows:
;                      1 = No ListView active
;                      2 = No item selected
;                      3 = No items to delete
; Author ........: Melba23
; Modified ......:
; Remarks .......: If multiple items are selected, all are deleted
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Delete()

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, "")

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Check for selected items
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    If $iIndex = "" Then Return SetError(2, 0, "")

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Determine final item
    Local $iLast = UBound($aGLVEx_Array) - 2

    ; Check if item is part of a multiple selection
    If StringInStr($iIndex, "|") Then
        ; Extract all selected items
        Local $aIndex = StringSplit($iIndex, "|")
        For $i = 1 To $aIndex[0]
            ; Remove highlighting from items
            _GUICtrlListView_SetItemSelected($hGLVEx_Handle, $i, False)
        Next

        ; Check if 1D/2D array
        Switch UBound($aGLVEx_Array, 0)
            Case 1
                ; Decrease count
                $aGLVEx_Array[0] -= $aIndex[0]
            Case 2
                ; Decrease count
                $aGLVEx_Array[0][0] -= $aIndex[0]
        EndSwitch

        ; Delete elements from array - start from bottom
        For $i = $aIndex[0] To 1 Step -1
            _GUIListViewEx_Array_Delete($aGLVEx_Array, $aIndex[$i] + 1)
        Next

        ; Delete items from ListView - again start from bottom
        For $i = $aIndex[0] To 1 Step -1
            _GUICtrlListView_DeleteItem($hGLVEx_Handle, $aIndex[$i])
        Next

    Else
        ; Check if 1D/2D array
        Switch UBound($aGLVEx_Array, 0)
            Case 1
                ; Decrease count
                $aGLVEx_Array[0] -= 1
            Case 2
                ; Decrease count
                $aGLVEx_Array[0][0] -= 1
        EndSwitch
        ; Delete element from array
        _GUIListViewEx_Array_Delete($aGLVEx_Array, $iIndex + 1)

        ; Delete item from ListView
        _GUICtrlListView_DeleteItem($hGLVEx_Handle, $iIndex)
        ; Set highlight - up one if bottom deleted
        If $iIndex = $iLast Then
            _GUIListViewEx_Highlight($iIndex - 1)
        Else
            _GUIListViewEx_Highlight($iIndex)
        EndIf
    EndIf

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Delete

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Up
; Description ...: Moves selected item in active ListView up 1 place
; Syntax.........: _GUIListViewEx_Up()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Array of active ListView with count in [0] element
;                  Failure: Returns "" and sets @error as follows:
;                      1 = No ListView active
;                      2 = No item selected
;                      3 = Item already at top
; Author ........: Melba23
; Modified ......:
; Remarks .......: If multiple items are selected, only the top consecutive block is moved
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Up()

    Local $iGLVExMove_Index, $iGLVEx_Moving = 0

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, 0)

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Check for selected items
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    Local $aIndex = StringSplit($iIndex, "|")
    $iGLVExMove_Index = $aIndex[1]
    ; Check if item is part of a multiple selection
    If $aIndex[0] > 1 Then
        ; Check for consecutive items
        For $i = 1 To $aIndex[0] - 1
            If $aIndex[$i + 1] = $aIndex[1] + $i Then
                $iGLVEx_Moving += 1
            Else
                ExitLoop
            EndIf
        Next
    Else
        $iGLVExMove_Index = $aIndex[1]
    EndIf

    ; Remove all highlighting
    _GUICtrlListView_SetItemSelected($hGLVEx_Handle, -1, False)

    ; Check not top item
    If $iGLVExMove_Index = "0" Then Return SetError(3, 0, "")

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Move consecutive items
    For $iIndex = $iGLVExMove_Index To $iGLVExMove_Index + $iGLVEx_Moving

        ; Swap array elements
        _GUIListViewEx_Array_Swap($aGLVEx_Array, $iIndex, $iIndex + 1)

        ; Swap checkboxes if required
        If $aGLVEx_Data[$iArray_Index][6] Then
            Local $fTemp = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex)
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex, _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex - 1))
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex - 1, $fTemp)
        EndIf

        ; Change data in affected items
        _GUIListViewEx_Data_Change($iIndex - 1, $iIndex);, $aGLVEx_Array)
        ; Set highlight and cancel existing one (needed for multiple selection ListViews)
        _GUIListViewEx_Highlight($iIndex - 1, $iIndex)
    Next

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Up

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Down
; Description ...: Moves selected item in active ListView down 1 place
; Syntax.........: _GUIListViewEx_Down()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Array of active ListView with count in [0] element
;                  Failure: Returns "" and sets @error as follows:
;                      1 = No ListView active
;                      2 = No item selected
;                      3 = Item already at bottom
; Author ........: Melba23
; Modified ......:
; Remarks .......: If multiple items are selected, only the bottom consecutive block is moved
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Down()

    Local $iGLVExMove_Index, $iGLVEx_Moving = 0

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, 0)

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Check for selected items
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    Local $aIndex = StringSplit($iIndex, "|")
    ; Check if item is part of a multiple selection
    If $aIndex[0] > 1 Then
        $iGLVExMove_Index = $aIndex[$aIndex[0]]
        ; Check for consecutive items
        For $i = 1 To $aIndex[0] - 1
            If $aIndex[$aIndex[0] - $i] = $aIndex[$aIndex[0]] - $i Then
                $iGLVEx_Moving += 1
            Else
                ExitLoop
            EndIf
        Next
    Else
        $iGLVExMove_Index = $aIndex[1]
    EndIf

    ; Remove all highlighting
    _GUICtrlListView_SetItemSelected($hGLVEx_Handle, -1, False)

    ; Check not last item
    If $iGLVExMove_Index = _GUICtrlListView_GetItemCount($hGLVEx_Handle) - 1 Then
        _GUIListViewEx_Highlight($iIndex)
        Return
    EndIf

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Move consecutive items
    For $iIndex = $iGLVExMove_Index To $iGLVExMove_Index - $iGLVEx_Moving Step -1

        ; Swap array elements
        _GUIListViewEx_Array_Swap($aGLVEx_Array, $iIndex + 1, $iIndex + 2)

        ; Swap checkboxes if required
        If $aGLVEx_Data[$iArray_Index][6] Then
            Local $fTemp = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex)
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex, _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex + 1))
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex + 1, $fTemp)
        EndIf

        ; Change data in affected items
        _GUIListViewEx_Data_Change($iIndex, $iIndex + 1)
        ; Set highlight and cancel existing one (needed for multiple selection ListViews)
        _GUIListViewEx_Highlight($iIndex + 1, $iIndex)

    Next

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Down

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_DragRegister
; Description ...: Registers Windows messages needed for the UDF
; Syntax.........: _GUIListViewEx_DragRegister([$fNOTIFY = True, [$fMOUSEMOVE = True, [$fLBUTTONUP = True]]])
; Parameters ....: $fNOTIFY    - True = Register WM_NOTIFY message
;                  $fMOUSEMOVE - True = Register WM_MOUSEMOVE message
;                  $fLBUTTONUP - True = Register WM_LBUTTONUP message
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If other handlers already registered, then call the relevant handler function from within that handler
;                  If no dragging is required, only the WM_NOTIFY handler needs to be registered
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_DragRegister($fNOTIFY = True, $fMOUSEMOVE = True, $fLBUTTONUP = True)

    ; Register required messages
    If $fNOTIFY    Then GUIRegisterMsg(0x004E, "_GUIListViewEx_WM_NOTIFY_Handler")    ; $WM_NOTIFY
    If $fMOUSEMOVE Then GUIRegisterMsg(0x0200, "_GUIListViewEx_WM_MOUSEMOVE_Handler") ; $WM_MOUSEMOVE
    If $fLBUTTONUP Then GUIRegisterMsg(0x0202, "_GUIListViewEx_WM_LBUTTONUP_Handler") ; $WM_LBUTTONUP

EndFunc   ;==>_GUIListViewEx_DragRegister

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_WM_NOTIFY_Handler
; Description ...: Windows message handler for WM_NOTIFY
; Syntax.........: _GUIListViewEx_WM_NOTIFY_Handler
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If a WM_NOTIFY handler already registered, then call this function from within that handler
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_WM_NOTIFY_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam

    ; Struct = $tagNMHDR and "int Item;int SubItem" from $tagNMLISTVIEW
    Local $tStruct = DllStructCreate("hwnd;uint_ptr;int_ptr;int;int", $lParam)
    If @error Then Return

    Local $iCode = BitAND(DllStructGetData($tStruct, 3), 0xFFFFFFFF)

    Switch $iCode
        Case $LVN_COLUMNCLICK, -2 ; $NM_CLICK
            ; Check if enabled ListView
            For $i = 1 To $aGLVEx_Data[0][0]
                If DllStructGetData($tStruct, 1) = $aGLVEx_Data[$i][0] Then
                    ExitLoop
                EndIf
            Next
            If $i > $aGLVEx_Data[0][0] Then Return ; Not enabled

            ; Set values for active ListView
            $aGLVEx_Data[0][1] = $i
            $hGLVEx_Handle = $aGLVEx_Data[$i][0]
            $hGLVEx_CID = $aGLVEx_Data[$i][1]
            $aGLVEx_Array = $aGLVEx_Data[$i][2]

            ; Sort if a column header was clicked and ListView is sortable
            If $iCode = $LVN_COLUMNCLICK And IsArray($aGLVEx_Data[$i][4]) Then
                ; Load current ListView sort state array
                Local $aLVSortState = $aGLVEx_Data[$aGLVEx_Data[0][0]][4]
                ; Sort column - get column from from struct
                _GUICtrlListView_SimpleSort($hGLVEx_Handle, $aLVSortState, DllStructGetData($tStruct, 5))
                ; Store new ListView sort state array
                $aGLVEx_Data[$aGLVEx_Data[0][0]][4] = $aLVSortState
                ; Reread listview items into array
                Switch UBound($aGLVEx_Array, 0) ; Check array format
                    Case 1
                        For $j = 1 To $aGLVEx_Array[0]
                            $aGLVEx_Array[$j] = _GUICtrlListView_GetItemTextString($hGLVEx_Handle, $j - 1)
                        Next
                    Case 2
                        Local $iDim2 = UBound($aGLVEx_Array, 2) - 1
                        For $j = 1 To $aGLVEx_Array[0][0]
                            For $k = 0 To $iDim2
                                $aGLVEx_Array[$j][$k] = _GUICtrlListView_GetItemText($hGLVEx_Handle, $j - 1, $k)
                            Next
                        Next
                EndSwitch
                ; Store amended array
                $aGLVEx_Data[$i][2] = $aGLVEx_Array
            EndIf

        Case $LVN_BEGINDRAG
            ; Check if enabled ListView
            For $i = 1 To $aGLVEx_Data[0][0]
                If DllStructGetData($tStruct, 1) = $aGLVEx_Data[$i][0] Then
                    ExitLoop
                EndIf
            Next
            If $i > $aGLVEx_Data[0][0] Then Return ; Not registered

            ; Set values for this ListView
            $aGLVEx_Data[0][1] = $i
            $hGLVEx_Handle = $aGLVEx_Data[$i][0]
            $hGLVEx_CID = $aGLVEx_Data[$i][1]
            Local $fImage = $aGLVEx_Data[$i][5]
            Local $fCheck = $aGLVEx_Data[$i][6]
            ; Copy array for manipulation
            $aGLVEx_Array = $aGLVEx_Data[$i][2]

            ; Check if Native or UDF and set focus
            If $hGLVEx_CID Then
                GUICtrlSetState($hGLVEx_CID, 256) ; $GUI_FOCUS
            Else
                _WinAPI_SetFocus($hGLVEx_Handle)
            EndIf

            ; Get dragged item index
            $iGLVExDragged_Index = DllStructGetData($tStruct, 4) ; Item
            ; Set dragged item count
            $iGLVEx_Dragging = 1

            ; Check for selected items
            Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
            ; Check if item is part of a multiple selection
            If StringInStr($iIndex, $iGLVExDragged_Index) And StringInStr($iIndex, "|") Then
                ; Extract all selected items
                Local $aIndex = StringSplit($iIndex, "|")
                For $i = 1 To $aIndex[0]
                    If $aIndex[$i] = $iGLVExDragged_Index Then ExitLoop
                Next
                ; Now check for consecutive items
                If $i <> 1 Then ; Up
                    For $j = $i - 1 To 1 Step -1
                        ; Consecutive?
                        If $aIndex[$j] <> $aIndex[$j + 1] - 1 Then ExitLoop
                        ; Adjust dragged index to this item
                        $iGLVExDragged_Index -= 1
                        ; Increase number to drag
                        $iGLVEx_Dragging += 1
                    Next
                EndIf
                If $i <> $aIndex[0] Then ; Down
                    For $j = $i + 1 To $aIndex[0]
                        ; Consecutive
                        If $aIndex[$j] <> $aIndex[$j - 1] + 1 Then ExitLoop
                        ; Increase number to drag
                        $iGLVEx_Dragging += 1
                    Next
                EndIf
            Else ; Either no selection or only a single
                ; Set flag
                $iGLVEx_Dragging = 1
            EndIf

            ; Remove all highlighting
            _GUICtrlListView_SetItemSelected($hGLVEx_Handle, -1, False)

            ; Create drag image
            If $fImage Then
                Local $aImageData = _GUICtrlListView_CreateDragImage($hGLVEx_Handle, $iGLVExDragged_Index)
                $hGLVExDragged_Image = $aImageData[0]
                _GUIImageList_BeginDrag($hGLVExDragged_Image, 0, 0, 0)
            EndIf

            ; Create Global array for checkboxes if required
            If $fCheck Then
                Global $aGLVExDragCheck_Array[UBound($aGLVEx_Array)]
                For $i = 1 To UBound($aGLVExDragCheck_Array) - 1
                    $aGLVExDragCheck_Array[$i] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $i - 1)
                Next
            EndIf

    EndSwitch

EndFunc   ;==>_GUIListViewEx_WM_NOTIFY_Handler

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_WM_MOUSEMOVE_Handler
; Description ...: Windows message handler for WM_NOTIFY
; Syntax.........: _GUIListViewEx_WM_MOUSEMOVE_Handler
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If a WM_MOUSEMOVE handler already registered, then call this function from within that handler
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_WM_MOUSEMOVE_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $iMsg, $wParam

    If Not $iGLVEx_Dragging Then Return "GUI_RUNDEFMSG"

    Local $aLV_Pos, $tLVHITTESTINFO, $iCurr_Index

    ; Get current mouse Y coord
    Local $iCurr_Y = BitShift($lParam, 16)

    ; Set insert mark to correct side of items depending on sense of movement when cursor within range
    If $iGLVExInsert_Index <> -1 Then
        If $iGLVExLast_Y = $iCurr_Y Then
            Return "GUI_RUNDEFMSG"
        ElseIf $iGLVExLast_Y > $iCurr_Y Then
            $fGLVEx_Bar_Under = False
            _GUICtrlListView_SetInsertMark($hGLVEx_Handle, $iGLVExInsert_Index, False)
        Else
            $fGLVEx_Bar_Under = True
            _GUICtrlListView_SetInsertMark($hGLVEx_Handle, $iGLVExInsert_Index, True)
        EndIf
    EndIf
    ; Store current Y coord
    $iGLVExLast_Y = $iCurr_Y

    ; Get ListView item under mouse - depends on ListView type
    If $hGLVEx_CID Then
        $aLV_Pos = ControlGetPos($hWnd, "", $hGLVEx_CID)
        $tLVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
        ; Force response even if off side of GUI - normal X coord = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
        DllStructSetData($tLVHITTESTINFO, 1, 1)
        DllStructSetData($tLVHITTESTINFO, 2, $iCurr_Y - $aLV_Pos[1])
        ; Get item under mouse
        $iCurr_Index = GUICtrlSendMsg($hGLVEx_CID, $LVM_HITTEST, 0, DllStructGetPtr($tLVHITTESTINFO))
    Else
        ; Get coords of client area
        Local $tPoint = DllStructCreate("int X;int Y")
        DllStructSetData($tPoint, "X", 0)
        DllStructSetData($tPoint, "Y", 0)
        Local $pPoint = DllStructGetPtr($tPoint)
        DllCall("user32.dll", "bool", "ClientToScreen", "hwnd", $hWnd, "ptr", $pPoint)
        ; Get coords of ListView
        $aLV_Pos = WinGetPos($hGLVEx_Handle)
        Local $iY = $iCurr_Y - $aLV_Pos[1] + DllStructGetData($tPoint, "Y")
        $tLVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
        ; Force response even if off side of GUI - normal X coord = BitAND($lParam, 0xFFFF) - $aLV_Pos[0] + DllStructGetData($tPoint, "X")
        DllStructSetData($tLVHITTESTINFO, 1, 1)
        DllStructSetData($tLVHITTESTINFO, 2, $iY)
        Local $pLVHITTESTINFO = DllStructGetPtr($tLVHITTESTINFO)
        ; Get item under mouse
        Local $aRet = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hGLVEx_Handle, "uint", $LVM_HITTEST, "wparam", 0, "lparam", $pLVHITTESTINFO)
        $iCurr_Index = $aRet[0]
    EndIf

    ; If mouse is above or below ListView then scroll ListView
    If $iCurr_Index = -1 Then
        If $fGLVEx_Bar_Under Then
            _GUICtrlListView_Scroll($hGLVEx_Handle, 0, 10)
        Else
            _GUICtrlListView_Scroll($hGLVEx_Handle, 0, -10)
        EndIf
        Sleep(100)
    EndIf

    ; Check if over same item
    If $iGLVExInsert_Index = $iCurr_Index Then Return "GUI_RUNDEFMSG"

    ; Show insert mark on current item
    _GUICtrlListView_SetInsertMark($hGLVEx_Handle, $iCurr_Index, $fGLVEx_Bar_Under)
    ; Store current item
    $iGLVExInsert_Index = $iCurr_Index

EndFunc   ;==>_GUIListViewEx_WM_MOUSEMOVE_Handler

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_WM_LBUTTONUP_Handler
; Description ...: Windows message handler for WM_NOTIFY
; Syntax.........: _GUIListViewEx_WM_LBUTTONUP_Handler
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If a WM_LBUTTONUP handler already registered, then call this function from within that handler
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_WM_LBUTTONUP_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam, $lParam

    If Not $iGLVEx_Dragging Then Return "GUI_RUNDEFMSG"

    ; Get item count
    Local $iMultipleItems = $iGLVEx_Dragging - 1

    ; Reset flag
    $iGLVEx_Dragging = 0

    ; Check mouse within ListView
    If $iGLVExInsert_Index = -1 Then
        ; Clear insert mark
        _GUICtrlListView_SetInsertMark($hGLVEx_Handle, -1, True)
        ; Reset highlight to original items
        For $i = 0 To $iMultipleItems
            _GUIListViewEx_HighLight($iGLVExDragged_Index + $i)
        Next
        Return
    EndIf

    ; Determine position to insert
    If $fGLVEx_Bar_Under Then
        If $iGLVExDragged_Index > $iGLVExInsert_Index Then $iGLVExInsert_Index += 1
    Else
        If $iGLVExDragged_Index < $iGLVExInsert_Index Then $iGLVExInsert_Index -= 1
    EndIf

    ; Clear insert mark
    _GUICtrlListView_SetInsertMark($hGLVEx_Handle, -1, True)

    ; Clear drag image
    If $hGLVExDragged_Image Then
        _GUIImageList_DragLeave($hGLVEx_Handle)
        _GUIImageList_EndDrag()
        _GUIImageList_Destroy($hGLVExDragged_Image)
        $hGLVExDragged_Image = 0
    EndIf

    ; Check not dropping on dragged item(s)
    Switch $iGLVExInsert_Index
        Case $iGLVExDragged_Index To $iGLVExDragged_Index + $iMultipleItems
            ; Reset highlight to original items
            For $i = 0 To $iMultipleItems
                _GUIListViewEx_HighLight($iGLVExDragged_Index + $i)
            Next
            Return
    EndSwitch

    ; Amend array
    ; Get data from dragged element(s)
    If $iMultipleItems Then
        ; Multiple dragged elements
        Switch UBound($aGLVEx_Array, 0) ; Check array format
            Case 1
                Local $aInsertData[$iMultipleItems + 1]
                For $i = 0 To $iMultipleItems
                    $aInsertData[$i] = $aGLVEx_Array[$iGLVExDragged_Index + 1 + $i]
                Next
            Case 2
                Local $aInsertData[$iMultipleItems + 1]
                For $i = 0 To $iMultipleItems
                    Local $aItemData[UBound($aGLVEx_Array, 2)]
                    For $j = 0 To UBound($aGLVEx_Array, 2) - 1
                        $aItemData[$j] = $aGLVEx_Array[$iGLVExDragged_Index + 1][$j]
                    Next
                    $aInsertData[$i] = $aItemData
                Next
        EndSwitch
    Else
        ; Single dragged element
        Switch UBound($aGLVEx_Array, 0) ; Check array format
            Case 1
                Local $aInsertData[1]
                $aInsertData[0] = $aGLVEx_Array[$iGLVExDragged_Index + 1]
            Case 2
                Local $aInsertData[1]
                Local $aItemData[UBound($aGLVEx_Array, 2)]
                For $i = 0 To UBound($aGLVEx_Array, 2) - 1
                    $aItemData[$i] = $aGLVEx_Array[$iGLVExDragged_Index + 1][$i]
                Next
                $aInsertData[0] = $aItemData
        EndSwitch
    EndIf

    ; Copy checkbox data from dragged elements
    If IsArray($aGLVExDragCheck_Array) Then
        If $iMultipleItems Then
            Local $aDragged_Data[$iMultipleItems + 1]
            For $i = 0 To $iMultipleItems
                $aDragged_Data[$i] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iGLVExDragged_Index + $i)
            Next
        Else
            Local $aDragged_Data[1]
            $aDragged_Data[0] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iGLVExDragged_Index)
        EndIf
    EndIf

    ; Delete dragged element(s) from arrays
    For $i = 0 To $iMultipleItems
        _GUIListViewEx_Array_Delete($aGLVEx_Array, $iGLVExDragged_Index + 1)
        If IsArray($aGLVExDragCheck_Array) Then
            _GUIListViewEx_Array_Delete($aGLVExDragCheck_Array, $iGLVExDragged_Index + 1)
        EndIf
    Next

    ; Amend insert positon for multiple items deleted above
    If $iGLVExDragged_Index < $iGLVExInsert_Index Then
        $iGLVExInsert_Index -= $iMultipleItems
    EndIf
    ; Re-insert dragged element(s) into array
    For $i = $iMultipleItems To 0 Step -1
        _GUIListViewEx_Array_Insert($aGLVEx_Array, $iGLVExInsert_Index + 1, $aInsertData[$i])
        If IsArray($aGLVExDragCheck_Array) Then
            _GUIListViewEx_Array_Insert($aGLVExDragCheck_Array, $iGLVExInsert_Index + 1, $aDragged_Data[$i])
        EndIf
    Next

    ; Amend ListView to match array
    If $iGLVExDragged_Index > $iGLVExInsert_Index Then
        _GUIListViewEx_Data_Change($iGLVExInsert_Index, $iGLVExDragged_Index + $iMultipleItems)
    Else
        _GUIListViewEx_Data_Change($iGLVExDragged_Index, $iGLVExInsert_Index + $iMultipleItems)
    EndIf

    ; Reset checkbox data
    If IsArray($aGLVExDragCheck_Array) Then
        For $i = 1 To UBound($aGLVExDragCheck_Array) - 1
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $i - 1, $aGLVExDragCheck_Array[$i])
        Next
        ; Clear array
        $aGLVExDragCheck_Array = 0
    EndIf

    ; Set highlight to inserted item(s)
    For $i = 0 To $iMultipleItems
        _GUIListViewEx_HighLight($iGLVExInsert_Index + $i)
    Next

    ; Store amended array
    $aGLVEx_Data[$aGLVEx_Data[0][1]][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0

EndFunc   ;==>_GUIListViewEx_WM_LBUTTONUP_Handler

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_HighLight($iIndexA, $iIndexB)
; Description ...: Highlights first item and ensures visible while removing hightlight from second in multiple selection ListViews
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================
Func _GUIListViewEx_Highlight($iIndexA, $iIndexB = -1)

    ; Check if Native or UDF and set focus
    If $hGLVEx_CID Then
        GUICtrlSetState($hGLVEx_CID, 256) ; $GUI_FOCUS
    Else
        _WinAPI_SetFocus($hGLVEx_Handle)
    EndIf
    ; Cancel highlight on other item - needed for multisel listviews
    If $iIndexB <> -1 Then _GUICtrlListView_SetItemSelected($hGLVEx_Handle, $iIndexB, False)
    ; Set highlight to inserted item and ensure in view
    _GUICtrlListView_SetItemState($hGLVEx_Handle, $iIndexA, $LVIS_SELECTED, $LVIS_SELECTED)
    _GUICtrlListView_EnsureVisible($hGLVEx_Handle, $iIndexA)

EndFunc   ;==>_GUIListViewEx_HighLight

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Data_Change($iStart, $iEnd)
; Description ...: Resets ListView items within a defined range to the current values in the stored array
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================
Func _GUIListViewEx_Data_Change($iStart, $iEnd)

    Local $sBlanker, $aInsert, $iDim2

    ; Check if Native or UDF
    If $hGLVEx_CID Then
        ; Native ListView
        For $i = $iStart To $iEnd
            ; Get CID of the item
            Local $iCID = _GUICtrlListView_GetItemParam($hGLVEx_Handle, $i)
            ; Check array type
            Switch UBound($aGLVEx_Array, 0)
                Case 1
                    $aInsert = StringSplit($aGLVEx_Array[$i + 1], "|", 2)
                Case 2
                    $iDim2 = UBound($aGLVEx_Array, 2)
                    Local $aInsert[$iDim2]
                    For $j = 0 To $iDim2 - 1
                        $aInsert[$j] = $aGLVEx_Array[$i + 1][$j]
                    Next
            EndSwitch
            ; Insert new data into each column in turn
            $sBlanker = ""
            For $j = 0 To UBound($aInsert) - 1
                GUICtrlSetData($iCID, $sBlanker & $aInsert[$j])
                $sBlanker &= "|"
            Next
        Next
    Else
        ; UDF ListView
        For $i = $iStart To $iEnd
            ; Check if multicolumn
            $iDim2 = UBound($aGLVEx_Array, 2)
            If @error Then
                _GUICtrlListView_SetItemText($hGLVEx_Handle, $i, $aGLVEx_Array[$i + 1])
            Else
                ; For each column - or just once if not multicolumn
                For $j = 0 To $iDim2 - 1
                    ; Set data
                    _GUICtrlListView_SetItemText($hGLVEx_Handle, $i, $aGLVEx_Array[$i + 1][$j], $j)
                Next
            EndIf
        Next
    EndIf

EndFunc   ;==>_GUIListViewEx_Data_Change

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Add
; Description ...: Adds a specified value at the end of an existing 1D or 2D array.
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================
Func _GUIListViewEx_Array_Add(ByRef $avArray, $vAdd = "", $iStart = 0)

    ; Get size of the Array to modify
    Local $iIndex_Max = UBound($avArray)

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1

            ReDim $avArray[$iIndex_Max + 1]
            $avArray[$iIndex_Max] = $vAdd

        Case 2

        ; Get size of second dimension
        Local $iDim2 = UBound($avArray, 2)

        ; Redim the Array
        ReDim $avArray[$iIndex_Max + 1][$iDim2]

        ; Add new elements
        If IsArray($vAdd) Then
            ; Get size of Insert array
            Local $vAdd_Max = UBound($vAdd)
            For $j = 0 To $iDim2 - 1
                ; If Insert array is too small to fill Array then continue with blanks
                If $j > $vAdd_Max - 1 - $iStart Then
                    $avArray[$iIndex_Max][$j] = ""
                Else
                    $avArray[$iIndex_Max][$j] = $vAdd[$j + $iStart]
                EndIf
            Next
        Else
            ; Fill Array with variable
            For $j = 0 To $iDim2 - 1
                $avArray[$iIndex_Max][$j] = $vAdd
            Next
        EndIf

    EndSwitch

    Return $iIndex_Max

EndFunc   ;==>_GUIListViewEx_Array_Add

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Insert
; Description ...: Adds a value at the specified index of a 1D or 2D array.
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================

Func _GUIListViewEx_Array_Insert(ByRef $avArray, $iIndex, $vInsert)

    ; Get size of the Array to modify
    Local $iIndex_Max = UBound($avArray)

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1

            ; Resize array
            ReDim $avArray[$iIndex_Max + 1]

            ; Move down all elements below the new index
            For $i = $iIndex_Max To $iIndex + 1 Step -1
                $avArray[$i] = $avArray[$i - 1]
            Next

            ; Add the value in the specified element
            $avArray[$iIndex] = $vInsert
            Return $iIndex_Max

        Case 2

            ; If at end of array
            If $iIndex > $iIndex_Max - 1 Then Return $iIndex_Max = _GUIListViewEx_Array_Add($avArray, $vInsert)

            ; Get size of second dimension
            Local $iDim2 = UBound($avArray, 2)

            ; Redim the Array
            ReDim $avArray[$iIndex_Max + 1][$iDim2]

            ; Move down all elements below the new index
            For $i = $iIndex_Max To $iIndex + 1 Step -1
                For $j = 0 To $iDim2 - 1
                    $avArray[$i][$j] = $avArray[$i - 1][$j]
                Next
            Next

            ; Insert new elements
            If IsArray($vInsert) Then
                ; Get size of Insert array
                Local $vInsert_Max = UBound($vInsert)
                For $j = 0 To $iDim2 - 1
                    ; If Insert array is too small to fill Array then continue with blanks
                    If $j > $vInsert_Max - 1 Then
                        $avArray[$iIndex][$j] = ""
                    Else
                        $avArray[$iIndex][$j] = $vInsert[$j]
                    EndIf
                Next
            Else
                ; Fill Array with variable
                For $j = 0 To $iDim2 - 1
                    $avArray[$iIndex][$j] = $vInsert
                Next
            EndIf

    EndSwitch

    Return $iIndex_Max + 1

EndFunc   ;==>_GUIListViewEx_Array_Insert

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Delete
; Description ...: Deletes a specified index from an existing 1D or 2D array.
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================

Func _GUIListViewEx_Array_Delete(ByRef $avArray, $iIndex)

    ; Get size of the Array to modify
    Local $iIndex_Max = UBound($avArray)

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1

            ; Move up all elements below the new index
            For $i = $iIndex To $iIndex_Max - 2
                $avArray[$i] = $avArray[$i + 1]
            Next

            ; Redim the Array
            ReDim $avArray[$iIndex_Max - 1]

        Case 2

            ; Get size of second dimension
            Local $iDim2 = UBound($avArray, 2)

            ; Move up all elements below the new index
            For $i = $iIndex To $iIndex_Max - 2
                For $j = 0 To $iDim2 - 1
                    $avArray[$i][$j] = $avArray[$i + 1][$j]
                Next
            Next

            ; Redim the Array
            ReDim $avArray[$iIndex_Max - 1][$iDim2]

    EndSwitch

    Return $iIndex_Max - 1

EndFunc   ;==>_GUIListViewEx_Array_Delete

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Swap
; Description ...: Swaps specified elements within a 1D or 2D array
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================

Func _GUIListViewEx_Array_Swap(ByRef $avArray, $iIndex1, $iIndex2)

    Local $vTemp

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1
            ; Swap the elements via a temp variable
            $vTemp = $avArray[$iIndex1]
            $avArray[$iIndex1] = $avArray[$iIndex2]
            $avArray[$iIndex2] = $vTemp

        Case 2

            ; Get size of second dimension
            Local $iDim2 = UBound($avArray, 2)
            ; Swap the elements via a temp variable
            For $i = 0 To $iDim2 - 1
                $vTemp = $avArray[$iIndex1][$i]
                $avArray[$iIndex1][$i] = $avArray[$iIndex2][$i]
                $avArray[$iIndex2][$i] = $vTemp
            Next
    EndSwitch

    Return 0

EndFunc   ;==>_GUIListViewEx_Array_Swap

Now to work on the UDF to get the "editing" part of your script to function correctly. You seem to like making me work! :D

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

  • Moderators
Posted

johnmcloud,

Testing time again! :D

Here is your much slimmer script: ;)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiListView.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>

#include "GUIListViewEx_Mod.au3"

Global $Number = 0, $hMenu
Global Enum $idMoveUp = 1000, $idMoveDown, $idDelete
Global $Style = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)

$hGUI = GUICreate("_GUICtrlListView_Example", 262, 351, -1, -1)
$cListview = GUICtrlCreateListView("N°|Test|Test2", 5, 5, 250, 272, $LVS_REPORT)
$hListview = GUICtrlGetHandle($cListview)
_GUICtrlListView_SetExtendedListViewStyle($hListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_BORDERSELECT))
_GUICtrlListView_SetColumnWidth($hListview, 0, 35)
_GUICtrlListView_SetColumnWidth($hListview, 1, 107)
_GUICtrlListView_SetColumnWidth($hListview, 2, 108)

$iLV_Index = _GUIListViewEx_Init($hListview, "", 0, 0, 3) ; The final parameter = "Sort & Edit" <<<<<<<<<<<<<<<<<<<<<<

$Label = GUICtrlCreateLabel("Name", 13, 290, 67, 17)
$c_Button_Add = GUICtrlCreateButton("Add", 90, 315, 80, 25)
$Info = GUICtrlCreateInput("Value", 88, 286, 83, 21)
$c_Button_Save = GUICtrlCreateButton("Save", 174, 284, 80, 25)

$hMenu = _GUICtrlMenu_CreatePopup()
_GUICtrlMenu_InsertMenuItem($hMenu, 0, "Move Up", $idMoveUp)
_GUICtrlMenu_InsertMenuItem($hMenu, 1, "Move Down", $idMoveDown)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "Delete", $idDelete)

$c_Dummy_Down = GUICtrlCreateDummy()
$c_Dummy_Up = GUICtrlCreateDummy()
$c_Dummy_Delete = GUICtrlCreateDummy()

Local $AccelKeys[3][2] = [["{DELETE}", $c_Dummy_Delete],["{UP}", $c_Dummy_Up],["{DOWN}", $c_Dummy_Down]]
GUISetAccelerators($AccelKeys, $hGUI)

Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hListview)]

GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $c_Button_Add
            Add_Item()
        Case $c_Button_Save
            Save_List()
        Case $c_Dummy_Delete
            Delete_Item()
        Case $c_Dummy_Down
            Move_Down()
        Case $c_Dummy_Up
            Move_Up()
    EndSwitch

    _GUIListViewEx_EditAction("1;2") ; This is the new function allowing you to edit columns 1 and 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<

WEnd

Func Add_Item()
    $Number += 1
    $vData = $Number & "|" & GUICtrlRead($Label) & "|" & GUICtrlRead($Info)
    _GUIListViewEx_Insert($vData)
EndFunc   ;==>Add_Item

Func Delete_Item()
    _GUIListViewEx_Delete()
EndFunc   ;==>Delete_Item

Func Save_List()
    Local $Save = FileSaveDialog("Save", @WorkingDir, "Txt Files (*.txt)", 2, "Test_File_" & @MDAY & "-" & @MON & "-" & @YEAR & "_" & @HOUR & "-" & @MIN)
    If @error Then
        ConsoleWrite("Abort")
    Else
        $List = FileOpen($Save & ".txt", 2)
        $Number_items = _GUICtrlListView_GetItemCount($hListview)
        For $i = 0 To $Number_items - 1 Step +1
            $output = StringReplace(_GUICtrlListView_GetItemTextString($hListview, $i), "|", " - ")
            FileWriteLine($List, $output)
        Next
        FileClose($List)
    EndIf
EndFunc   ;==>Save_List

Func Move_Up()
    _GUIListViewEx_Up()
EndFunc   ;==>Move_Up

Func Move_Down()
    _GUIListViewEx_Down()
EndFunc   ;==>Move_Down

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)

    _GUIListViewEx_WM_NOTIFY_Handler($hWnd, $iMsg, $iwParam, $ilParam) ; The UDF does everything else in here <<<<<<<<<<<<<<<<<<<

    Local $tNMHDR, $hWndFrom, $iCode
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListview
            Switch $iCode
                Case $NM_RCLICK
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    If DllStructGetData($tInfo, "Item") > -1 Then
                        _GUICtrlMenu_TrackPopupMenu($hMenu, $hGUI)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Switch $wParam
        Case $idMoveUp
            Move_Up()
        Case $idMoveDown
            Move_Down()
        Case $idDelete
            Delete_Item()
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

And here is a beta UDF to test it with - again save it as GUIListViewEx_Mod.au3:

#include-once

; #INDEX# ============================================================================================================
; Title .........: GUIListViewEx
; AutoIt Version : 3.3 +
; Language ......: English
; Description ...: Permits insertion, deletion, moving, dragging and sorting of items within activated ListViews
; Remarks .......: - It is important to use _GUIListViewEx_Close when a enabled ListView is deleted to free the memory used
;                    by the $aGLVEx_Data array which shadows the ListView contents.
;                  - If the script already has WM_NOTIFY, WM_MOUSEMOVE or WM_LBUTTONUP handlers then only set the
;                    unregistered messages in _GUIListViewEx_DragRegister and call the relevant _GUIListViewEx_WM_#####_Handler
;                    from within the existing handler
;                  - Uses 2 undocumented function within GUIListView UDF to set and colour insert mark (thanks rover)
;                  - If ListView is editable, Opt("GUICloseOnESC") set to 0 as ESC = edit cancel.  Do not reset Opt in script
; Author ........: Melba23 - credit to martin (basic drag code), Array.au3 authors (original array functions)
; Modified ......;
; ====================================================================================================================

;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

; #INCLUDES# =========================================================================================================
#include <GuiListView.au3>
#include <GUIImageList.au3>

; #GLOBAL VARIABLES# =================================================================================================
; Array to hold registered ListView data
Global $aGLVEx_Data[1][8] = [[0, 0]]
; [0][0] = Count            [n][0] = ListView handle
; [0][1] = Active Index        [n][1] = Native ListView ControlID / 0
;                             [n][2] = Content array
;                             [n][3] = [0] element is count
;                           [n][4] = Sorting array
;                           [n][5] = Drag image
;                             [n][6] = Checkbox array
;                           [n][7] = Editable
; Variables for all UDF functions
Global $hGLVEx_Handle, $hGLVEx_CID, $aGLVEx_Array
; Variables for UDF dragging handlers
Global $iGLVEx_Dragging = 0, $iGLVExDragged_Index, $hGLVExDragged_Image = 0, $iGLVExInsert_Index = -1, $iGLVExLast_Y
Global $fGLVEx_Bar_Under, $fGLVEx_MultipleDrag, $aGLVExDragCheck_Array
; Variables for UDF edit
Global $cGLVEx_EditCID = 0, $fGLVEx_EditFlag = False

; #CURRENT# ==========================================================================================================
; _GUIListViewEx_Init:                 Enables UDF button functions for the ListView and sets insert mark colour
; _GUIListViewEx_Close:                Disables all UDF functions for the specified ListView and clears all memory used
; _GUIListViewEx_SetActive:            Set specified ListView as active for UDF functions
; _GUIListViewEx_GetActive:            Get index number of ListView active for UDF functions
; _GUIListViewEx_Return_Array:         Returns an array reflecting the current state of the ListView
; _GUIListViewEx_Insert:               Inserts data just below selected item in active ListView
; _GUIListViewEx_Delete:               Deletes selected item in active ListView
; _GUIListViewEx_Up:                   Moves selected item in active ListView up 1 place
; _GUIListViewEx_Down:                 Moves selected item in active ListView down 1 place
; _GUIListViewEx_EditAction:           Allows editing of ListView items
; _GUIListViewEx_DragRegister:         Registers Windows messages to enable item dragging for listed ListViews
; _GUIListViewEx_WM_NOTIFY_Handler:    Windows message handler for WM_NOTIFY
; _GUIListViewEx_WM_MOUSEMOVE_Handler: Windows message handler for WM_MOUSEMOVE
; _GUIListViewEx_WM_LBUTTONUP_Handler: Windows message handler for WM_LBUTTONUP
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _GUIListViewEx_HighLight:    Highlights specified ListView item and ensures it is visible
; _GUIListViewEx_Data_Change:  Resets ListView items within a defined range to the current values in the stored array
; _GUIListViewEx_Array_Add:    Adds a specified value at the end of an array
; _GUIListViewEx_Array_Insert: Adds a value at the specified index of an array
; _GUIListViewEx_Array_Delete: Deletes a specified index from an array
; _GUIListViewEx_Array_Swap:   Swaps specified elements within an array
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Init
; Description ...: Enables UDF button functions for the ListView and sets insert mark colour for drag function
; Syntax.........: _GUIListViewEx_Init($hLV, [$aArray = "", [$iStart = 0, [$iColour, [$iAdded, $fImage]]]]])
; Parameters ....: $hLV     - Handle or ControlID of ListView
;                  $a Array - Name of array used to fill ListView.  "" = empty ListView
;                  $iStart  - 0 (default) = ListView data starts in [0] element of array, 1 = Count in [0] element
;                  $iColour - RGB colour for insert mark (default = black)
;                  $iAdded  - 0   - No added features (default).  To get added fatures add the following
;                             + 1 - Sortable by clickign on column headers
;                             + 2 - Editable by double clicking on a subitem
;                  $fImage  - True = Shadow image of dragged item when dragging
; Requirement(s).: v3.3 +
; Return values .: Index number of ListView for use in other GUIListViewEx functions
; Author ........: Melba23
; Modified ......:
; Remarks .......: - If the ListView is the only one enabled, it is automatically set as active
;                  - If no array is passed a shadow array is created automatically - if the ListView has more than
;                  1 column this array is 2D with the second dimension set to the number of columns
;                  - The shadow array has a count in element [0] added if it does not exist. However, if the $iStart
;                  parameter is set to 0 this count element will not be returned by other GUIListViewEx functions
;                  - Only first item of a multiple selection is shadow imaged when dragging (API limitation)
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Init($hLV, $aArray = "", $iStart = 0, $iColour = 0, $iAdded = 0, $fImage = False)

    Local $iIndex = 0

    ; See if there is a blank line available in the array
    For $i = 1 To $aGLVEx_Data[0][0]
        If $aGLVEx_Data[$i][0] = 0 Then
            $iIndex = $i
            ExitLoop
        EndIf
    Next
    ; If no blank line found then increase array size
    If $iIndex = 0 Then
        $aGLVEx_Data[0][0] += 1
        ReDim $aGLVEx_Data[$aGLVEx_Data[0][0] + 1][8]
        $iIndex = $aGLVEx_Data[0][0]
    EndIf

    ; Store ListView handle and ControlID
    If IsHWnd($hLV) Then
        $aGLVEx_Data[$iIndex][0] = $hLV
        $aGLVEx_Data[$iIndex][1] = 0
    Else
        $aGLVEx_Data[$iIndex][0] = GUICtrlGetHandle($hLV)
        $aGLVEx_Data[$iIndex][1] = $hLV
    EndIf

    ; Create a shadow array if needed
    If $aArray = "" Then
        Local $iCols = _GUICtrlListView_GetColumnCount($aGLVEx_Data[$iIndex][0])
        Switch $iCols
            Case 1
                Local $aReplacement[1] = [0]
            Case Else
                Local $aReplacement[1][$iCols] = [[0]]
        EndSwitch
        $aArray = $aReplacement
    Else
        ; Add count element to shadow array if required
        If $iStart = 0 Then _GUIListViewEx_Array_Insert($aArray, 0, UBound($aArray))
    EndIf
    ; Store array
    $aGLVEx_Data[$iIndex][2] = $aArray

    ; Store [0] = count data
    $aGLVEx_Data[$iIndex][3] = $iStart
    ; If sortable, store sort array
    If BitAnd($iAdded, 1) Then
        Local $aLVSortState[_GUICtrlListView_GetColumnCount($hLV)]
        $aGLVEx_Data[$iIndex][4] = $aLVSortState
    Else
        $aGLVEx_Data[$iIndex][4] = 0
    EndIf
    ; If editable
    If BitAnd($iAdded, 2) Then
        $aGLVEx_Data[$iIndex][7] = 1
        ; Limit ESC to edit cancel
        Opt("GUICloseOnESC", 0)
    Else
        $aGLVEx_Data[$iIndex][7] = 0
    EndIf
    ; If image required
    If $fImage Then
        $aGLVEx_Data[$iIndex][5] = 1
    EndIf
    ;  If checkbox extended style
    If BitAnd(_GUICtrlListView_GetExtendedListViewStyle($hLV), 4) Then ; $LVS_EX_CHECKBOXES
        $aGLVEx_Data[$iIndex][6] = 1
    EndIf

    ; Set insert mark colour after conversion to BGR
    _GUICtrlListView_SetInsertMarkColor($hLV, BitOR(BitShift(BitAND($iColour, 0x000000FF), -16), BitAND($iColour, 0x0000FF00), BitShift(BitAND($iColour, 0x00FF0000), 16)))

    ; If only 1 current ListView then activate
    Local $iListView_Count = 0
    For $i = 1 To $iIndex
        If $aGLVEx_Data[$i][0] Then $iListView_Count += 1
    Next
    If $iListView_Count = 1 Then _GUIListViewEx_SetActive($iIndex)

    ; Return ListView index
    Return $iIndex

EndFunc   ;==>_GUIListViewEx_Init

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Close
; Description ...: Disables all UDF functions for the specified ListView and clears all memory used
; Syntax.........: _GUIListViewEx_Close($iIndex)
; Parameters ....: $iIndex - Index number of ListView to close as returned by _GUIListViewEx_Init
;                            0 (default) = Closes all ListViews
; Requirement(s).: v3.3 +
; Return values .: Success: 1
;                  Failure: 0 and @error set to 1 - Invalid index number
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Close($iIndex = 0)

    ; Check valid index
    If $iIndex < 0 Or $iIndex > $aGLVEx_Data[0][0] Then Return SetError(1, 0, 0)

    If $iIndex = 0 Then
        ; Remove all ListView data
        Global $aGLVEx_Data[1][8] = [[0, 0]]
    Else
        ; Reset all data for ListView
        For $i = 0 To 6
            $aGLVEx_Data[$iIndex][$i] = 0
        Next

        ; Cancel active index if set to this ListView
        If $aGLVEx_Data[0][1] = $iIndex Then $aGLVEx_Data[0][1] = 0
    EndIf

    Return 1

EndFunc   ;==>_GUIListViewEx_Close

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_SetActive
; Description ...: Set specified ListView as active for UDF functions
; Syntax.........: _GUIListViewEx_SetActive($iIndex)
; Parameters ....: $iIndex - Index number of ListView as returned by _GUIListViewEx_Init
;                  An index of 0 clears any current setting
; Requirement(s).: v3.3 +
; Return values .: Success: Returns previous active index number, 0 = no previously active ListView
;                  Failure: -1 and @error set to 1 - Invalid index number
; Author ........: Melba23
; Modified ......:
; Remarks .......: ListViews can also be activated by clicking on them
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_SetActive($iIndex)

    ; Check valid index
    If $iIndex < 0 Or $iIndex > $aGLVEx_Data[0][0] Then Return SetError(1, 0, -1)

    Local $iCurr_Index = $aGLVEx_Data[0][1]

    If $iIndex Then
        ; Store index of specified ListView
        $aGLVEx_Data[0][1] = $iIndex
        ; Set values for specified ListView
        $hGLVEx_Handle = $aGLVEx_Data[$iIndex][0]
        $hGLVEx_CID = $aGLVEx_Data[$iIndex][1]
    Else
        ; Clear active index
        $aGLVEx_Data[0][1] = 0
    EndIf

    Return $iCurr_Index

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_GetActive
; Description ...: Get index number of ListView active for UDF functions
; Syntax.........: _GUIListViewEx_GetActive()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Index number as returned by _GUIListViewEx_Init, 0 = no active ListView
; Author ........: Melba23
; Modified ......:
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_GetActive()

    Return $aGLVEx_Data[0][1]

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Return_Array
; Description ...: Returns an array reflecting the current state of the ListView
; Syntax.........: _GUIListViewEx_Return_Array($iIndex)
; Parameters ....: $iIndex - Index number of ListView as returned by _GUIListViewEx_Init
;                  $iCheck - If non-zero then the state of the checkboxes is returned (Default = 0)
; Requirement(s).: v3.3 +
; Return values .: Success: Array of current ListView - presence of count in [0] element determined by _GUIListViewEx_Init
;                  Failure: Empty array returns null string and sets @error as follows:
;                           1 = Invalid index number
;                           2 = Empty array (no items in ListView)
;                           3 = $iCheck set to True but ListView does not have checkbox style
; Author ........: Melba23
; Modified ......:
; Remarks .......: The $iStart parameter from GUIListViewEx_Init determines whether the [0] element is a count
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Return_Array($iIndex, $iCheck = 0)

    ; Check valid index
    If $iIndex < 1 Or $iIndex > $aGLVEx_Data[0][0] Then Return SetError(1, 0, "")

    ; Copy current array
    Local $aRetArray = $aGLVEx_Data[$iIndex][2]

    ; Check if checkbox array
    If $iCheck Then
        If $aGLVEx_Data[$iIndex][6] Then
            Local $aCheck_Array[UBound($aRetArray)]
            For $i = 1 To UBound($aRetArray) - 1
                $aCheck_Array[$i] = _GUICtrlListView_GetItemChecked($aGLVEx_Data[$iIndex][0], $i - 1)
            Next
            ; Remove count element if required
            If $aGLVEx_Data[$iIndex][3] = 0 Then
                ; Check at least one entry in 1D/2D array
                Switch UBound($aRetArray, 0)
                    Case 1
                        If $aRetArray[0] = 0 Then Return SetError(2, 0, "")
                    Case 2
                        If $aRetArray[0][0] = 0 Then Return SetError(2, 0, "")
                EndSwitch
                ; Delete count element
                _GUIListViewEx_Array_Delete($aCheck_Array, 0)
            EndIf
            Return $aCheck_Array
        Else
            Return SetError(3, 0, "")
        EndIf
    EndIf

    ; Remove count element of array if required
    If $aGLVEx_Data[$iIndex][3] = 0 Then
        ; Check at least one entry in 1D/2D array
        Switch UBound($aRetArray, 0)
            Case 1
                If $aRetArray[0] = 0 Then Return SetError(2, 0, "")
            Case 2
                If $aRetArray[0][0] = 0 Then Return SetError(2, 0, "")
        EndSwitch
        ; Delete count element
        _GUIListViewEx_Array_Delete($aRetArray, 0)
    EndIf

    ; Return array
    Return $aRetArray

EndFunc   ;==>_GUIListViewEx_Return_Array

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Insert
; Description ...: Inserts data just below selected item in active ListView
;                  If no selection, data added at end
; Syntax.........: _GUIListViewEx_Insert($vData)
; Parameters ....: $vData - Data to insert, can be in array or delimited string format
; Requirement(s).: v3.3 +
; Return values .: Success: Array of current ListView with count in [0] element
;                  Failure: If no ListView active then returns "" and sets @error to 1
; Author ........: Melba23
; Modified ......:
; Remarks .......: - New data is inserted after the selected item.  If no item is selected then the datat is added at
;                  the end of the ListView.  If multiple items are selected, the data is inserted after the first
;                  - $vData can be passed in string or array format - it is automatically transformed if required
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Insert($vData)

    Local $vInsert

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, "")

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Get selected item in ListView
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    Local $iInsert_Index = $iIndex
    ; If no selection
    If $iIndex = "" Then $iInsert_Index = -1
    ; Check for multiple selections
    If StringInStr($iIndex, "|") Then
        Local $aIndex = StringSplit($iIndex, "|")
        ; Use first selection
        $iIndex = $aIndex[1]
        ; Cancel all other selections
        For $i = 2 To $aIndex[0]
            _GUICtrlListView_SetItemSelected($hGLVEx_Handle, $aIndex[$i], False)
        Next
    EndIf

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Create Local array for checkboxes if required
    If $aGLVEx_Data[$iArray_Index][6] Then
        Local $aCheck_Array[UBound($aGLVEx_Array)]
        For $i = 1 To UBound($aCheck_Array) - 1
            $aCheck_Array[$i] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $i - 1)
        Next
    EndIf

    ; Check if 1D/2D array
    Switch UBound($aGLVEx_Array, 0)
        Case 1
            ; If empty array insert at 0
            If $aGLVEx_Array[0] = 0 Then $iInsert_Index = 0
            ; Get data into string format for insert
            If IsArray($vData) Then
                $vInsert = ""
                For $i = 0 To UBound($vData) - 1
                    $vInsert &= $vData[$i] & "|"
                Next
                $vInsert = StringTrimRight($vInsert, 1)
            Else
                $vInsert = $vData
            EndIf
            ; Increase count
            $aGLVEx_Array[0] += 1
        Case 2
            ; If empty array insert at 0
            If $aGLVEx_Array[0][0] = 0 Then $iInsert_Index = 0
            ; Get data into array format for insert
            If IsArray($vData) Then
                $vInsert = $vData
            Else
                Local $aData = StringSplit($vData, "|")
                Switch $aData[0]
                    Case 1
                        $vInsert = $aData[1]
                    Case Else
                        Local $vInsert[$aData[0]]
                        For $i = 0 To $aData[0] - 1
                            $vInsert[$i] = $aData[$i + 1]
                        Next
                EndSwitch
            EndIf
            ; Increase count
            $aGLVEx_Array[0][0] += 1
    EndSwitch

    ; Insert data into array
    If $iIndex = "" Then
        _GUIListViewEx_Array_Add($aGLVEx_Array, $vInsert)
    Else
        _GUIListViewEx_Array_Insert($aGLVEx_Array, $iInsert_Index + 2, $vInsert)
        If $aGLVEx_Data[$iArray_Index][6] Then
            _GUIListViewEx_Array_Insert($aCheck_Array, $iInsert_Index + 2, False)
            ; Reset all checkboxes
            For $i = 1 To UBound($aCheck_Array) - 1
                _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $i - 1, $aCheck_Array[$i])
            Next
        EndIf
    EndIf

    ; Check if Native or UDF
    If $hGLVEx_CID Then
        ; Add new item at ListView end
        If IsArray($vInsert) Then
            If IsArray($vData) Then
                $vInsert = ""
                For $i = 0 To UBound($vData) - 1
                    $vInsert &= $vData[$i] & "|"
                Next
                $vInsert = StringTrimRight($vInsert, 1)
                GUICtrlCreateListViewItem($vInsert, $hGLVEx_CID)
            Else
                GUICtrlCreateListViewItem($vData, $hGLVEx_CID)
            EndIf
        Else
            GUICtrlCreateListViewItem($vInsert, $hGLVEx_CID)
        EndIf
    Else
        ; Add new item at ListView end
        Local $iNewItem
        If IsArray($vInsert) Then
            $iNewItem = _GUICtrlListView_AddItem($hGLVEx_Handle, $vInsert[0])
            ; Add new subitems
            For $i = 1 To UBound($vInsert) - 1
                _GUICtrlListView_AddSubItem($hGLVEx_Handle, $iNewItem, $vInsert[$i], $i)
            Next
        Else
            $iNewItem = _GUICtrlListView_AddItem($hGLVEx_Handle, $vInsert)
        EndIf
    EndIf
    ; Check where item was to be inserted
    If $iIndex = "" Then
        _GUIListViewEx_Data_Change($iInsert_Index, $iInsert_Index)
        ; No moves required so set highlight
        _GUIListViewEx_Highlight(_GUICtrlListView_GetItemCount($hGLVEx_Handle) - 1)
    Else
        ; Reset item contents below insert position
        _GUIListViewEx_Data_Change($iInsert_Index, _GUICtrlListView_GetItemCount($hGLVEx_Handle) - 1)
        ; Set highlight
        _GUIListViewEx_Highlight($iInsert_Index + 1, $iInsert_Index)
    EndIf

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Insert

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Delete
; Description ...: Deletes selected item in active ListView
; Syntax.........: _GUIListViewEx_Delete()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Array of active ListView with count in [0] element
;                  Failure: Returns "" and sets @error as follows:
;                      1 = No ListView active
;                      2 = No item selected
;                      3 = No items to delete
; Author ........: Melba23
; Modified ......:
; Remarks .......: If multiple items are selected, all are deleted
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Delete()

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, "")

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Check for selected items
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    If $iIndex = "" Then Return SetError(2, 0, "")

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Determine final item
    Local $iLast = UBound($aGLVEx_Array) - 2

    ; Check if item is part of a multiple selection
    If StringInStr($iIndex, "|") Then
        ; Extract all selected items
        Local $aIndex = StringSplit($iIndex, "|")
        For $i = 1 To $aIndex[0]
            ; Remove highlighting from items
            _GUICtrlListView_SetItemSelected($hGLVEx_Handle, $i, False)
        Next

        ; Check if 1D/2D array
        Switch UBound($aGLVEx_Array, 0)
            Case 1
                ; Decrease count
                $aGLVEx_Array[0] -= $aIndex[0]
            Case 2
                ; Decrease count
                $aGLVEx_Array[0][0] -= $aIndex[0]
        EndSwitch

        ; Delete elements from array - start from bottom
        For $i = $aIndex[0] To 1 Step -1
            _GUIListViewEx_Array_Delete($aGLVEx_Array, $aIndex[$i] + 1)
        Next

        ; Delete items from ListView - again start from bottom
        For $i = $aIndex[0] To 1 Step -1
            _GUICtrlListView_DeleteItem($hGLVEx_Handle, $aIndex[$i])
        Next

    Else
        ; Check if 1D/2D array
        Switch UBound($aGLVEx_Array, 0)
            Case 1
                ; Decrease count
                $aGLVEx_Array[0] -= 1
            Case 2
                ; Decrease count
                $aGLVEx_Array[0][0] -= 1
        EndSwitch
        ; Delete element from array
        _GUIListViewEx_Array_Delete($aGLVEx_Array, $iIndex + 1)

        ; Delete item from ListView
        _GUICtrlListView_DeleteItem($hGLVEx_Handle, $iIndex)
        ; Set highlight - up one if bottom deleted
        If $iIndex = $iLast Then
            _GUIListViewEx_Highlight($iIndex - 1)
        Else
            _GUIListViewEx_Highlight($iIndex)
        EndIf
    EndIf

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Delete

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Up
; Description ...: Moves selected item in active ListView up 1 place
; Syntax.........: _GUIListViewEx_Up()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Array of active ListView with count in [0] element
;                  Failure: Returns "" and sets @error as follows:
;                      1 = No ListView active
;                      2 = No item selected
;                      3 = Item already at top
; Author ........: Melba23
; Modified ......:
; Remarks .......: If multiple items are selected, only the top consecutive block is moved
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Up()

    Local $iGLVExMove_Index, $iGLVEx_Moving = 0

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, 0)

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Check for selected items
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    Local $aIndex = StringSplit($iIndex, "|")
    $iGLVExMove_Index = $aIndex[1]
    ; Check if item is part of a multiple selection
    If $aIndex[0] > 1 Then
        ; Check for consecutive items
        For $i = 1 To $aIndex[0] - 1
            If $aIndex[$i + 1] = $aIndex[1] + $i Then
                $iGLVEx_Moving += 1
            Else
                ExitLoop
            EndIf
        Next
    Else
        $iGLVExMove_Index = $aIndex[1]
    EndIf

    ; Remove all highlighting
    _GUICtrlListView_SetItemSelected($hGLVEx_Handle, -1, False)

    ; Check not top item
    If $iGLVExMove_Index = "0" Then Return SetError(3, 0, "")

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Move consecutive items
    For $iIndex = $iGLVExMove_Index To $iGLVExMove_Index + $iGLVEx_Moving

        ; Swap array elements
        _GUIListViewEx_Array_Swap($aGLVEx_Array, $iIndex, $iIndex + 1)

        ; Swap checkboxes if required
        If $aGLVEx_Data[$iArray_Index][6] Then
            Local $fTemp = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex)
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex, _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex - 1))
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex - 1, $fTemp)
        EndIf

        ; Change data in affected items
        _GUIListViewEx_Data_Change($iIndex - 1, $iIndex);, $aGLVEx_Array)
        ; Set highlight and cancel existing one (needed for multiple selection ListViews)
        _GUIListViewEx_Highlight($iIndex - 1, $iIndex)
    Next

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Up

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_Down
; Description ...: Moves selected item in active ListView down 1 place
; Syntax.........: _GUIListViewEx_Down()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Success: Array of active ListView with count in [0] element
;                  Failure: Returns "" and sets @error as follows:
;                      1 = No ListView active
;                      2 = No item selected
;                      3 = Item already at bottom
; Author ........: Melba23
; Modified ......:
; Remarks .......: If multiple items are selected, only the bottom consecutive block is moved
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_Down()

    Local $iGLVExMove_Index, $iGLVEx_Moving = 0

    ; Set data for active ListView
    Local $iArray_Index = $aGLVEx_Data[0][1]
    ; If no ListView active then return
    If $iArray_Index = 0 Then Return SetError(1, 0, 0)

    ; Load active ListView details
    $hGLVEx_Handle = $aGLVEx_Data[$iArray_Index][0]
    $hGLVEx_CID = $aGLVEx_Data[$iArray_Index][1]

    ; Check for selected items
    Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
    Local $aIndex = StringSplit($iIndex, "|")
    ; Check if item is part of a multiple selection
    If $aIndex[0] > 1 Then
        $iGLVExMove_Index = $aIndex[$aIndex[0]]
        ; Check for consecutive items
        For $i = 1 To $aIndex[0] - 1
            If $aIndex[$aIndex[0] - $i] = $aIndex[$aIndex[0]] - $i Then
                $iGLVEx_Moving += 1
            Else
                ExitLoop
            EndIf
        Next
    Else
        $iGLVExMove_Index = $aIndex[1]
    EndIf

    ; Remove all highlighting
    _GUICtrlListView_SetItemSelected($hGLVEx_Handle, -1, False)

    ; Check not last item
    If $iGLVExMove_Index = _GUICtrlListView_GetItemCount($hGLVEx_Handle) - 1 Then
        _GUIListViewEx_Highlight($iIndex)
        Return
    EndIf

    ; Copy array for manipulation
    $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]

    ; Move consecutive items
    For $iIndex = $iGLVExMove_Index To $iGLVExMove_Index - $iGLVEx_Moving Step -1

        ; Swap array elements
        _GUIListViewEx_Array_Swap($aGLVEx_Array, $iIndex + 1, $iIndex + 2)

        ; Swap checkboxes if required
        If $aGLVEx_Data[$iArray_Index][6] Then
            Local $fTemp = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex)
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex, _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iIndex + 1))
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $iIndex + 1, $fTemp)
        EndIf

        ; Change data in affected items
        _GUIListViewEx_Data_Change($iIndex, $iIndex + 1)
        ; Set highlight and cancel existing one (needed for multiple selection ListViews)
        _GUIListViewEx_Highlight($iIndex + 1, $iIndex)

    Next

    ; Store amended array
    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0
    ; Return amended array
    Return _GUIListViewEx_Return_Array($iArray_Index)

EndFunc   ;==>_GUIListViewEx_Down

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_EditAction
; Description ...: Allows editing of ListView items
; Syntax.........: _GUIListViewEx_EditAction([$sCols = "*"[, $iDelta_X = 0[, $iDelta_Y = 0]]])
; Parameters ....: $sCols    = Editable columns - "" = all (default).  Separate multiple columns with ;
;                  $iDelta_X = Fine adjustment of edit control in X axis
;                  $iDelta_Y = Fine adjustment of edit control in Y axis
; Requirement(s).: v3.3 +
; Return values .: Success: Edited array of active ListView
;                  Failure: Returns "" and sets @error as follows:
;                           1 - Edit cancelled
;                           2 - Column not editable
; Author ........: Melba23
; Modified ......:
; Remarks .......: This function must be called within the script idle loop. Once called, all other script activity
;                  suspended until edit is confimed {ENTER} or cancelled {ESCAPE}
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_EditAction($sCols = "", $iDelta_X = 0, $iDelta_Y = 0)

    ; If an item was double clicked
    If $fGLVEx_EditFlag Then
        ; Get handle of ListView parent
        Local $aResult = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", $hGLVEx_Handle)
        Local $hWnd = $aResult[0]
        ; Set data for active ListView
        Local $iArray_Index = $aGLVEx_Data[0][1]
        ; If no ListView active then return
        If $iArray_Index = 0 Then
            Return SetError(1, 0, "")
        EndIf
        ; Get clicked item info
        Local $aHit = _GUICtrlListView_SubItemHitTest($hGLVEx_Handle)
        ; Check if column is editable
        If $sCols Then
            If Not StringInStr(";" & $sCols, ";" & $aHit[1]) Then
                ; Clear flag
                $fGLVEx_EditFlag = False
                Return SetError(2, 0, "")
            EndIf
        EndIf
        ; Read current text of clicked item
        Local $sItemOrgText = _GUICtrlListView_GetItemText($hGLVEx_Handle, $aHit[0], $aHit[1])
        ; Get size of edit box
        Local $aRect = _GUICtrlListView_GetSubItemRect($hGLVEx_Handle, $aHit[0], $aHit[1])
        Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hGLVEx_Handle, $aHit[1]) - 7
        Local $iEdit_Height = $aRect[3] - $aRect[1]
        ; Get position of ListView within GUI client area
        Local $aPos = WinGetPos($hGLVEx_Handle)
        Local $tPoint = DllStructCreate("int X;int Y")
        DllStructSetData($tPoint, "X", $aPos[0])
        DllStructSetData($tPoint, "Y", $aPos[1])
        _WinAPI_ScreenToClient($hWnd, $tPoint)
        Local $iEdit_X = DllStructGetData($tPoint, "X") + $aRect[0] + 5 + $iDelta_X
        Local $iEdit_Y = DllStructGetData($tPoint, "Y") + $aRect[1] + 2 + $iDelta_Y
        ; Prevent ListView header resize
        ControlDisable($hWnd, "", HWnd(_GUICtrlListView_GetHeader($hGLVEx_Handle)))
        ; Create temporary edit - set keyboard focus and select all text
        $cGLVEx_EditCID = GUICtrlCreateEdit($sItemOrgText, $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, 0)
        GUICtrlSetState($cGLVEx_EditCID, 256) ; $GUI_FOCUS
        GUICtrlSendMsg($cGLVEx_EditCID, 0xB1, 0, -1) ; $EM_SETSEL
        ; Copy array for manipulation
        $aGLVEx_Array = $aGLVEx_Data[$iArray_Index][2]
        ; Return index flag
        Local $iReturnIndex = -1
        ; Wait for edit to end
        While $fGLVEx_EditFlag
            ; If ENTER pressed
            If _WinAPI_GetAsyncKeyState(0x0D) Then
                ; Set label to edit content
                Local $sItemNewText = GUICtrlRead($cGLVEx_EditCID)
                ; Check edit took place
                If $sItemNewText <> $sItemOrgText Then
                    ; Amend item text
                    _GUICtrlListView_SetItemText($hGLVEx_Handle, $aHit[0], $sItemNewText, $aHit[1])
                    ; Amend array element
                    $aGLVEx_Array[$aHit[0] + 1][$aHit[1]] = $sItemNewText
                    ; Store amended array
                    $aGLVEx_Data[$iArray_Index][2] = $aGLVEx_Array
                    ; Set array to return
                    $iReturnIndex = $iArray_Index
                EndIf
                ExitLoop
            EndIf
            ; If ESC pressed
            If _WinAPI_GetAsyncKeyState(0x1B) Then
                ExitLoop
            EndIf
            ; Save CPU
            Sleep(10)
        WEnd
        ; Delete copied array
        $aGLVEx_Array = 0
        ; Delete temporary edit
        GUICtrlDelete($cGLVEx_EditCID)
        $cGLVEx_EditCID = 0
        ; Reenable ListView header resize
        ControlEnable($hWnd, "", HWnd(_GUICtrlListView_GetHeader($hGLVEx_Handle)))
        ; Clear flag
        $fGLVEx_EditFlag = False

        Return _GUIListViewEx_Return_Array($iReturnIndex)

    EndIf

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_DragRegister
; Description ...: Registers Windows messages needed for the UDF
; Syntax.........: _GUIListViewEx_DragRegister([$fNOTIFY = True, [$fMOUSEMOVE = True, [$fLBUTTONUP = True]]])
; Parameters ....: $fNOTIFY    - True = Register WM_NOTIFY message
;                  $fMOUSEMOVE - True = Register WM_MOUSEMOVE message
;                  $fLBUTTONUP - True = Register WM_LBUTTONUP message
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If other handlers already registered, then call the relevant handler function from within that handler
;                  If no dragging is required, only the WM_NOTIFY handler needs to be registered
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_DragRegister($fNOTIFY = True, $fMOUSEMOVE = True, $fLBUTTONUP = True)

    ; Register required messages
    If $fNOTIFY    Then GUIRegisterMsg(0x004E, "_GUIListViewEx_WM_NOTIFY_Handler")    ; $WM_NOTIFY
    If $fMOUSEMOVE Then GUIRegisterMsg(0x0200, "_GUIListViewEx_WM_MOUSEMOVE_Handler") ; $WM_MOUSEMOVE
    If $fLBUTTONUP Then GUIRegisterMsg(0x0202, "_GUIListViewEx_WM_LBUTTONUP_Handler") ; $WM_LBUTTONUP

EndFunc   ;==>_GUIListViewEx_DragRegister

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_WM_NOTIFY_Handler
; Description ...: Windows message handler for WM_NOTIFY
; Syntax.........: _GUIListViewEx_WM_NOTIFY_Handler
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If a WM_NOTIFY handler already registered, then call this function from within that handler
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_WM_NOTIFY_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam

    ; Struct = $tagNMHDR and "int Item;int SubItem" from $tagNMLISTVIEW
    Local $tStruct = DllStructCreate("hwnd;uint_ptr;int_ptr;int;int", $lParam)
    If @error Then Return

    ; Check if enabled ListView
    For $iLVIndex = 1 To $aGLVEx_Data[0][0]
        If DllStructGetData($tStruct, 1) = $aGLVEx_Data[$iLVIndex][0] Then
            ExitLoop
        EndIf
    Next
    If $iLVIndex > $aGLVEx_Data[0][0] Then Return ; Not enabled

    Local $iCode = BitAND(DllStructGetData($tStruct, 3), 0xFFFFFFFF)

    Switch $iCode
        Case $LVN_COLUMNCLICK, -2 ; $NM_CLICK

            ; Set values for active ListView
            $aGLVEx_Data[0][1] = $iLVIndex
            $hGLVEx_Handle = $aGLVEx_Data[$iLVIndex][0]
            $hGLVEx_CID = $aGLVEx_Data[$iLVIndex][1]
            ; Copy array for manipulation
            $aGLVEx_Array = $aGLVEx_Data[$iLVIndex][2]

            ; Sort if a column header was clicked and ListView is sortable
            If $iCode = $LVN_COLUMNCLICK And IsArray($aGLVEx_Data[$iLVIndex][4]) Then
                ; Load current ListView sort state array
                Local $aLVSortState = $aGLVEx_Data[$aGLVEx_Data[0][0]][4]
                ; Sort column - get column from from struct
                _GUICtrlListView_SimpleSort($hGLVEx_Handle, $aLVSortState, DllStructGetData($tStruct, 5))
                ; Store new ListView sort state array
                $aGLVEx_Data[$aGLVEx_Data[0][0]][4] = $aLVSortState
                ; Reread listview items into array
                Switch UBound($aGLVEx_Array, 0) ; Check array format
                    Case 1
                        For $j = 1 To $aGLVEx_Array[0]
                            $aGLVEx_Array[$j] = _GUICtrlListView_GetItemTextString($hGLVEx_Handle, $j - 1)
                        Next
                    Case 2
                        Local $iDim2 = UBound($aGLVEx_Array, 2) - 1
                        For $j = 1 To $aGLVEx_Array[0][0]
                            For $k = 0 To $iDim2
                                $aGLVEx_Array[$j][$k] = _GUICtrlListView_GetItemText($hGLVEx_Handle, $j - 1, $k)
                            Next
                        Next
                EndSwitch
                ; Store amended array
                $aGLVEx_Data[$iLVIndex][2] = $aGLVEx_Array
            EndIf

        Case $LVN_BEGINDRAG
            ; Set values for this ListView
            $aGLVEx_Data[0][1] = $iLVIndex
            $hGLVEx_Handle = $aGLVEx_Data[$iLVIndex][0]
            $hGLVEx_CID = $aGLVEx_Data[$iLVIndex][1]
            Local $fImage = $aGLVEx_Data[$iLVIndex][5]
            Local $fCheck = $aGLVEx_Data[$iLVIndex][6]
            ; Copy array for manipulation
            $aGLVEx_Array = $aGLVEx_Data[$iLVIndex][2]

            ; Check if Native or UDF and set focus
            If $hGLVEx_CID Then
                GUICtrlSetState($hGLVEx_CID, 256) ; $GUI_FOCUS
            Else
                _WinAPI_SetFocus($hGLVEx_Handle)
            EndIf

            ; Get dragged item index
            $iGLVExDragged_Index = DllStructGetData($tStruct, 4) ; Item
            ; Set dragged item count
            $iGLVEx_Dragging = 1

            ; Check for selected items
            Local $iIndex = _GUICtrlListView_GetSelectedIndices($hGLVEx_Handle)
            ; Check if item is part of a multiple selection
            If StringInStr($iIndex, $iGLVExDragged_Index) And StringInStr($iIndex, "|") Then
                ; Extract all selected items
                Local $aIndex = StringSplit($iIndex, "|")
                For $i = 1 To $aIndex[0]
                    If $aIndex[$i] = $iGLVExDragged_Index Then ExitLoop
                Next
                ; Now check for consecutive items
                If $i <> 1 Then ; Up
                    For $j = $i - 1 To 1 Step -1
                        ; Consecutive?
                        If $aIndex[$j] <> $aIndex[$j + 1] - 1 Then ExitLoop
                        ; Adjust dragged index to this item
                        $iGLVExDragged_Index -= 1
                        ; Increase number to drag
                        $iGLVEx_Dragging += 1
                    Next
                EndIf
                If $i <> $aIndex[0] Then ; Down
                    For $j = $i + 1 To $aIndex[0]
                        ; Consecutive
                        If $aIndex[$j] <> $aIndex[$j - 1] + 1 Then ExitLoop
                        ; Increase number to drag
                        $iGLVEx_Dragging += 1
                    Next
                EndIf
            Else ; Either no selection or only a single
                ; Set flag
                $iGLVEx_Dragging = 1
            EndIf

            ; Remove all highlighting
            _GUICtrlListView_SetItemSelected($hGLVEx_Handle, -1, False)

            ; Create drag image
            If $fImage Then
                Local $aImageData = _GUICtrlListView_CreateDragImage($hGLVEx_Handle, $iGLVExDragged_Index)
                $hGLVExDragged_Image = $aImageData[0]
                _GUIImageList_BeginDrag($hGLVExDragged_Image, 0, 0, 0)
            EndIf

            ; Create Global array for checkboxes if required
            If $fCheck Then
                Global $aGLVExDragCheck_Array[UBound($aGLVEx_Array)]
                For $i = 1 To UBound($aGLVExDragCheck_Array) - 1
                    $aGLVExDragCheck_Array[$i] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $i - 1)
                Next
            EndIf

        Case -3 ; $NM_DBLCLK
            ; Only used on UDF ListViews - so confirm no ControlID - and if editable
            If $aGLVEx_Data[$iLVIndex][1] = 0 And $aGLVEx_Data[$iLVIndex][7] = 1 Then
                ; Set values for active ListView
                $aGLVEx_Data[0][1] = $iLVIndex
                $hGLVEx_Handle = $aGLVEx_Data[$iLVIndex][0]
                ; Copy array for manipulation
                $aGLVEx_Array = $aGLVEx_Data[$iLVIndex][2]
                ; Set editing flag
                $fGLVEx_EditFlag = True
            EndIf

    EndSwitch

EndFunc   ;==>_GUIListViewEx_WM_NOTIFY_Handler

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_WM_MOUSEMOVE_Handler
; Description ...: Windows message handler for WM_NOTIFY
; Syntax.........: _GUIListViewEx_WM_MOUSEMOVE_Handler
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If a WM_MOUSEMOVE handler already registered, then call this function from within that handler
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_WM_MOUSEMOVE_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $iMsg, $wParam

    If Not $iGLVEx_Dragging Then Return "GUI_RUNDEFMSG"

    Local $aLV_Pos, $tLVHITTESTINFO, $iCurr_Index

    ; Get current mouse Y coord
    Local $iCurr_Y = BitShift($lParam, 16)

    ; Set insert mark to correct side of items depending on sense of movement when cursor within range
    If $iGLVExInsert_Index <> -1 Then
        If $iGLVExLast_Y = $iCurr_Y Then
            Return "GUI_RUNDEFMSG"
        ElseIf $iGLVExLast_Y > $iCurr_Y Then
            $fGLVEx_Bar_Under = False
            _GUICtrlListView_SetInsertMark($hGLVEx_Handle, $iGLVExInsert_Index, False)
        Else
            $fGLVEx_Bar_Under = True
            _GUICtrlListView_SetInsertMark($hGLVEx_Handle, $iGLVExInsert_Index, True)
        EndIf
    EndIf
    ; Store current Y coord
    $iGLVExLast_Y = $iCurr_Y

    ; Get ListView item under mouse - depends on ListView type
    If $hGLVEx_CID Then
        $aLV_Pos = ControlGetPos($hWnd, "", $hGLVEx_CID)
        $tLVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
        ; Force response even if off side of GUI - normal X coord = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
        DllStructSetData($tLVHITTESTINFO, 1, 1)
        DllStructSetData($tLVHITTESTINFO, 2, $iCurr_Y - $aLV_Pos[1])
        ; Get item under mouse
        $iCurr_Index = GUICtrlSendMsg($hGLVEx_CID, $LVM_HITTEST, 0, DllStructGetPtr($tLVHITTESTINFO))
    Else
        ; Get coords of client area
        Local $tPoint = DllStructCreate("int X;int Y")
        DllStructSetData($tPoint, "X", 0)
        DllStructSetData($tPoint, "Y", 0)
        Local $pPoint = DllStructGetPtr($tPoint)
        DllCall("user32.dll", "bool", "ClientToScreen", "hwnd", $hWnd, "ptr", $pPoint)
        ; Get coords of ListView
        $aLV_Pos = WinGetPos($hGLVEx_Handle)
        Local $iY = $iCurr_Y - $aLV_Pos[1] + DllStructGetData($tPoint, "Y")
        $tLVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
        ; Force response even if off side of GUI - normal X coord = BitAND($lParam, 0xFFFF) - $aLV_Pos[0] + DllStructGetData($tPoint, "X")
        DllStructSetData($tLVHITTESTINFO, 1, 1)
        DllStructSetData($tLVHITTESTINFO, 2, $iY)
        Local $pLVHITTESTINFO = DllStructGetPtr($tLVHITTESTINFO)
        ; Get item under mouse
        Local $aRet = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hGLVEx_Handle, "uint", $LVM_HITTEST, "wparam", 0, "lparam", $pLVHITTESTINFO)
        $iCurr_Index = $aRet[0]
    EndIf

    ; If mouse is above or below ListView then scroll ListView
    If $iCurr_Index = -1 Then
        If $fGLVEx_Bar_Under Then
            _GUICtrlListView_Scroll($hGLVEx_Handle, 0, 10)
        Else
            _GUICtrlListView_Scroll($hGLVEx_Handle, 0, -10)
        EndIf
        Sleep(100)
    EndIf

    ; Check if over same item
    If $iGLVExInsert_Index = $iCurr_Index Then Return "GUI_RUNDEFMSG"

    ; Show insert mark on current item
    _GUICtrlListView_SetInsertMark($hGLVEx_Handle, $iCurr_Index, $fGLVEx_Bar_Under)
    ; Store current item
    $iGLVExInsert_Index = $iCurr_Index

EndFunc   ;==>_GUIListViewEx_WM_MOUSEMOVE_Handler

; #FUNCTION# =========================================================================================================
; Name...........: _GUIListViewEx_WM_LBUTTONUP_Handler
; Description ...: Windows message handler for WM_NOTIFY
; Syntax.........: _GUIListViewEx_WM_LBUTTONUP_Handler
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Modified ......:
; Remarks .......: If a WM_LBUTTONUP handler already registered, then call this function from within that handler
; Example........: Yes
;=====================================================================================================================
Func _GUIListViewEx_WM_LBUTTONUP_Handler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam, $lParam

    If Not $iGLVEx_Dragging Then Return "GUI_RUNDEFMSG"

    ; Get item count
    Local $iMultipleItems = $iGLVEx_Dragging - 1

    ; Reset flag
    $iGLVEx_Dragging = 0

    ; Check mouse within ListView
    If $iGLVExInsert_Index = -1 Then
        ; Clear insert mark
        _GUICtrlListView_SetInsertMark($hGLVEx_Handle, -1, True)
        ; Reset highlight to original items
        For $i = 0 To $iMultipleItems
            _GUIListViewEx_HighLight($iGLVExDragged_Index + $i)
        Next
        Return
    EndIf

    ; Determine position to insert
    If $fGLVEx_Bar_Under Then
        If $iGLVExDragged_Index > $iGLVExInsert_Index Then $iGLVExInsert_Index += 1
    Else
        If $iGLVExDragged_Index < $iGLVExInsert_Index Then $iGLVExInsert_Index -= 1
    EndIf

    ; Clear insert mark
    _GUICtrlListView_SetInsertMark($hGLVEx_Handle, -1, True)

    ; Clear drag image
    If $hGLVExDragged_Image Then
        _GUIImageList_DragLeave($hGLVEx_Handle)
        _GUIImageList_EndDrag()
        _GUIImageList_Destroy($hGLVExDragged_Image)
        $hGLVExDragged_Image = 0
    EndIf

    ; Check not dropping on dragged item(s)
    Switch $iGLVExInsert_Index
        Case $iGLVExDragged_Index To $iGLVExDragged_Index + $iMultipleItems
            ; Reset highlight to original items
            For $i = 0 To $iMultipleItems
                _GUIListViewEx_HighLight($iGLVExDragged_Index + $i)
            Next
            Return
    EndSwitch

    ; Amend array
    ; Get data from dragged element(s)
    If $iMultipleItems Then
        ; Multiple dragged elements
        Switch UBound($aGLVEx_Array, 0) ; Check array format
            Case 1
                Local $aInsertData[$iMultipleItems + 1]
                For $i = 0 To $iMultipleItems
                    $aInsertData[$i] = $aGLVEx_Array[$iGLVExDragged_Index + 1 + $i]
                Next
            Case 2
                Local $aInsertData[$iMultipleItems + 1]
                For $i = 0 To $iMultipleItems
                    Local $aItemData[UBound($aGLVEx_Array, 2)]
                    For $j = 0 To UBound($aGLVEx_Array, 2) - 1
                        $aItemData[$j] = $aGLVEx_Array[$iGLVExDragged_Index + 1][$j]
                    Next
                    $aInsertData[$i] = $aItemData
                Next
        EndSwitch
    Else
        ; Single dragged element
        Switch UBound($aGLVEx_Array, 0) ; Check array format
            Case 1
                Local $aInsertData[1]
                $aInsertData[0] = $aGLVEx_Array[$iGLVExDragged_Index + 1]
            Case 2
                Local $aInsertData[1]
                Local $aItemData[UBound($aGLVEx_Array, 2)]
                For $i = 0 To UBound($aGLVEx_Array, 2) - 1
                    $aItemData[$i] = $aGLVEx_Array[$iGLVExDragged_Index + 1][$i]
                Next
                $aInsertData[0] = $aItemData
        EndSwitch
    EndIf

    ; Copy checkbox data from dragged elements
    If IsArray($aGLVExDragCheck_Array) Then
        If $iMultipleItems Then
            Local $aDragged_Data[$iMultipleItems + 1]
            For $i = 0 To $iMultipleItems
                $aDragged_Data[$i] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iGLVExDragged_Index + $i)
            Next
        Else
            Local $aDragged_Data[1]
            $aDragged_Data[0] = _GUICtrlListView_GetItemChecked($hGLVEx_Handle, $iGLVExDragged_Index)
        EndIf
    EndIf

    ; Delete dragged element(s) from arrays
    For $i = 0 To $iMultipleItems
        _GUIListViewEx_Array_Delete($aGLVEx_Array, $iGLVExDragged_Index + 1)
        If IsArray($aGLVExDragCheck_Array) Then
            _GUIListViewEx_Array_Delete($aGLVExDragCheck_Array, $iGLVExDragged_Index + 1)
        EndIf
    Next

    ; Amend insert positon for multiple items deleted above
    If $iGLVExDragged_Index < $iGLVExInsert_Index Then
        $iGLVExInsert_Index -= $iMultipleItems
    EndIf
    ; Re-insert dragged element(s) into array
    For $i = $iMultipleItems To 0 Step -1
        _GUIListViewEx_Array_Insert($aGLVEx_Array, $iGLVExInsert_Index + 1, $aInsertData[$i])
        If IsArray($aGLVExDragCheck_Array) Then
            _GUIListViewEx_Array_Insert($aGLVExDragCheck_Array, $iGLVExInsert_Index + 1, $aDragged_Data[$i])
        EndIf
    Next

    ; Amend ListView to match array
    If $iGLVExDragged_Index > $iGLVExInsert_Index Then
        _GUIListViewEx_Data_Change($iGLVExInsert_Index, $iGLVExDragged_Index + $iMultipleItems)
    Else
        _GUIListViewEx_Data_Change($iGLVExDragged_Index, $iGLVExInsert_Index + $iMultipleItems)
    EndIf

    ; Reset checkbox data
    If IsArray($aGLVExDragCheck_Array) Then
        For $i = 1 To UBound($aGLVExDragCheck_Array) - 1
            _GUICtrlListView_SetItemChecked($hGLVEx_Handle, $i - 1, $aGLVExDragCheck_Array[$i])
        Next
        ; Clear array
        $aGLVExDragCheck_Array = 0
    EndIf

    ; Set highlight to inserted item(s)
    For $i = 0 To $iMultipleItems
        _GUIListViewEx_HighLight($iGLVExInsert_Index + $i)
    Next

    ; Store amended array
    $aGLVEx_Data[$aGLVEx_Data[0][1]][2] = $aGLVEx_Array
    ; Delete copied array
    $aGLVEx_Array = 0

EndFunc   ;==>_GUIListViewEx_WM_LBUTTONUP_Handler

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_HighLight($iIndexA, $iIndexB)
; Description ...: Highlights first item and ensures visible while removing hightlight from second in multiple selection ListViews
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================
Func _GUIListViewEx_Highlight($iIndexA, $iIndexB = -1)

    ; Check if Native or UDF and set focus
    If $hGLVEx_CID Then
        GUICtrlSetState($hGLVEx_CID, 256) ; $GUI_FOCUS
    Else
        _WinAPI_SetFocus($hGLVEx_Handle)
    EndIf
    ; Cancel highlight on other item - needed for multisel listviews
    If $iIndexB <> -1 Then _GUICtrlListView_SetItemSelected($hGLVEx_Handle, $iIndexB, False)
    ; Set highlight to inserted item and ensure in view
    _GUICtrlListView_SetItemState($hGLVEx_Handle, $iIndexA, $LVIS_SELECTED, $LVIS_SELECTED)
    _GUICtrlListView_EnsureVisible($hGLVEx_Handle, $iIndexA)

EndFunc   ;==>_GUIListViewEx_HighLight

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Data_Change($iStart, $iEnd)
; Description ...: Resets ListView items within a defined range to the current values in the stored array
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================
Func _GUIListViewEx_Data_Change($iStart, $iEnd)

    Local $sBlanker, $aInsert, $iDim2

    ; Check if Native or UDF
    If $hGLVEx_CID Then
        ; Native ListView
        For $i = $iStart To $iEnd
            ; Get CID of the item
            Local $iCID = _GUICtrlListView_GetItemParam($hGLVEx_Handle, $i)
            ; Check array type
            Switch UBound($aGLVEx_Array, 0)
                Case 1
                    $aInsert = StringSplit($aGLVEx_Array[$i + 1], "|", 2)
                Case 2
                    $iDim2 = UBound($aGLVEx_Array, 2)
                    Local $aInsert[$iDim2]
                    For $j = 0 To $iDim2 - 1
                        $aInsert[$j] = $aGLVEx_Array[$i + 1][$j]
                    Next
            EndSwitch
            ; Insert new data into each column in turn
            $sBlanker = ""
            For $j = 0 To UBound($aInsert) - 1
                GUICtrlSetData($iCID, $sBlanker & $aInsert[$j])
                $sBlanker &= "|"
            Next
        Next
    Else
        ; UDF ListView
        For $i = $iStart To $iEnd
            ; Check if multicolumn
            $iDim2 = UBound($aGLVEx_Array, 2)
            If @error Then
                _GUICtrlListView_SetItemText($hGLVEx_Handle, $i, $aGLVEx_Array[$i + 1])
            Else
                ; For each column - or just once if not multicolumn
                For $j = 0 To $iDim2 - 1
                    ; Set data
                    _GUICtrlListView_SetItemText($hGLVEx_Handle, $i, $aGLVEx_Array[$i + 1][$j], $j)
                Next
            EndIf
        Next
    EndIf

EndFunc   ;==>_GUIListViewEx_Data_Change

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Add
; Description ...: Adds a specified value at the end of an existing 1D or 2D array.
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================
Func _GUIListViewEx_Array_Add(ByRef $avArray, $vAdd = "", $iStart = 0)

    ; Get size of the Array to modify
    Local $iIndex_Max = UBound($avArray)

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1

            ReDim $avArray[$iIndex_Max + 1]
            $avArray[$iIndex_Max] = $vAdd

        Case 2

        ; Get size of second dimension
        Local $iDim2 = UBound($avArray, 2)

        ; Redim the Array
        ReDim $avArray[$iIndex_Max + 1][$iDim2]

        ; Add new elements
        If IsArray($vAdd) Then
            ; Get size of Insert array
            Local $vAdd_Max = UBound($vAdd)
            For $j = 0 To $iDim2 - 1
                ; If Insert array is too small to fill Array then continue with blanks
                If $j > $vAdd_Max - 1 - $iStart Then
                    $avArray[$iIndex_Max][$j] = ""
                Else
                    $avArray[$iIndex_Max][$j] = $vAdd[$j + $iStart]
                EndIf
            Next
        Else
            ; Fill Array with variable
            For $j = 0 To $iDim2 - 1
                $avArray[$iIndex_Max][$j] = $vAdd
            Next
        EndIf

    EndSwitch

    Return $iIndex_Max

EndFunc   ;==>_GUIListViewEx_Array_Add

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Insert
; Description ...: Adds a value at the specified index of a 1D or 2D array.
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================

Func _GUIListViewEx_Array_Insert(ByRef $avArray, $iIndex, $vInsert)

    ; Get size of the Array to modify
    Local $iIndex_Max = UBound($avArray)

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1

            ; Resize array
            ReDim $avArray[$iIndex_Max + 1]

            ; Move down all elements below the new index
            For $i = $iIndex_Max To $iIndex + 1 Step -1
                $avArray[$i] = $avArray[$i - 1]
            Next

            ; Add the value in the specified element
            $avArray[$iIndex] = $vInsert
            Return $iIndex_Max

        Case 2

            ; If at end of array
            If $iIndex > $iIndex_Max - 1 Then Return $iIndex_Max = _GUIListViewEx_Array_Add($avArray, $vInsert)

            ; Get size of second dimension
            Local $iDim2 = UBound($avArray, 2)

            ; Redim the Array
            ReDim $avArray[$iIndex_Max + 1][$iDim2]

            ; Move down all elements below the new index
            For $i = $iIndex_Max To $iIndex + 1 Step -1
                For $j = 0 To $iDim2 - 1
                    $avArray[$i][$j] = $avArray[$i - 1][$j]
                Next
            Next

            ; Insert new elements
            If IsArray($vInsert) Then
                ; Get size of Insert array
                Local $vInsert_Max = UBound($vInsert)
                For $j = 0 To $iDim2 - 1
                    ; If Insert array is too small to fill Array then continue with blanks
                    If $j > $vInsert_Max - 1 Then
                        $avArray[$iIndex][$j] = ""
                    Else
                        $avArray[$iIndex][$j] = $vInsert[$j]
                    EndIf
                Next
            Else
                ; Fill Array with variable
                For $j = 0 To $iDim2 - 1
                    $avArray[$iIndex][$j] = $vInsert
                Next
            EndIf

    EndSwitch

    Return $iIndex_Max + 1

EndFunc   ;==>_GUIListViewEx_Array_Insert

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Delete
; Description ...: Deletes a specified index from an existing 1D or 2D array.
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================

Func _GUIListViewEx_Array_Delete(ByRef $avArray, $iIndex)

    ; Get size of the Array to modify
    Local $iIndex_Max = UBound($avArray)

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1

            ; Move up all elements below the new index
            For $i = $iIndex To $iIndex_Max - 2
                $avArray[$i] = $avArray[$i + 1]
            Next

            ; Redim the Array
            ReDim $avArray[$iIndex_Max - 1]

        Case 2

            ; Get size of second dimension
            Local $iDim2 = UBound($avArray, 2)

            ; Move up all elements below the new index
            For $i = $iIndex To $iIndex_Max - 2
                For $j = 0 To $iDim2 - 1
                    $avArray[$i][$j] = $avArray[$i + 1][$j]
                Next
            Next

            ; Redim the Array
            ReDim $avArray[$iIndex_Max - 1][$iDim2]

    EndSwitch

    Return $iIndex_Max - 1

EndFunc   ;==>_GUIListViewEx_Array_Delete

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _GUIListViewEx_Array_Swap
; Description ...: Swaps specified elements within a 1D or 2D array
; Author ........: Melba23
; Remarks .......:
; ===============================================================================================================================

Func _GUIListViewEx_Array_Swap(ByRef $avArray, $iIndex1, $iIndex2)

    Local $vTemp

    ; Get type of array
    Switch UBound($avArray, 0)
        Case 1
            ; Swap the elements via a temp variable
            $vTemp = $avArray[$iIndex1]
            $avArray[$iIndex1] = $avArray[$iIndex2]
            $avArray[$iIndex2] = $vTemp

        Case 2

            ; Get size of second dimension
            Local $iDim2 = UBound($avArray, 2)
            ; Swap the elements via a temp variable
            For $i = 0 To $iDim2 - 1
                $vTemp = $avArray[$iIndex1][$i]
                $avArray[$iIndex1][$i] = $avArray[$iIndex2][$i]
                $avArray[$iIndex2][$i] = $vTemp
            Next
    EndSwitch

    Return 0

EndFunc   ;==>_GUIListViewEx_Array_Swap

Any comment welcomed (and from anyone else who would like to try it). :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted

If you want the items in the listview to be sortable, you would need to modify the _GUICtrlListview_AddItem line in your _GUIListViewEx_Insert function to allow for the 5th parameter to be passed to the _GUICtrlListview_AddItem function.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

  • Moderators
Posted

BrewManNH,

I am afraid I do not understand your comment. When I run the script the columns are sortable as they are - so why do I need the $iParam parameter? Can you provide me with a scenario in which a sort on the ListView in that script fails? :huh:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted

Here are 4 examples using _GUICtrlListview_RegisterSort with and without the 5th parameter set. I created 4 of them because I wanted to show that it affects sorting using both the native AU3 ListView and the UDF created ListView.

#include <StructureConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <GUIListview.au3>
Global $lv
Example1()
Example2()
Example3()
Example4()
; ********************************************************
; Example 1 - Listview items created without 5th parameter
; ********************************************************
Func Example1()
    Local $lv, $msg

    GUICreate("Without 5th parameter set", 300, 200)

    $lv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180)
    _GUICtrlListView_RegisterSortCallBack(-1) ; Register the function "SortLV" for the sorting callback

    _GUICtrlListView_AddItem($lv, "ABC")
    _GUICtrlListView_AddSubItem($lv, 0, "666", 1)
    _GUICtrlListView_AddSubItem($lv, 0, "10.05.2004", 2)
    _GUICtrlListView_AddItem($lv, "DEF")
    _GUICtrlListView_AddSubItem($lv, 1, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 1, "11.05.2005", 2)
    _GUICtrlListView_AddItem($lv, "CDE")
    _GUICtrlListView_AddSubItem($lv, 2, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 2, "12.05.2004", 2)

    GUISetState()

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $lv
                $bSet = 0
                $nCurCol = GUICtrlGetState($lv)
                _GUICtrlListView_SortItems($lv, $nCurCol)
        EndSwitch
    WEnd
    _GUICtrlListView_UnRegisterSortCallBack($lv)
    GUIDelete()
EndFunc   ;==>Example1


; *******************************************************
; Example 2 - Listview items created with 5th parameter
; *******************************************************
Func Example2()
    Local $lv, $msg

    GUICreate("With 5th parameter set", 300, 200)

    $lv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180)
    _GUICtrlListView_RegisterSortCallBack(-1) ; Register the function "SortLV" for the sorting callback

    _GUICtrlListView_AddItem($lv, "ABC", -1, 1000)
    _GUICtrlListView_AddSubItem($lv, 0, "666", 1)
    _GUICtrlListView_AddSubItem($lv, 0, "10.05.2004", 2)
    _GUICtrlListView_AddItem($lv, "DEF")
    _GUICtrlListView_AddSubItem($lv, 1, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 1, "11.05.2005", 2)
    _GUICtrlListView_AddItem($lv, "CDE")
    _GUICtrlListView_AddSubItem($lv, 2, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 2, "12.05.2004", 2)

    GUISetState()

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $lv
                $bSet = 0
                $nCurCol = GUICtrlGetState($lv)
                _GUICtrlListView_SortItems($lv, $nCurCol)
        EndSwitch
    WEnd
    _GUICtrlListView_UnRegisterSortCallBack($lv)
    GUIDelete()
EndFunc   ;==>Example2

; ********************************************************
; Example 3 - Listview items created without 5th parameter, using UDF created ListView
; ********************************************************
Func Example3()
    Local $msg

    Local $hGUI = GUICreate("Without 5th parameter set", 300, 200)

    $lv = _GUICtrlListView_Create($hGUI, "Column1|Col2|Col3", 10, 10, 280, 180)
    _GUICtrlListView_RegisterSortCallBack($lv) ; Register the function "SortLV" for the sorting callback
    GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")
    _GUICtrlListView_AddItem($lv, "ABC")
    _GUICtrlListView_AddSubItem($lv, 0, "666", 1)
    _GUICtrlListView_AddSubItem($lv, 0, "10.05.2004", 2)
    _GUICtrlListView_AddItem($lv, "DEF")
    _GUICtrlListView_AddSubItem($lv, 1, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 1, "11.05.2005", 2)
    _GUICtrlListView_AddItem($lv, "CDE")
    _GUICtrlListView_AddSubItem($lv, 2, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 2, "12.05.2004", 2)

    GUISetState()

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $lv
                $bSet = 0
                $nCurCol = GUICtrlGetState($lv)
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $nCurCol = ' & $nCurCol & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
                _GUICtrlListView_SortItems($lv, $nCurCol)
        EndSwitch
    WEnd
    _GUICtrlListView_UnRegisterSortCallBack($lv)
    GUIDelete()
EndFunc   ;==>Example3
; *******************************************************
; Example 2 - Listview items created with 5th parameter, using UDF created ListView
; *******************************************************
Func Example4()
        Local $msg

    Local $hGUI = GUICreate("With 5th parameter set", 300, 200)

    $lv = _GUICtrlListView_Create($hGUI, "Column1|Col2|Col3", 10, 10, 280, 180)
    _GUICtrlListView_RegisterSortCallBack($lv) ; Register the function "SortLV" for the sorting callback
    GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")
    _GUICtrlListView_AddItem($lv, "ABC", -1, 1000)
    _GUICtrlListView_AddSubItem($lv, 0, "666", 1)
    _GUICtrlListView_AddSubItem($lv, 0, "10.05.2004", 2)
    _GUICtrlListView_AddItem($lv, "DEF")
    _GUICtrlListView_AddSubItem($lv, 1, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 1, "11.05.2005", 2)
    _GUICtrlListView_AddItem($lv, "CDE")
    _GUICtrlListView_AddSubItem($lv, 2, "444", 1)
    _GUICtrlListView_AddSubItem($lv, 2, "12.05.2004", 2)

    GUISetState()

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $lv
                $bSet = 0
                $nCurCol = GUICtrlGetState($lv)
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $nCurCol = ' & $nCurCol & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
                _GUICtrlListView_SortItems($lv, $nCurCol)
        EndSwitch
    WEnd
    _GUICtrlListView_UnRegisterSortCallBack($lv)
    GUIDelete()
EndFunc
Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iCode, $tNMHDR, $hWndListView, $hWndListView2

    $hWndListView = $lv
    If Not IsHWnd($lv) Then $hWndListView = GUICtrlGetHandle($lv)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)

                    ; Kick off the sort callback
                    _GUICtrlListView_SortItems($hWndFrom, DllStructGetData($tInfo, "SubItem"))
                    ; No return value
            EndSwitch
    EndSwitch
    Return $__LISTVIEWCONSTANT_GUI_RUNDEFMSG
EndFunc   ;==>_WM_NOTIFY

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

  • Moderators
Posted

BrewmanNH,

I wondered if that was the reason behind your comment - but as I only use SimpleSort on a single column at a time in the UDF, and not the more complex SortCallBack, it is not necessary to use the additional parameter to enable sorting to take place. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted

Does that mean that using your UDF, even with that change, you can't use another sorting routine?

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

  • Moderators
Posted

BrewManNH,

I have no idea as I have never tried. The whole idea behind the UDF (like many of the others I have written) was to simplify a relatively complex control (ListViews in this case) for the less-experienced user, so I decided to go for the simpler solution internally. :)

I imagine that if you use the UDF and do not ask it to do the sort internally you could then use the SortCallBack code. But give me a moment and I will try it out. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...