I'm modifing a screensaver app I made many years ago that shows any pictures on your drive with a delay for how long the pictures show for. Now what I want to change is it shows a list of all the pictures selected in a listbox in the order they are shown. If I select a picture name then I press an up or down button it will move the name up or down in the list. Now I assume you can do it if you use a String array of the names. Once one is selected remember the text then reload the listbox with the old text in the new position. Now I know that the bubble sort is a bad idea. I'm just wondering if there is a simpler idea.
Now the other slight problem is the up and down buttons captions. Now there are plenty of examples in Charmap.exe but when I try to copy and paste them into the caption they don't show. Even if I change the Command button font to the same font as Charmap. I know I get get around it but making a picture pointing up and down and using the picture property but I thought it would be quicker using a standard font.
I've don't a search for this type of question and nothing comes back apart from plenty of sorts which I don't needs it sorting.
I can post the app if its needed.
Thanks in anticipation.
Keith
I've been programming with VB for 25 years. Started with VB4 16bit Pro, VB5 Pro, VB6 Pro/Enterprise and now VB3 Pro. But I'm no expert, I'm still learning.
For the 1st problem, you don't need a separate array of strings. Remove lines of code dealing with ItemData if your listbox doesn't use the ItemData property to store anything. Also, change control names as needed to match yours.
Code:
Private Sub cmdUpDn_Click(Index As Integer)
Dim sItem As String, lData As Long
Dim lDir As Long
If Index = 0 Then ' up
If List1.ListIndex = 0 Then Exit Sub ' at top already
lDir = -1
Else
If List1.ListIndex = List1.ListCount - 1 Then Exit Sub ' at bottom already
lDir = 1
End If
sItem = List1.List(List1.ListIndex)
lData = List1.ItemData(List1.ListIndex)
List1.List(List1.ListIndex) = List1.List(List1.ListIndex + lDir)
List1.ItemData(List1.ListIndex) = List1.ItemData(List1.ListIndex + lDir)
List1.List(List1.ListIndex + lDir) = sItem
List1.ItemData(List1.ListIndex + lDir) = lData
List1.ListIndex = List1.ListIndex + lDir
End Sub
Insomnia is just a byproduct of, "It can't be done"
Here's one I've used for moving multiple selected items in a listbox up or down.
Edit- updated to support listbox ItemData.
Code:
Public Sub MoveListItems(LstBox As ListBox, Direction As Integer)
'////////////////////////////////////////////////////////////////////
' / Move multiple selected listbox items up or down the list /
' ------------------------------------------------------------------/
' syntax examples: /
' MoveListItems List1, -1 ' Move selected List1 items up the list. /
' MoveListItems List2, 1 ' Move selected List2 items down the list./
'////////////////////////////////////////////////////////////////////
Dim sTmp As String
Dim iTmp As Long
Dim Skip As Boolean
Dim i As Integer, Pos As Integer
With LstBox
If Direction = -1 Then ' move selected items up
Pos = 0
For i = 0 To .ListCount - 1
Skip = False
If .Selected(i) Then
If i = Pos Then Skip = True
Pos = Pos + 1
If Not Skip Then
sTmp = .List(i - 1) ' text
.List(i - 1) = .List(i)
.List(i) = sTmp
iTmp = .ItemData(i - 1) ' itemdata
.ItemData(i - 1) = .ItemData(i)
.ItemData(i) = iTmp
.ListIndex = i - 1
.Selected(i) = False
.Selected(i - 1) = True
End If
End If
Next i
Else ' move selected items down
Pos = .ListCount - 1
For i = .ListCount - 1 To 0 Step -1
Skip = False
If .Selected(i) Then
If i = Pos Then Skip = True
Pos = Pos - 1
If Not Skip Then
sTmp = .List(i + 1) ' text
.List(i + 1) = .List(i)
.List(i) = sTmp
iTmp = .ItemData(i + 1) ' itemdata
.ItemData(i + 1) = .ItemData(i)
.ItemData(i) = iTmp
.ListIndex = i + 1
.Selected(i) = False
.Selected(i + 1) = True
End If
End If
Next i
End If
End With
End Sub
Last edited by Edgemeal; Jul 30th, 2009 at 01:35 PM.
Any thoughts of getting the Command button Captions apart from pictures?
Keith
I've been programming with VB for 25 years. Started with VB4 16bit Pro, VB5 Pro, VB6 Pro/Enterprise and now VB3 Pro. But I'm no expert, I'm still learning.
As SchoolbusDriver posted in #2 above. One option is to use Marlett font. Make the button caption 5 for up arrow, 6 for down arrow. Increase font size as needed.
If the font doesn't exist on target pcs, the captions will probably revert to the numbers 5 and 6 vs the arrows.
Insomnia is just a byproduct of, "It can't be done"
I have alway done a remove and add to the list box to move items. And as SchoolBusDriver suggested try the Marlett font.
Code:
Option Explicit
Private Sub Form_Load()
Dim i As Integer
For i = 1 To 10
List1.AddItem i
Next i
With cmdUpDown(0)
.Font = "Marlett"
.Caption = "t"
.FontSize = 16
End With
With cmdUpDown(1)
.Font = "Marlett"
.Caption = "u"
.FontSize = 16
End With
End Sub
Private Sub cmdUpDown_Click(Index As Integer)
Dim intStep As Integer
Dim intIndex As Integer
Dim strEntry As String
With List1
If Index = 0 Then
'Up
If .ListIndex < 1 Then Exit Sub
intStep = -1
Else
'Down
If .ListIndex = .ListCount - 1 Or .ListIndex = -1 Then Exit Sub
intStep = 1
End If
intIndex = .ListIndex + intStep
strEntry = .List(.ListIndex)
.RemoveItem .ListIndex
.AddItem strEntry, intIndex
.ListIndex = intIndex
End With
End Sub
I use LaVolpe's technique for doing the actual moving, though I would use a With...End With to make it more readable.
Code:
Private Sub cmdUpDn_Click(Index As Integer)
Dim sItem As String, lData As Long
Dim lDir As Long
With List1
If Index = 0 Then ' up
If .ListIndex = 0 Then Exit Sub ' at top already
lDir = -1
Else
If .ListIndex = .ListCount - 1 Then Exit Sub ' at bottom already
lDir = 1
End If
sItem = .List(.ListIndex)
lData = .ItemData(.ListIndex)
.List(.ListIndex) = .List(.ListIndex + lDir)
.ItemData(.ListIndex) = .ItemData(.ListIndex + lDir)
.List(.ListIndex + lDir) = sItem
.ItemData(.ListIndex + lDir) = lData
.ListIndex = .ListIndex + lDir
End With
End Sub
For the arrows I use bitmaps, which I've zipped up and attached. Be sure to set UseMaskColor to True, and set the Mask Color to absolute Gray, as opposed to a system color. It's in the far left column of the palette dropdown, third down from the top.
Last edited by Ellis Dee; Jul 30th, 2009 at 02:34 PM.
I don't have vb6 at the moment so I did it in Excel...
Sure can work with slight amendments...
Code:
Dim i As Long, TouchMeNot As Boolean, pos As Long, strTmp As String
Private Sub cmdUP_Click()
pos = 0
For i = 0 To ListBox1.ListCount - 1
TouchMeNot = False
If ListBox1.Selected(i) Then
If i = pos Then TouchMeNot = True
pos = pos + 1
If TouchMeNot = False Then
strTmp = ListBox1.List(i - 1)
ListBox1.List(i - 1) = ListBox1.List(i)
ListBox1.List(i) = strTmp
ListBox1.ListIndex = i - 1
ListBox1.Selected(i) = False
ListBox1.Selected(i - 1) = True
End If
End If
Next
End Sub
Private Sub cmdDN_Click()
pos = ListBox1.ListCount - 1
For i = ListBox1.ListCount - 1 To 0 Step -1
TouchMeNot = False
If ListBox1.Selected(i) Then
If i = pos Then TouchMeNot = True
pos = pos - 1
If Not TouchMeNot Then
strTmp = ListBox1.List(i + 1)
ListBox1.List(i + 1) = ListBox1.List(i)
ListBox1.List(i) = strTmp
ListBox1.ListIndex = i + 1
ListBox1.Selected(i) = False
ListBox1.Selected(i + 1) = True
End If
End If
Next
End Sub
Regarding the font the simplest way will be to use a picture like you suggested in post 1 or you could use Anibtn32.ocx to create animated button (I am not sure if vb6 supports it now. used to use it many years ago...)
Last edited by Siddharth Rout; Jul 30th, 2009 at 03:18 PM.
Reason: typo
A good exercise for the Heart is to bend down and help another up...
Please Mark your Thread "Resolved", if the query is solved
MyGear:
★ CPU ★ Ryzen 5 5800X
★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
★ Keyboard ★ TVS Electronics Gold Keyboard
★ Mouse ★ Logitech G502 Hero
@LaVolpe your code would only move it up and not down. Sorry I didn't analyse the code to find out why.
@Edgemeal your code work great but there is a slight error or typo as you stated that
Code:
If Direction = -1 Then ' move selected items up
-1 makes it go down, no problem.
I've used some arrow icons as there pictures its the easiest way. I also did a search on PSC and there was one app ListBox Functions that shows 33 different ListBox functions and one of those is moving items up and down a ListBox.
Thanks again guys for your input, this topic is soon [Resolved].
Keith
I've been programming with VB for 25 years. Started with VB4 16bit Pro, VB5 Pro, VB6 Pro/Enterprise and now VB3 Pro. But I'm no expert, I'm still learning.
Keith, use 2 command buttons indexed 0 and 1. The index 0 button is up and 1 is down.
Code:
Private Sub cmdUpDn_Click(Index As Integer)
Dim sItem As String, lData As Long
Dim lDir As Long
If Index = 0 Then ' up
If List1.ListIndex = 0 Then Exit Sub ' at top already
lDir = -1
Else
If List1.ListIndex = List1.ListCount - 1 Then Exit Sub ' at bottom already
lDir = 1
End If
sItem = List1.List(List1.ListIndex)
lData = List1.ItemData(List1.ListIndex)
List1.List(List1.ListIndex) = List1.List(List1.ListIndex + lDir)
List1.ItemData(List1.ListIndex) = List1.ItemData(List1.ListIndex + lDir)
List1.List(List1.ListIndex + lDir) = sItem
List1.ItemData(List1.ListIndex + lDir) = lData
List1.ListIndex = List1.ListIndex + lDir
End Sub
Yes I can see that (I'm using a control array for the buttons as well) but the only reference to the Index is in the first few lines which checks if its at the top or bottom of the list.
Keith
I've been programming with VB for 25 years. Started with VB4 16bit Pro, VB5 Pro, VB6 Pro/Enterprise and now VB3 Pro. But I'm no expert, I'm still learning.
Re: [RESOLVED] Moving items up and down in a listbox
Originally Posted by Keithuk
Yes I can see that (I'm using a control array for the buttons as well) but the only reference to the Index is in the first few lines which checks if its at the top or bottom of the list.
You probably already have a solution, but for anyone else that comes to this thread, here is a full example
1. Add 1 command button to a form, name it cmdUpDn
2. Copy and paste that button to the same form, reply Yes to msgbox asking if you want control array created
3. Add a listbox to the form, leave it named List1
4. Copy & paste this code
Code:
Private Sub Form_Load()
Dim x As Long
For x = 1 To 10
List1.AddItem "Item " & x
Next
cmdUpDn(0).Caption = "Move Up"
cmdUpDn(1).Caption = "Move Down"
End Sub
Private Sub cmdUpDn_Click(Index As Integer)
Dim sItem As String, lData As Long
Dim lDir As Long
With List1
If .ListIndex > -1 Then ' else no item selected
If Index = 0 Then ' up
If .ListIndex > 0 Then lDir = -1 ' else at top already
Else
If .ListIndex < .ListCount - 1 Then lDir = 1 ' else at bottom already
End If
If lDir Then
sItem = .List(.ListIndex)
lData = .ItemData(.ListIndex)
.List(.ListIndex) = .List(.ListIndex + lDir)
.ItemData(.ListIndex) = .ItemData(.ListIndex + lDir)
.List(.ListIndex + lDir) = sItem
.ItemData(.ListIndex + lDir) = lData
.ListIndex = .ListIndex + lDir
End If
End If
End With
End Sub
Last edited by LaVolpe; Jul 31st, 2009 at 10:14 AM.
Reason: cleaned up the code a bit
Insomnia is just a byproduct of, "It can't be done"
Yes I can see that (I'm using a control array for the buttons as well) but the only reference to the Index is in the first few lines which checks if its at the top or bottom of the list.
That section of code also initialized lDir to be either -1 or 1, depending on the direction you're moving. The swap then occurs between the current item and the current item + lDir. Thus the Index value determines the direction of movement.