ListBox - Drag Items To New Location

Category: Controls - .Techniques

Date: 02-16-2022

Return to Index


 
'Sometimes you want the user to be able to reorder items in
'a list - preferably with the mouse.  This example shows how
'to popup a dialog that contains a list, allowing the user
'to drag the order of the list items.
 
'Compilable Example:  (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "win32api.inc"
%IDC_ListBox = 500 : %IDC_Button = 501
Global hDlg, hOrder As Dword
 
Function PBMain() As Long
   Dialog New Pixels, 0, "Test",300,300,200,185, %WS_OverlappedWindow To hDlg
   Control Add Button, hDlg, %IDC_Button, "Show Reorder Dialog", 20,20,120,20
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   Select Case Cb.Msg
      Case %WM_Command : If Cb.Ctl = %IDC_Button And Cb.CtlMsg = %BN_Clicked Then DisplayOrderDialog
   End Select
End Function
 
Sub DisplayOrderDialog
   Dim MyArray(5) As String
   Array Assign MyArray() = "Name", "Text","Image","Top", "Left", "Width"
   Dialog New Pixels, hDlg, "ReOrder",100,100,100,150, %WS_SysMenu, 0 To hOrder
   Control Add ListBox, hOrder, %IDC_ListBox, MyArray(), 0,0,110,200
   Dialog Show Modal hOrder Call OrderProc
End Sub
 
CallBack Function OrderProc() As Long
   Local pt As Point
   Static StartItem, EndItem, DragInWork As Long
   Select Case Cb.Msg
      Case %WM_SetCursor
         GetCursorPos pt
         ScreenToClient hOrder, pt
         If GetDlgCtrlID (Cb.WParam) <> %IDC_ListBox Then Exit Function
         Select Case Hi(WordCb.LParam)  'monitors lbuttondown, mousemose, lbuttonup
            Case %WM_LButtonDown
               DragInWork = 1
               Control Send hOrder, %IDC_ListBox, %LB_ItemFromPoint, 0, Mak(Long, pt.x, pt.y) To StartItem
               EndItem = 0
            Case %WM_MouseMove
               If DragInWork Then
                  Control Send hOrder, %IDC_ListBox, %LB_ItemFromPoint, 0, Mak(Long, pt.x, pt.y) To EndItem
                  ArrangeListBoxItems StartItem, EndItem
                  DragInWork = 0
               End If
         End Select
   End Select
End Function
 
Sub ArrangeListBoxItems(StartItem As Long, EndItem As Long)
   'place startitem in the position of enditem. maintain order above end position
   Local i, iCount, iReturn As Long, StartText, temp As String
   Incr StartItem : Incr EndItem    'arguments are zero-based values
   ListBox Get Count hOrder, %IDC_ListBox To iCount
   ListBox Get Text hOrder, %IDC_ListBox, StartItem To StartText
   If (StartItem = EndItem) Or (StartItem > iCount) Or (EndItem > iCount) Then Exit Sub
   If StartItem < EndItem Then     'start is above end
      For i = StartItem To EndItem-1
         ListBox Get Text hOrder, %IDC_ListBox, i+1 To temp
         ListBox Set Text hOrder, %IDC_ListBox, i, temp
      Next i
      ListBox Set Text hOrder, %IDC_ListBox, EndItem, StartText
   Else    'end is above start
      For i = StartItem To EndItem+1 Step -1
         ListBox Get Text hOrder, %IDC_ListBox, i-1 To temp
         ListBox Set Text hOrder, %IDC_ListBox, i, temp
      Next i
      ListBox Set Text hOrder, %IDC_ListBox, EndItem, StartText
   End If
End Sub
 
'gbs_00696
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm