Jump to content

Listbox functions (Clear, Delete, Invert, Move Selection)


Recommended Posts

Hi, here are few functions for the ListBox.

I have searched the forum, but most of the functions are for listview, so i took one example code from melba23 (clear selection) and

wrote few more functions. (Because my current project needs them).

 

These functions work only on a Multi-selection ListBox . 

Edit: Only 1 function does not work with single selection box.

The functions do: Clear Selection, Delete Selected items, Invert Selection, Move selected items up and down.

 The example code has 2 Listboxes. The selected items on the left ListBox can be moved up and down. The right Listbox has buttons for the other functions.

#include <GUIConstantsEx.au3>
#include <GuiListBox.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Local $singlesel = 0, $iMsgBoxAnswer = 0

;MsgBox features: Title=Yes, Text=Yes, Buttons=Yes and No, Icon=Question, Modality=Task Modal

$iMsgBoxAnswer = MsgBox(8228, "Choose Listbox selecton type", "Yes for single, No for multi selection box")
If $iMsgBoxAnswer = 6 Then $singlesel = 1 ;Yes

Local $BL_1,$BL_2,$BR_1,$BR_2,$BR_3,$BR_4,$BR_5,$BR_6

Global $hForm1 = GUICreate("Listbox test", 349, 287)
$LB_1 = GUICtrlCreateList("", 6, 40, 157, 244, BitOR($LBS_NOTIFY, $LBS_MULTIPLESEL, $WS_HSCROLL, $WS_VSCROLL, $LBS_DISABLENOSCROLL))

If $singlesel = 1 Then
    $LB_2 = GUICtrlCreateList("", 179, 40, 157, 244, BitOR($LBS_NOTIFY, $WS_HSCROLL, $WS_VSCROLL, $LBS_DISABLENOSCROLL))
Else
    $LB_2 = GUICtrlCreateList("", 179, 40, 157, 244, BitOR($LBS_NOTIFY, $LBS_MULTIPLESEL, $WS_HSCROLL, $WS_VSCROLL, $LBS_DISABLENOSCROLL))
    $BR_3 = GUICtrlCreateButton("Reverse Sel", 272, 22, 68, 17)
EndIf

$BL_1 = GUICtrlCreateButton("Up", 20, 3, 35, 18)
$BL_2 = GUICtrlCreateButton("Down", 60, 3, 35, 18)
$BR_1 = GUICtrlCreateButton("Up", 200, 3, 35, 18)
$BR_2 = GUICtrlCreateButton("Down", 240, 3, 35, 18)

$BR_4 = GUICtrlCreateButton("Clear Sel", 217, 22, 52, 17)
$BR_5 = GUICtrlCreateButton("Delete", 175, 22, 40, 17)
$BR_6 = GUICtrlCreateButton("Populate", 290, 3, 50, 18)
GUISetState(@SW_SHOW)

For $x = 0 To 50
    If $x <= 10 Then GUICtrlSetData($LB_1, $x & " test", 0)
    GUICtrlSetData($LB_2, $x & " Test", 0)
Next


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $BL_1
            $a = Listbox_ItemMoveUD($LB_1, -1)
            If $a > -1 Then WinSetTitle($hForm1, "", "Moved items: " & $a)
        Case $BL_2
            $a = Listbox_ItemMoveUD($LB_1, 1)
            If $a > -1 Then WinSetTitle($hForm1, "", "Moved items: " & $a)
        Case $BR_1
            Listbox_ItemMoveUD($LB_2, -1)
        Case $BR_2
            Listbox_ItemMoveUD($LB_2, 1)
        Case $BR_3
            Listbox_ReverseSelection($LB_2)
        Case $BR_4
            Listbox_ClearSelection($LB_2)
        Case $BR_5
            Listbox_DeleteSelectedItems($LB_2)
        Case $BR_6                                  ;Populate
            GUICtrlSetData($LB_2, "") ; Clears the listbox
            For $x = 0 To 50
                GUICtrlSetData($LB_2, $x & " Test", 0)
            Next
    EndSwitch
WEnd


;note $hLB_ID - is the Listbox id

Func Listbox_DeleteSelectedItems($hLB_ID)
    Local $aSel = _GUICtrlListBox_GetSelItems($hLB_ID)        ;Get selected items
    Local $i, $slb = 0, $y, $x
    If $aSel[0] = 0 Then            ;If the array is empty, there is no selection, or it is a single selection listbox
        For $x = 0 To _GUICtrlListBox_GetCount($hLB_ID) - 1
            $y = _GUICtrlListBox_GetSel($hLB_ID, $x)
            If $y = True Then
                $slb = 1
                _GUICtrlListBox_DeleteString($hLB_ID, $x) ;Perform a delete on single sel. LB
                ExitLoop
            EndIf
        Next
    EndIf

    If $slb = 0 Then
        _GUICtrlListBox_BeginUpdate($hLB_ID)
        For $i = $aSel[0] To 1 Step -1                    ;Loop backwards and delete the selected items
            _GUICtrlListBox_DeleteString($hLB_ID, $aSel[$i])
        Next
        _GUICtrlListBox_EndUpdate($hLB_ID)
    EndIf
EndFunc   ;==>Listbox_DeleteSelectedItems

Func Listbox_ClearSelection($hLB_ID)
    ;Removes the selection from multi and single selection ListBox
    Local $aSel = _GUICtrlListBox_GetSelItems($hLB_ID)            ;Code from Melba23 - Autoit Forum
    Local $slb, $x, $y
    If $aSel[0] = 0 Then
        _GUICtrlListBox_SetCurSel($hLB_ID, -1)
        $slb = 1
    EndIf

    If $slb = 0 Then
        _GUICtrlListBox_BeginUpdate($hLB_ID)
        For $i = 1 To $aSel[0]
            _GUICtrlListBox_SetSel($hLB_ID, $aSel[$i], False)
        Next
        _GUICtrlListBox_EndUpdate($hLB_ID)
    EndIf
EndFunc   ;==>Listbox_ClearSelection

Func Listbox_ReverseSelection($hLB_ID)
    ;Logically, this function works only on multi-selection listboxes
    Local $i
    Local $aCou = _GUICtrlListBox_GetCount($hLB_ID)
    Local $cSel = _GUICtrlListBox_GetCaretIndex($hLB_ID)    ;Save the caret
    _GUICtrlListBox_BeginUpdate($hLB_ID)
    For $i = 0 To $aCou
        _GUICtrlListBox_SetSel($hLB_ID, $i, Not (_GUICtrlListBox_GetSel($hLB_ID, $i)))
    Next
    _GUICtrlListBox_SetCaretIndex($hLB_ID, $cSel)            ;Restore the caret
    _GUICtrlListBox_EndUpdate($hLB_ID)
EndFunc   ;==>Listbox_ReverseSelection


Func Listbox_ItemMoveUD($hLB_ID, $iDir = -1)
    ;Listbox_ItemMoveUD - Up/Down  Move Multi/Single item in a ListBox
    ;$iDir: -1 up, 1 down
    ;Return values -1 nothing to do, 0 nothing moved, >0 performed moves
    Local $iCur, $iNxt, $aCou, $aSel, $i, $m = 0, $y, $slb = 0 ;Current, next, Count, Selection, loop , movecount

    $aSel = _GUICtrlListBox_GetSelItems($hLB_ID) ;Put selected items in an array
    $aCou = _GUICtrlListBox_GetCount($hLB_ID) ;Get total item count of the listbox

    If $aSel[0] = 0 Then
        $y = _GUICtrlListBox_GetCurSel($hLB_ID)
        If $y > -1 Then
            _ArrayAdd($aSel, $y)
            $aSel[0] = 1
            $slb = 1
        EndIf
    EndIf

    ;WinSetTitle($hGUI, "", $aSel[0])                   ;Debugging info

    Select
        Case $iDir = -1 ;Move Up
            For $i = 1 To $aSel[0]
                If $aSel[$i] > 0 Then
                    $iNxt = _GUICtrlListBox_GetText($hLB_ID, $aSel[$i] - 1) ;Save the selection index - 1 text
                    _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i] - 1, _GUICtrlListBox_GetText($hLB_ID, $aSel[$i])) ;Replace the index-1 text with the index text
                    _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i], $iNxt) ;Replace the selection with the saved var
                    $m = $m + 1
                EndIf
            Next
            For $i = 1 To $aSel[0] ;Restore the selections after moving
                If $aSel[$i] > 0 Then
                    If $slb = 0 Then
                        _GUICtrlListBox_SetSel($hLB_ID, $aSel[$i] - 1, 1)
                    Else
                        _GUICtrlListBox_SetCurSel($hLB_ID, $aSel[$i] - 1)
                    EndIf
                EndIf
            Next
            Return $m
        Case $iDir = 1 ;Move Down
            If $aSel[0] > 0 Then
                For $i = $aSel[0] To 1 Step -1
                    If $aSel[$i] < $aCou - 1 Then
                        $iNxt = _GUICtrlListBox_GetText($hLB_ID, $aSel[$i] + 1)
                        _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i] + 1, _GUICtrlListBox_GetText($hLB_ID, $aSel[$i]))
                        _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i], $iNxt)
                        $m = $m + 1
                    EndIf
                Next
            EndIf
            For $i = $aSel[0] To 1 Step -1 ;Restore the selections after moving
                If $aSel[$i] < $aCou - 1 Then
                    If $slb = 0 Then
                        _GUICtrlListBox_SetSel($hLB_ID, $aSel[$i] + 1, 1)
                    Else
                        _GUICtrlListBox_SetCurSel($hLB_ID, $aSel[$i] + 1)
                    EndIf
                EndIf
            Next
            Return $m
    EndSelect
    Return -1
EndFunc   ;==>Listbox_ItemMoveUD

 

Edited by Dan_555
Updated code, now working with single selection boxes too
Link to post
Share on other sites
  • Dan_555 changed the title to Listbox functions (Clear, Delete, Invert, Move Selection)

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.

  • Similar Content

    • By meety
      My au3 script program needs administrator privileges on win10 to be executed correctly, because it needs to be added to the boot---Script code:RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", @ScriptName, "REG_SZ", @ScriptFullPath)
      I need to let the program automatically get administrator privileges, so I use a function of #RequireAdmin. Although the program can be added to the boot, but does not execute after system boot up? why is that?
      What should I do?
      --------------------------------------------------------------------
      Update:
      I found that after using the #RequireAdmin function, the program cannot be executed after system boot up.
      An example is given below. after it is compiled, it will not be executed after system boot up in the following two ways.
      1. C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\
      2. RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", @ScriptName, "REG_SZ", @ScriptFullPath)
      why is that?
      example
      #include <MsgBoxConstants.au3>
      #RequireAdmin
      Func test()
          MsgBox(0, "", "this is test message")
      EndFunc   ;==>test
      test()
       
       
    • By PeterVerbeek
      This topic give you access to an AutoIt functions library I maintain which is called PAL, Peter's AutoIt Library. The latest version 1.25 contains 212 functions divided into these topics:
      window, desktop and monitor GUI, mouse and color GUI controls including graphical buttons (jpg, png) logics and mathematics include constants string, xml string and file string dialogues and progress bars data lists: lists, stacks, shift registers and key maps (a.ka. dictionaries) miscellaneous: logging/debugging, process and system info Change log and files section  on the PAL website (SourceForge).
      A lot of these functions were created in the development of Peace, Peter's Equalizer APO Configuration Extension, which is a user interface for the system-wide audio driver called Equalizer APO.
    • By TheSaint
      I like and have been using TeraCopy, a third party program, for many years. Mostly it is a great program, but it does have some issues. On Windows XP for instance, Thumbs.db files could often hold up a copy or move process until the user manually responded to the error prompt. Some other issues I discuss below.
      PLEASE NOTE - I am not related to or affiliated in any way with the 3rd party TeraCopy program developers.
      ALSO NOTE - I myself have only tested TeraCopy Cure at this point, on Windows 7 (32 bit), and only with the free version of TeraCopy 2.27.
      This program, TeraCopy Cure, is related to another one of my TeraCopy assistant programs, TeraCopy Timer, but aims at being simpler and quicker to use ... if lacking its more advanced features.
      TeraCopy Cure is a frontend for TeraCopy and sets out to make up for its flaws and limitations.
      One of those flaws is queuing order, and the limitation relates to a same destination issue.
      You would think that queue order would be the same as add order, but that is not the case, and if you are doing a mix of COPY and MOVE then the COPY process could easily fail. It could fail with some source items, even if the  COPY process has already started before the same source MOVE process begins ... especially if the destination folder is on the source drive ... only the currently copying file is locked to that process.
      If you drag and drop another source for a same destination as an existing or impending COPY or MOVE process, then usually TeraCopy nicely adds it for you to that existing job. However, you might wish to avoid that, or it might occur during the testing phase of that active process, and then not be properly processed etc. But you are not given a choice and it just gets added.
       
           
      HOW TO USE
      See the right-click menu of the 'Batch List' (lowest field) and the right-click menu of the Tree field, for some useful options.
      (1) If desired, enable 'Auto Start'. NOTE - Even if enabled, this can be bypassed.
      (2) Set the destination folder, either by browsing on the tree or by dragging a folder to the Destination input field or label. Right-clicking on a folder in Explorer will also work, if enabled. The destination folder path will also show in the Tree if that right-click option is enabled.
      (3) Then drag & drop source file or folder onto one of three five areas - Folder (Drive) Tree field, or COPY or MOVE buttons ... this now also includes the source input and label.
      NOTE - If the Folder (Drive) Tree field is used, then you will additionally need to click either the COPY or MOVE button, to have that job added to the Batch List ... but this avoids 'Auto Start' if it is enabled. Drag & dropping to the buttons instead, saves on clicking, but starts the first job etc immediately if 'Auto Start' is enabled.
      (4) If needed and ready, click the START button to run the first job and those that follow.
      More information is included in program and in the NOTES etc sections below.
         
      WARNING - Depending on the amount of content on your destination drive, and folder level depth, and the speed of your PC, display of the full path in the Folder (Drive) Tree can take a while to show ... if you have that (right-click) option enabled ... it isn't by default. I found this feature quite tricky to get right, and I'm still not 100% sure it is now full-proof.
      TeraCopy Cure v1.5.zip  (source is included)
      TeraCopy Cure v1.6.zip  (source is included)
      NOTES
      UPDATES INFORMATION
      OLDER DOWNLOADS
       
    • By RAMzor
      Hello all,
      I am trying to get scrolling events for ListBox (mouse wheel and up/down arrows) but without success. The event not occured on row change but if I click on it - yes
      The ComboBox works fine even if not in focus (with mouse wheel) but I prefer visual look of ListBox. In addition to all, I can't change the height of control. Unfortunately it depends only on font size and same fonts has different heights between InputBox and ComboBox
      Is there a way to get over the issue?
      Any other ideas for unit selection realization are welcome
      #include <GuiComboBox.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <ListBoxConstants.au3> Global $idCombo, $idComboUnit, $idList, $idListUnit Global $sComboInitUnit = "pJ", $fComboVal = 7.5 Global $sListInitUnit = "nF", $fListVal = 0.15 Units_Conversion_Example() Func Units_Conversion_Example() ; Create GUI GUICreate("Units Conversion", 400, 296) $idCombo = GUICtrlCreateInput($fComboVal, 22, 20, 91, 26) GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif") $idComboUnit = GUICtrlCreateCombo("", 112, 20, 50, 30) GUICtrlSetData(-1, "uJ|nJ|pJ", $sComboInitUnit) GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif") $idList = GUICtrlCreateInput($fListVal, 22, 80, 91, 26) GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif") $idListUnit = GUICtrlCreateList("", 112, 80, 57, 26, BitOR($LBS_NOTIFY,$LBS_NOSEL,$WS_VSCROLL)) GUICtrlSetData(-1, "uF|nF|pF", $sListInitUnit) GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif") GUISetState(@SW_SHOW) GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Do Sleep(5) Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo, $hWndListBox If Not IsHWnd($idComboUnit) Then $hWndCombo = GUICtrlGetHandle($idComboUnit) If Not IsHWnd($idListUnit) Then $hWndListBox = GUICtrlGetHandle($idListUnit) $hWndFrom = $lParam $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word $iCode = BitShift($wParam, 16) ; Hi Word Switch $hWndFrom Case $hWndCombo Switch $iCode Case $LBN_SELCHANGE ConsoleWrite(GUICtrlRead($idComboUnit) & @CRLF) EndSwitch Case $hWndListBox Switch $iCode Case $CBN_SELCHANGE ConsoleWrite(GUICtrlRead($idListUnit) & @CRLF) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND  
       
    • By Rabu
      I want to use the winsock overlapped/completion routine method of i/o, but how do I get the pointer to my user function.  I know it is possible because when using the old method of windows messages, the user function name was used instead of a pointer.
×
×
  • Create New...