Act only on mouse selected items in a file list box

This code allows an action on all the items in a file list box.

For iCounter = 0 To filSource.ListCount - 1
        If (Right(filSource.Path, 1) <> "\") Then sSourceFile = filSource.Path + "\" Else sSourceFile = filSource.Path
            sSourceFile = sSourceFile + filSource.list(iCounter)
            sTargetFile = getTargetFileName(sSourceFile)
        If (sSourceFile = sTargetFile) Then
            sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
        End If
'
'Other code
'
'
Next iCounter

How do I change the code to allow an action on only mouse selected items in a file list box?
egabelAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

PreeceCommented:
Try this:

        If filSource.Selected(iCounter) Then
            MsgBox filSource.List(iCounter)
        End If


Preece
egabelAuthor Commented:
Thanks Preece,

How do I incorporate your code into mine?

Be well,
egabel
PreeceCommented:
For iCounter = 0 To filSource.ListCount - 1
    If filSource.Selected(iCounter) Then
        If (Right(filSource.Path, 1) <> "\") Then sSourceFile = filSource.Path + "\" Else sSourceFile = filSource.Path
            sSourceFile = sSourceFile + filSource.list(iCounter)
            sTargetFile = getTargetFileName(sSourceFile)
        If (sSourceFile = sTargetFile) Then
            sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
        End If
    End If
'
'Other code
'
'
Next iCounter

Preece
Your Guide to Achieving IT Business Success

The IT Service Excellence Tool Kit has best practices to keep your clients happy and business booming. Inside, you’ll find everything you need to increase client satisfaction and retention, become more competitive, and increase your overall success.

Robberbaron (robr)Commented:
You said 'mouse selected' items. I dont think there is a way to differentiate between mouse selected and items selected using keyboard.
There is just one selected property.  You may be able to intercept keyboard actions and discard them.
egabelAuthor Commented:
Hi Preese,

When I click on the files I want in the file list box, the code won't work.  filSource.Selected always remains false.

If I change the code to:  

For iCounter = 0 To filSource.ListCount - 1
    If filSource.Selected(iCounter) = False Then
        If (Right(filSource.Path, 1) <> "\") Then sSourceFile = filSource.Path + "\" Else sSourceFile = filSource.Path
            sSourceFile = sSourceFile + filSource.list(iCounter)
            sTargetFile = getTargetFileName(sSourceFile)
        If (sSourceFile = sTargetFile) Then
            sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
        End If
    End If

the code will run all the items in the file list box.  How do I get the files I want selected so the code will run.

Thanx,
egabel
PreeceCommented:
-  Just to clarify, are you selecting a few items, then clicking a button to invoke code on those selected items?  Or are you wanting to invoke the code right when you click an item in the filelistbox?  Either way, the code should work...

-  You are using a normal VB filelistbox, not a 3rd party control, right?

-  I'm assuming you have the multiselect property set to extended.  

The following code is straight from an app I've done that uses a filelistbox.  I can select a few items from the filelistbox, then click a button and it only acts on those selected items:

    Dim lX As Long
   
    For lX = 0 To File1.ListCount - 1
        If File1.Selected(lX) Then
            MsgBox pvsFolder & "\" & File1.List(lX)
        End If
    Next lX

PreeceCommented:
Also, this:

    For lX = 0 To File1.ListCount - 1
        If File1.Selected(lX) Then                         <<<<<< this line
            MsgBox pvsFolder & "\" & File1.List(lX)
        End If
    Next lX

is the same as:

Dim lX As Long
   
    For lX = 0 To File1.ListCount - 1
        If File1.Selected(lX) = True Then                         <<<<<< this line
            MsgBox pvsFolder & "\" & File1.List(lX)
        End If
    Next lX


Not sure why you are checking for false:

    If filSource.Selected(iCounter) = False Then

Preece
PreeceCommented:
Another thing, RobberBaron may have a point; please clarify if you want to restrict this to just selecting items with the mouse and not the keyboard...

Preece
egabelAuthor Commented:
Hi Preese,

You asked:
-  Just to clarify, are you selecting a few items, then clicking a button to invoke code on those selected items?  YES

-  You are using a normal VB filelistbox, not a 3rd party control, right?  YES

-  I'm assuming you have the multiselect property set to extended.  YES

I want to restrict this to just selecting items with the mouse.  Sorry I did not clarify this sooner.

How does the Selected property get set to True?

Best,
egabel
egabelAuthor Commented:
Hi Preese,

One more item with regards to my last question.  MSDN states, regarding the Selected property, "The Selected property will not return True for those items which are only highlighted".  I expect that when I click on an item in the file list box that it becomes selected, ie. set to True.  Is this not correct?

Thanks,
egabel
PreeceCommented:
>>How does the Selected property get set to True?
To best of my knowledge, the selected property is associated with each individual item in the list, not the filelistbox as a whole.  That is why you loop thru the list and test the selected property of each item.  Some controls have as SelCount property, such as the normal listbox and the Farpoint ListPro, which can come in handy, but not the filelistbox (bummer!).  

-  Is the code still acting on all items even if a only one or a few are selected?

>>I want to restrict this to just selecting items with the mouse.  Sorry I did not clarify this sooner.
If I'm understanding you correctly, is there a real need to not allow selecting with the keyboard?

Perhaps you mean that if you do select items with the keyboard, that you don't want the selected property for each item to be set.  Well, I don't think that is possible.  If an item is selected, via mouse, keyboard, or both, it is selected, and the selected property for each item will be set.

>>MSDN states, regarding the Selected property, "The Selected property will not return True for those items which are only highlighted.
I must be missing something, or just tired, because that doesn't make sense.  In my mind, if an item is highlighted, it is selected!  If you select an item, it becomes highlighted.  Everyone else looking at this thread agree?

Hope this helps.
Preece

Robberbaron (robr)Commented:
this is Preeces code with very slight modification to prevent keyboard selection.  trial form with filelistbox File1 & commandbutton Command1.

Private Sub Command1_Click()
Dim lX As Long, xmsg As String
   
    For lX = 0 To File1.ListCount - 1
        If File1.Selected(lX) = True Then           ' entry selected by mouse click, extended selection
            xmsg = xmsg & File1.Path & "\" & File1.List(lX) & vbCrLf
        End If
    Next lX

    MsgBox xmsg, vbInformation + vbOKOnly, "results"
End Sub

Private Sub File1_KeyDown(KeyCode As Integer, Shift As Integer)
    KeyCode = 0
End Sub

'----
msgbox shows only those files selected using mouse. Keyboard selection , incl scrolling is ignored.
need to release selections somewhere to. ie set selected property to false for each entry in file list box.
Like preece, i've got into the good habit of using & for string concatenation rather than +. It picks up logic errors....

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Robberbaron (robr)Commented:
The only way to highlight is to select. At least when using mouse.  
You can have a currentitem (noted by dashed outline box) that is not selected by setting the listindex by code. Perhaps thats what they mean by 'selected'
egabelAuthor Commented:
Hi Guys,

I don't know why but I think that another part of the code is causing the problem.  The code is not mine.  I have modified it to suit my needs.  I'm pretty much a VB beginner so, maybe my explanations and understanding are not 100% clear.  For example, initially, I asked "How do I change the code to allow an action on only mouse selected items in a file list box?"  I should have said "How do I change the code to allow an action on only highlighted items in a file list box?"

As you said earlier, the following code should work but it does not:

For iCounter = 0 To filSource.ListCount - 1
    If filSource.Selected(iCounter) Then
        If (Right(filSource.Path, 1) <> "\") Then sSourceFile = filSource.Path + "\" Else sSourceFile = filSource.Path
            sSourceFile = sSourceFile + filSource.list(iCounter)
            sTargetFile = getTargetFileName(sSourceFile)
        If (sSourceFile = sTargetFile) Then
            sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
        End If
    End If

When I comment out the 2nd and last lines it works just fine but all of the items in the file list box are acted upon.  I want to be able to select the file(s) to be acted upon.  Maybe the following section of the code (subroutine) which includes your additions will help.

Private Sub cmdMake_Click()
    Dim gdiImgInfo As CGDIPlusImageInfo
    Dim i As Integer
    Dim sSourceFile As String, sTargetFile As String
    Dim lOldHeight As Long, lOldWidth As Long
    Dim lNewHeight As Long, lNewWidth As Long
    Dim lAspect As Single


    Call dirSource_Change
    Call dirTarget_Change

    If (cmdMake.Enabled = False) Then Exit Sub
    prgMake.Max = filSource.ListCount
    prgMake.value = 0

    If yesHTML = 1 Then Call OpenHTMLStream
    Set gdiImgInfo = New CGDIPlusImageInfo
   
    For i = 0 To filSource.ListCount - 1
'        If filSource.Selected(i) Then
            If (Right(filSource.Path, 1) <> "\") Then sSourceFile = filSource.Path + "\" Else sSourceFile = filSource.Path
                sSourceFile = sSourceFile + filSource.list(i)
                sTargetFile = getTargetFileName(sSourceFile)
            If (sSourceFile = sTargetFile) Then
                sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
            End If
'        End If


    '////////////////// GDI+ functions
    gdiImgInfo.OpenImage sSourceFile

    lNewWidth = CLng(txtWidth.Text)
    lNewHeight = CLng(txtHeight.Text)

    picTarget.Picture = GDIPlus_MakeThumbs.CreateThumbnail(LoadPicturePlus(sSourceFile), lNewWidth, lNewHeight)
    sTargetFile = Replace(sTargetFile, ".bmp", ".jpg")
    SaveJPG picTarget.Picture, sTargetFile, quality:=txtNPQ
    '//////////////////
   
    If yesHTML = 1 Then
        sSourceFile = Replace(sSourceFile, removeFromStr(sSourceFile), "")  'delete the all up to the \Images directory
        sTargetFile = Replace(sTargetFile, removeFromStr(sTargetFile), "")    'from the HTML stream
        sSourceFile = Replace(sSourceFile, "\", "/")  'replace all backslashes with forward slashes in the HTML stream
        sTargetFile = Replace(sTargetFile, "\", "/")
        WriteHTMLStream sSourceFile, sTargetFile
    End If

    prgMake.value = i + 1
    Me.Caption = "Pix Resizer is resizing pictures " & CStr(i + 1) & " of " + CStr(filSource.ListCount)
    DoEvents
    Next i

    Set gdiImgInfo = Nothing

    prgMake.value = 0
    Call dirSource_Change
    Call dirTarget_Change
    Me.Caption = "Pix Resizer"
 
    If yesHTML = 1 Then frmHTML.txtHTML.Text = CloseHTMLStream: frmHTML.Show vbModal

End Sub

The only other alternative is for you to see the whole program.  Thanks for all the help and patience.

Be well,
egabel
PreeceCommented:
There are problems in how the For loop code is formatted.  I've reformatted it, and I think this is what you want.  I've moved the End If for our selected check to just above the Next i:

     For i = 0 To filSource.ListCount - 1
        If filSource.Selected(i) Then
            If (Right(filSource.Path, 1) <> "\") Then
                sSourceFile = filSource.Path + "\"
            Else
                sSourceFile = filSource.Path
            End If
            sSourceFile = sSourceFile + filSource.List(i)
            sTargetFile = getTargetFileName(sSourceFile)
            If (sSourceFile = sTargetFile) Then
                sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
            End If


            '////////////////// GDI+ functions
            gdiImgInfo.OpenImage sSourceFile
       
            lNewWidth = CLng(txtWidth.Text)
            lNewHeight = CLng(txtHeight.Text)
       
            picTarget.Picture = GDIPlus_MakeThumbs.CreateThumbnail(LoadPicturePlus(sSourceFile), lNewWidth, lNewHeight)
            sTargetFile = Replace(sTargetFile, ".bmp", ".jpg")
            SaveJPG picTarget.Picture, sTargetFile, quality:=txtNPQ
            '//////////////////
           
            If yesHTML = 1 Then
                sSourceFile = Replace(sSourceFile, removeFromStr(sSourceFile), "")  'delete the all up to the \Images directory
                sTargetFile = Replace(sTargetFile, removeFromStr(sTargetFile), "")    'from the HTML stream
                sSourceFile = Replace(sSourceFile, "\", "/")  'replace all backslashes with forward slashes in the HTML stream
                sTargetFile = Replace(sTargetFile, "\", "/")
                WriteHTMLStream sSourceFile, sTargetFile
            End If
   
            prgMake.Value = i + 1
            Me.Caption = "Pix Resizer is resizing pictures " & CStr(i + 1) & " of " + CStr(filSource.ListCount)
            DoEvents
        End If
    Next i
PreeceCommented:
Proper indentation is important and well placed code constructs, in this case our "If filSource.Selected(i) Then" and it's corresponding "End If"!  Now we know why the code was acting on every item regardless of the selected check!

Preece
egabelAuthor Commented:
Thanks for the lesson on proper indentation.  I should know better!!

I added your changes and the code no longer crashes but filSource.Selected always remains False no matter how many of the files in the file list box I highlight (select) with the mouse.  The code does nothing.  

If I comment out the "If filSource.Selected(i) Then" and it's corresponding "End If", the code runs but all the items in the file list box are acted upon as before.  What is this frustrated beginner doing wrong?

egabel
PreeceCommented:
Are you sure that you are using the proper file list box?  Do you have more than one on your form?  

Post your newly modified code again!

Preece
egabelAuthor Commented:
As far as I know, I'm using the standard VB file list box.  There is another file list box called fil.target.

     For i = 0 To filSource.ListCount - 1
        If filSource.Selected(i) Then
            If (Right(filSource.Path, 1) <> "\") Then
                sSourceFile = filSource.Path + "\"
            Else
                sSourceFile = filSource.Path
            End If
            sSourceFile = sSourceFile + filSource.List(i)
            sTargetFile = getTargetFileName(sSourceFile)
            If (sSourceFile = sTargetFile) Then
                sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
            End If


            '////////////////// GDI+ functions
            gdiImgInfo.OpenImage sSourceFile
       
            lNewWidth = CLng(txtWidth.Text)
            lNewHeight = CLng(txtHeight.Text)
       
            picTarget.Picture = GDIPlus_MakeThumbs.CreateThumbnail(LoadPicturePlus(sSourceFile), lNewWidth, lNewHeight)
            sTargetFile = Replace(sTargetFile, ".bmp", ".jpg")
            SaveJPG picTarget.Picture, sTargetFile, quality:=txtNPQ
            '//////////////////
           
            If yesHTML = 1 Then
                sSourceFile = Replace(sSourceFile, removeFromStr(sSourceFile), "")  'delete the all up to the \Images directory
                sTargetFile = Replace(sTargetFile, removeFromStr(sTargetFile), "")    'from the HTML stream
                sSourceFile = Replace(sSourceFile, "\", "/")  'replace all backslashes with forward slashes in the HTML stream
                sTargetFile = Replace(sTargetFile, "\", "/")
                WriteHTMLStream sSourceFile, sTargetFile
            End If
   
            prgMake.Value = i + 1
            Me.Caption = "Pix Resizer is resizing pictures " & CStr(i + 1) & " of " + CStr(filSource.ListCount)
            DoEvents
        End If
    Next i

egabel
PreeceCommented:
With this code:

    For i = 0 To filSource.ListCount - 1
        If filSource.Selected(i) Then
            debug.print "Item selected:  " & filSource.Selected(i)    ' <--  put a debug.print here, also set a breakpoint on this line
            If (Right(filSource.Path, 1) <> "\") Then            

Step thru the code and see if it is getting this far.  If so, let it finish and then post to this thread what was printed in the immediate window....

Preece
Robberbaron (robr)Commented:
you said the other filelist was fil.target    hopefully that really is filTarget  (no dot).  Or replace the dot with a -.

perhaps you should also check that the filelist is correct ....

     For i = 0 To filSource.ListCount - 1
        debug.print "File Item " & filSource.List(i) & " = " & iif(filSource.Selected(i),"Selected", "Clear"  ' <--  put a debug.print
        If   filSource.Selected(i) Then
......


This should show each item in your source listbox and a message noting if it was selected or clear.....
does this show each item that exists in the filelist box as expected ?
egabelAuthor Commented:
Did as you asked:

For i = 0 To filSource.ListCount - 1
        If filSource.Selected(i) Then
            Debug.Print "Item selected:  " & filSource.Selected(i)    ' <--  put a debug.print here, also set a breakpoint on this line
            If (Right(filSource.Path, 1) <> "\") Then

Results:
It never gets past "If filSource.Selected(i) Then" and it's corresponding "End If" until all the files in the file list box have been checked because ".Selected" always remains False even though files are selected with the mouse in the source file list box.

egabel
Robberbaron (robr)Commented:
what the result when you move the debug outside the if selected line..
PreeceCommented:
>>As far as I know, I'm using the standard VB file list box.

Just to be sure, on the form, select the filelistbox.  Look at the properties window.  
Just below the title "Properties - filSource", there is a dropdown.  Does it say:  "filSource  FileListBox"?
                                                                                                                                 ^^^^^^
Preece
egabelAuthor Commented:
robberbaron asked:

you said the other filelist was fil.target    hopefully that really is filTarget  (no dot).  Sorry, it is filTarget (No Dot)

Preese asked:

Just to be sure, on the form, select the filelistbox.  Look at the properties window.  
Just below the title "Properties - filSource", there is a dropdown.  Does it say:  "filSource  FileListBox"? YES

egabel
Robberbaron (robr)Commented:
1/ good that its filTarget     makes sense.
2/ what'S the resulting output when you move the debug outside the "if selected " line ?
     For i = 0 To filSource.ListCount - 1
        debug.print "File Item " & filSource.List(i) & " = " & iif(filSource.Selected(i),"Selected", "Clear"  ' <--  put a debug.print
        If   filSource.Selected(i) Then
....
egabelAuthor Commented:
Hi robberbaron,

When I add your debug.print line, the program runs and below is what I get in the intermediate window.  Also prior to running the code, I clicked on IMG_1782.JPG, IMG_1784.JPG and IMG_1785a.JPG.

Intermediate window:

File Item IMG_1782.JPG = Clear
File Item IMG_1783.JPG = Clear
File Item IMG_1784.JPG = Clear
File Item IMG_1785.JPG = Clear
File Item Img_1785_5X7.jpg = Clear
File Item Img_1785a.jpg = Clear

egabel
Robberbaron (robr)Commented:
something is strange then.
the files are being listed correctly but no selections are recorded.  This is not usual.
this is what is does on my test form.
File Item ADDSCCUS.DLL = Clear
File Item BIBLIO.MDB = Clear
File Item C2.EXE = Selected
File Item CVPACK.ERR = Clear
File Item CVPACK.EXE = Selected
File Item LICENSE.TXT = Clear

1/ To make sure we are using the correct control, is it possible to temporarily rename the filelist control to filZZZ.
2/ modify your code by globally replacing filSource with filZZZ .
egabelAuthor Commented:
Hi robberbaron ,

The file list box control I'm using in the code is the same one that comes up in the group on the left side of the screen as default when VB is started.  The icon looks like a page with the upper right corner folded over and lines across the page.

I don't know to accomplish your 1/ & 2/.

egabel
Robberbaron (robr)Commented:
1/ you are using the correct control. Each control has a unique name (or part of a control array). I just need to confirm its name is ok.click on the filelist control on the form.  In the right properties panel, you have an option to Name the control. use filZZZ

2/ change to the code window. Edit / Search & Replace / filSource to filZZZ

its a desparate attempt to remove any possible conflict between control names.
egabelAuthor Commented:
OK, now I understand what you wanted!!  Did your 1/ and 2/ but the code still runs the same as with the name filSource.

egabel
egabelAuthor Commented:
Hi Preese and robberbaron,

I got the code to run properly.  I'm not sure why but when I commented out the "Call dirSource_Change" and "Call dirTarget_Change" lines in the section of code below, I am able to select the files I wish to resize.  Thanks very much for the help for and patience with me during this exersize.  I have split the points equally between the two of you.

Be well,
egabel

Private Sub cmdMake_Click()
    Dim gdiImgInfo As CGDIPlusImageInfo
    Dim i As Integer
    Dim sSourceFile As String, sTargetFile As String
    Dim lOldHeight As Long, lOldWidth As Long
    Dim lNewHeight As Long, lNewWidth As Long
    Dim lAspect As Single


'    Call dirSource_Change
'    Call dirTarget_Change

    If (cmdMake.Enabled = False) Then Exit Sub
    prgMake.Max = filSource.ListCount
    prgMake.value = 0

    If yesHTML = 1 Then Call OpenHTMLStream
    Set gdiImgInfo = New CGDIPlusImageInfo
   
    For i = 0 To filSource.ListCount - 1
         If filSource.Selected(i) Then
            If (Right(filSource.Path, 1) <> "\") Then sSourceFile = filSource.Path + "\" Else sSourceFile = filSource.Path
                sSourceFile = sSourceFile + filSource.list(i)
                sTargetFile = getTargetFileName(sSourceFile)
            If (sSourceFile = sTargetFile) Then
                sTargetFile = GetDirectory(sTargetFile) + "_" + GetFile(sTargetFile)
            End If
PreeceCommented:
Whew!  Glad you finally resolved it.  Thanks for the points.
Also, good work, robberbaron!  Good we could collaborate.

Preece
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.