Visual Basic Common Control API Routines
SHGetFileInfo: ListView Demo 2 - Populating the ListView
Second of four pages to create a ListView application to retrieve files from a specified folder.
Posted:   Sunday March 1, 1997
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB4-32, Windows 95
OS restrictions:   None
Author:   VBnet - Randy Birch
Related:   SHGetFileInfo: ListView Demo 1 - Obtaining the File Path
SHGetFileInfo: ListView Demo 2 - Populating the ListView
SHGetFileInfo: ListView Demo 3 - Adding Sorting Functionality
SHGetFileInfo: ListView Demo 4 - Adding the Associated Icons
SHGetFileInfo: ListView Demo 1 - Obtaining the File Path

This page details the code required to populate the listview control with files matching the selected file spec using the APIs FindFirstFile, FindNextFile and the WIN32_FIND_DATA type.

When the demo is completed, the final app will retrieve the users selection and populate the listview with selected files from that folder, complete with associated icons, file name, file type, file size and created date.

To the project constructed in Demo 1, add a ListView control as shown in the illustration.

In its Custom Properties, set:
   View = 3 - Report
   LabelEdit = 1 - Manual

Add the column headers as:
   Column 1 - Name - size=1700
   Column 2 - Size - size=900
   Column 3 - Type - size=1800
   Column 4 - Created - size=900

Set column 2 and column 4 to right alignment. Do not assign an imagelist to the control.
 BAS Module Code
To the bas module, make the following modifications and additions:

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
To the Constant declarations add:
Public Const SHGFI_DISPLAYNAME = &H200
Public Const SHGFI_EXETYPE = &H2000
Public Const SHGFI_SYSICONINDEX = &H4000  'system icon index
Public Const SHGFI_LARGEICON = &H0        'large icon
Public Const SHGFI_SMALLICON = &H1        'small icon
Public Const ILD_TRANSPARENT = &H1        'display transparent
Public Const SHGFI_TYPENAME = &H400

Public Const MAX_PATH As Long = 260

To the Type area, add:
   hIcon          As Long
   iIcon          As Long
   dwAttributes   As Long
   szDisplayName  As String * MAX_PATH
   szTypeName     As String * 80
End Type

Public shinfo As SHFILEINFO

Public Type FILETIME
  dwLowDateTime     As Long
  dwHighDateTime    As Long
End Type

  wYear             As Integer
  wMonth            As Integer
  wDayOfWeek        As Integer
  wDay              As Integer
  wHour             As Integer
  wMinute           As Integer
  wSecond           As Integer
  wMilliseconds     As Integer
End Type

Public Type WIN32_FIND_DATA
  dwFileAttributes  As Long
  ftCreationTime    As FILETIME
  ftLastAccessTime  As FILETIME
  ftLastWriteTime   As FILETIME
  nFileSizeHigh     As Long
  nFileSizeLow      As Long
  dwReserved0       As Long
  dwReserved1       As Long
  cFileName         As String * MAX_PATH
  cAlternate        As String * 14
End Type

In the API declaration area, add:
Public Declare Function FindFirstFile Lib "kernel32" _
   Alias "FindFirstFileA" _
  (ByVal lpFileName As String, 
   lpFindFileData As WIN32_FIND_DATA) As Long
Public Declare Function FindNextFile Lib "kernel32" _
  Alias "FindNextFileA" _
  (ByVal hFindFile As Long, 
   lpFindFileData As WIN32_FIND_DATA) As Long

Public Declare Function FindClose Lib "kernel32" _
  (ByVal hFindFile As Long) As Long

Public Declare Function FileTimeToSystemTime Lib "kernel32" _
  (lpFileTime As FILETIME, 
   lpSystemTime As SYSTEMTIME) As Long
Public Declare Function UpdateWindow Lib "user32" _
      (ByVal hwnd As Long) As Long

Public Declare Function ImageList_Draw Lib "comctl32" _
  (ByVal himl&, _
   ByVal i&, _
   ByVal hDCDest&, _
   ByVal x&, _
   ByVal y&, _
   ByVal flags&) As Long

Public Declare Function SHGetFileInfo Lib "shell32" _
   Alias "SHGetFileInfoA" _
  (ByVal pszPath As String, _
   ByVal dwFileAttributes As Long, _
   psfi As SHFILEINFO, _
   ByVal cbSizeFileInfo As Long, _
   ByVal uFlags As Long) As Long
 Form Code
Make the following additions to the form code:

Option Explicit

In the form's general declarations, add:
Dim UpdateFrequency  As Integer

In the form code, make the following bolded changes: 
Private Sub Form_Load()

    Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
    With Combo1
        .AddItem "All Files and Folders (*.*)"
        .AddItem "Applications (*.exe)"
        .AddItem "Device Drivers (*.drv)"
        .AddItem "Documents (*.doc)"
        .AddItem "Dynamic Link Libraries (*.dll)"
        .AddItem "Rich Text Format Documents (*.rtf)"
        .AddItem "System Files (*.sys)"
        .AddItem "Visual Basic Modules (*.bas)"
        .AddItem "Visual Basic Forms (*.frm)"
        .AddItem "Visual Basic 3 Projects (*.mak)"
        .AddItem "Visual Basic 4 Projects (*.vbp)"
        .AddItem "Postscript Printer Font Metrics (*.pfm)"
        .AddItem "Text Files (*.txt)"
        .AddItem "True Type Fonts (*.ttf)"
        .AddItem "Windows Help Files (*.hlp)"
        .AddItem "Windows Shortcuts (*.lnk)"
        .ListIndex = 0
    End With
    With ListView1
      .SortKey = 0
    End With
    UpdateFrequency = 25
End Sub

Private Sub cmdSelect_Click(index As Integer)

    Select Case index
        Case 0: fPath$ = vbGetBrowseDirectory$()
                If Len(fPath$) > 0 Then vbGetFileList
        Case 1: If Len(fPath$) > 0 Then vbGetFileList
        Case 2: Unload Me
    End Select
End Sub

Add the following new code to the form:
Private Function TrimNull(item As String) As String

    Dim pos As Integer
    pos = InStr(item, Chr$(0))
    If pos Then item = Left$(item, pos - 1)
    TrimNull = item
End Function

Private Sub vbGetFileList()

    Dim hFile As Long
    Dim fName As String
    Dim fExt As String
    Dim counter As Integer
    Me.MousePointer = vbArrowHourglass
    fExt = vbGetComboFileSpec()
    If Len(fPath) > 0 And Len(fExt) > 0 Then
      fName = fPath & fExt
      DisplayName = fName
          hFile = FindFirstFile(fName, WFD)
            If hFile > 0 Then
              counter = 1
              vbAddFileItemView WFD
                While FindNextFile(hFile, WFD)
                  counter = counter + 1
                  vbAddFileItemView WFD
                    If counter = UpdateFrequency Then
                        Call UpdateWindow(ListView1.hwnd)
                        counter = 0
                    End If
            End If
          FindClose hFile
    End If
    cmdSelect(1).Enabled = False
    Me.MousePointer = vbDefault
End Sub

Private Sub vbAddFileItemView(WFD As WIN32_FIND_DATA)

    Dim sFileName As String
    Dim ListImgKey As String
    Dim fType As String
    sFileName = TrimNull(WFD.cFileName)
    If sFileName <> "." And sFileName <> ".." Then
        Dim hInfo As Long
        Dim tExeType As Long
        Dim itmX As ListItem
        hInfo = SHGetFileInfo(fPath & sFileName, 0&, shinfo, Len(shinfo), BASIC_SHGFI_FLAGS)
        fType = LCase$(TrimNull(shinfo.szTypeName))
        Set itmX = ListView1.ListItems.Add(, , LCase$(sFileName))
        itmX.SubItems(1) = vbGetFileSizeKBStr(WFD.nFileSizeHigh + WFD.nFileSizeLow)
        itmX.SubItems(2) = fType
        itmX.SubItems(3) = vbGetFileDate$(WFD.ftCreationTime)
    End If
End Sub

Private Function vbGetFileDate(CT As FILETIME) As String

    Dim ds As Single
    If FileTimeToSystemTime(CT, ST) Then
       ds = DateSerial(ST.wYear, ST.wMonth, ST.wDay)
       vbGetFileDate$ = Format$(ds, "Short Date")
       vbGetFileDate$ = ""
    End If
End Function

Private Function vbGetFileSizeKBStr(fsize As Long) As String

    vbGetFileSizeKBStr = Format$(((fsize) / 1000) + 0.5, "#,###,###") & "kb"
End Function
Run the project, and click the Select Folder button. Browse to any folder, and hit OK. The folder selected and the file type from the combo box should be returned in the DisplayName label as a fully-qualified path and filespec. In addition, the listview should populate with all the files in the selected directory matching the selected file type.

Move to SHGetFileInfo: ListView Demo 3 - Adding Sorting Functionality.


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter