CountFolder




Option Explicit
Public Const MAX_PATH = 260
'GetDriveType return values

Public Const DRIVE_REMOVABLE = 2
Public Const DRIVE_FIXED = 3
Public Const DRIVE_REMOTE = 4
Public Const DRIVE_CDROM = 5
Public Const DRIVE_RAMDISK = 6
Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
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
Public Declare Function GetDriveType _
Lib "kernel32" Alias "GetDriveTypeA" _
(ByVal nDrive As String) As Long
Public Declare Function GetLogicalDriveStrings _
Lib "kernel32" Alias "GetLogicalDriveStringsA" _
(ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
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
'flags for the user options

Public displayExpanded As Boolean 'integer for VB4
Public displaySorted As Boolean 'integer for VB4
Public NoOfDrives As Integer
Public LoadAll As Boolean 'integer for VB4
Public Function TrimNull(startstr As String) As String
Dim pos As Integer
pos = InStr(startstr, Chr$(0))

If pos Then
TrimNull = Left$(startstr, pos - 1)
Exit Function
End If

'if this far, there was

'no Chr$(0), so return the string

TrimNull = startstr

End Function

Public Sub GetAllDrivesFolders(tvwTree As Control, nodParentNode As Node)
'this routine uses a pre-dimmed array to speed up

'processing. Initially, the array is DIM'med to

'200 elements; in the While loop it is increased

'another 200 elements when "found Mod 200 = 0"

'(or the number found divided by 200 equals 0).

'At the end of the loop, it is resized down to the

'total found. This is significantly faster than

'using a Redim Preserve statement for each element found.

Dim nodX As Node

Dim WFD As WIN32_FIND_DATA
Dim hFile As Long

Dim sFile As String
Dim sPath As String

Dim i As Integer
Dim r As Long
Dim found As Integer

'assign the fullpath property to the path to search,

'assuring that the path is qualified.

If Right$(nodParentNode.FullPath, 1) "\" Then
sPath = nodParentNode.FullPath & "\"
Else: sPath = nodParentNode.FullPath
End If

'strip off the "My Computer" from the FullPath property.

'The actual fullpath is "My Computer\C:\", however,

'the Findxxx APIs want only the qualified path, i.e "C:\".

sPath = Mid$(sPath, 13, Len(sPath))
'find the first file matching the parameter \*.*

hFile = FindFirstFile(sPath & "*.*" & Chr$(0), WFD)

'reset the counter flag

found = 0
ReDim fArray(200)

If hFile -1 Then
sFile = TrimNull(WFD.cFileName)

WFD.dwFileAttributes = vbDirectory

While FindNextFile(hFile, WFD)

sFile = TrimNull(WFD.cFileName)

'ignore the 2 standard root entries

If (sFile ".") And (sFile "..") Then

If (WFD.dwFileAttributes And vbDirectory) Then

found = found + 1

'if found is at 200, then add some more array elements

If found Mod 200 = 0 Then ReDim Preserve fArray(found + 100)

fArray(found) = sFile

End If

End If

Wend

End If

r = FindClose(hFile)

'trim down the array to equal the elements found

ReDim Preserve fArray(found)

'add the folders to the treeview

For i = 1 To found

Set nodX = tvwTree.Nodes.Add(nodParentNode.Key, _
tvwChild, _
sPath & fArray(i) & "Dir", _
fArray(i), 8, 9)

'and get some more

If LoadAll Then GetAllDrivesFolders tvwTree, nodX

Next i

nodParentNode.Sorted = displaySorted
nodParentNode.Expanded = displayExpanded
End Sub

Sub GetNextLevelFolders(tvwTree As Control, nodParentNode As Node)

Dim nodX As Node

Dim WFD As WIN32_FIND_DATA
Dim hFile As Long

Dim sFile As String
Dim sPath As String

Dim i As Integer
Dim r As Long
Dim found As Integer
'assign the fullpath property to the path to search,

'assuring that the path is qualified.

If Right$(nodParentNode.FullPath, 1) "\" Then
sPath = nodParentNode.FullPath & "\"
Else: sPath = nodParentNode.FullPath
End If
'strip off the "My Computer" from the FullPath property.

'The actual fullpath is "My Computer\C:\", however,

'the Findxxx APIs want only the qualified path, i.e "C:\".

sPath = Mid$(sPath, 13, Len(sPath))
'find the first file matching the parameter \*.*

hFile = FindFirstFile(sPath & "*.*" & Chr$(0), WFD)

If hFile -1 Then

sFile = TrimNull(WFD.cFileName)

While FindNextFile(hFile, WFD)

sFile = TrimNull(WFD.cFileName)

'ignore the 2 standard root entries

If (sFile ".") And (sFile "..") Then

If (WFD.dwFileAttributes And vbDirectory) Then
'add the item and its icon

Set nodX = tvwTree.Nodes.Add(nodParentNode.Key, _
tvwChild, _
sPath & sFile & "Dir", _
sFile, 8, 9)
End If

End If

Wend

End If

r = FindClose(hFile)

nodParentNode.Sorted = displaySorted
nodParentNode.Expanded = displayExpanded

End Sub

Private Sub Form_Load()
'centre the form

Me.Move (Screen.Width - Me.Width) / 2, (Screen.Height - Me.Height) / 2
'set initial options

chkSort.Value = 1
chkExpanded.Value = 1
optLoadType(0).Value = True
'load the system drives

GetSystemDrives
'store the initial number of treeview elements for

'later subtraction when presenting the total number

'of files loaded (tvwControl_click routine)

NoOfDrives = tvwControl.Nodes.Count
lblMessage = "Set your Load options, then click any drive."
End Sub

Private Sub cmdEnd_Click()
Unload Me
Set Form1 = Nothing

End Sub

Private Sub chkExpanded_Click()
displayExpanded = chkExpanded.Value = 1
End Sub

Private Sub chkSort_Click()
displaySorted = chkSort.Value = 1
End Sub

Private Sub optLoadType_Click(Index As Integer)
LoadAll = optLoadType(1).Value = True
End Sub

Private Sub GetSystemDrives()
Dim nodX As Node
Dim r As Long
Dim allDrives As String
Dim currDrive As String
Dim drvIcon As Integer
'assign the imagelist to the treeview

tvwControl.ImageList = ImageList1
'add a base "My Computer" to the tree

Set nodX = tvwControl.Nodes.Add(, , "Root", "My Computer", 1, 1)
nodX.Expanded = True
'get the list of all available drives

allDrives = rgbGetAvailableDrives()

Do Until allDrives = Chr$(0)

'strip off one drive item from the allDrives$

currDrive = StripNulls(allDrives)

'determine the appropriate imagelist icon to display

drvIcon = GetDriveDisplayIcon(currDrive)

'we can't have the trailing slash, so ..

currDrive = Left$(currDrive, 2)

'Add the drive to the treeview.

Set nodX = tvwControl.Nodes.Add("Root", _
tvwChild, _
currDrive$ & "Dir", _
currDrive$, drvIcon, drvIcon)
nodX.Expanded = True

Loop

'force sorting of the drive letters

nodX.Sorted = True
End Sub

Private Function rgbGetAvailableDrives() As String
'returns a single string of available drive

'letters, each separated by a chr$(0)

Dim r As Long
Dim tmp As String

tmp = Space$(64)
r = GetLogicalDriveStrings(Len(tmp), tmp)

rgbGetAvailableDrives = Trim$(tmp)
End Function

Private Function GetDriveDisplayIcon(driveName) As Integer
Dim dIcon As Integer

Select Case GetDriveType(driveName)
Case 0, 1: dIcon = 1
Case DRIVE_REMOVABLE:
Select Case Left$(driveName, 1)
Case "a", "b": dIcon = 2
Case Else: dIcon = 5
End Select

Case DRIVE_FIXED: dIcon = 3
Case DRIVE_REMOTE: dIcon = 6
Case DRIVE_CDROM: dIcon = 4
Case DRIVE_RAMDISK: dIcon = 7
End Select

GetDriveDisplayIcon = dIcon

End Function

Private Function StripNulls(startstr As String) As String
'Take a string separated by a chr$(0), and split off 1 item, and

'shorten the string so that the next item is ready for removal.

Dim pos As Integer
Dim c As Integer
pos = InStr(startstr$, Chr$(0))

If pos Then
StripNulls = Mid$(startstr, 1, pos - 1)
startstr = Mid$(startstr, pos + 1, Len(startstr))
Exit Function
End If
End Function

Private Sub tvwControl_Click()
Dim nodX As Node
'show a wait message for long searches

lblMessage = "Searching drive " & _
tvwControl.SelectedItem & _
" for folders ... please wait"
DoEvents
'identify the selected node

Set nodX = tvwControl.SelectedItem
'verify it's valid

If (UCase$(Right$(nodX.Key, 3)) = "DIR") And (nodX.Children = 0) Then

'based on the user options, ...

If LoadAll Then
GetAllDrivesFolders tvwControl, nodX
Else: GetNextLevelFolders tvwControl, nodX
End If

End If
'subtract NoOfDrives because "My Computer" and the

'initial drives loaded should not be counted as a folder

lblMessage = "Total folders displayed : " & _
tvwControl.Nodes.Count - NoOfDrives

End Sub

'Please note that if you select Load All Drive's Folders,

'and you have a large drive with many folders, the app may appear to

'hang as it retrieves the information. Therefore, save the project

'before running, in case you need to Ctrl-Alt-Del out of the routine.

Enumerating Folders using FindFirstFile & FindNextFile API, AdvancedRelated
Related page Enumerating Folders using the FindFirstFile & FindNextFile
APIs has been completed.
This code demonstrates how to both recursively and singly search for all
folders on a target drive using the Win95/NT4 APIs FindFirstFile and
FindNextFile, and a routine to search just the selected folder.
The results are displayed in a treeview control, complete with the
appropriate icons for the type of drive installed, and folder icons for
the folders. The search depth (single level or all folders), as well as
options for sorting the folders and expanding on load are user-selectable.
For a discussion on the FindFirstFile, FindNextFile, and the WIN32_FIND_DATA
structure, see Enumerating Folders using FindFirstFile & FindNextFile.
Start a new project, and to the form add a command buttons (cmdEnd), a
Treeview control (tvwControl), an autosizing label (lblMessage), two
checkbox controls (chkExpanded and chkSort), and a control array of 2
option buttons (optLoadType(0) & optLoadType(1)), as indicated in the
illustration.
Add an imagelist to the form (ImageList1), and populate it with several
16x16 pixel icons. If you would prefer, download a blank form containing
the imagelist icons used in this demo rather than construct them yourself.










( countfolder.html )- by Paolo Puglisi - Modifica del 17/12/2023