'========================================================
' File Search
' by: Rick Meyer date: July 2001
'========================================================
' File Name: fileSrch.frm
' Object Name: Form1
' Description: Interface and code to:
' • Search for files recursively
' • Add a listbox horizontal scrollbar
'========================================================
Option Explicit
'========================================================
' API declarations for the file searching operations
'========================================================
Const FILE_ATTRIBUTE_NORMAL = &H80
Const FILE_ATTRIBUTE_HIDDEN = &H2
Const FILE_ATTRIBUTE_SYSTEM = &H4
Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private 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 * 260
cAlternate As String * 14
End Type
Private Declare Function FindFirstFile _
Lib "kernel32" Alias "FindFirstFileA" ( _
ByVal lpFileName As String, _
lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile _
Lib "kernel32" Alias "FindNextFileA" ( _
ByVal hFindFile As Long, _
lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" _
(ByVal hFindFile As Long) As Long
'========================================================
' API declarations for
' adding the listbox horizontal scrollbar
'========================================================
Const LB_SETHORIZONTALEXTENT = &H194
Private Declare Function SendMessageByNum _
Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
'========================================================
' Module level program variables
'========================================================
Dim Num%, maxWdth&
Private Sub Command1_Click()
Num = 0
maxWdth = 0
List1.Clear
searchForFiles Dir1.Path, Combo1.Text
'Determine the width to pass to the API
maxWdth = maxWdth + TextWidth(" ")
maxWdth = maxWdth / Screen.TwipsPerPixelX
'The API call to add the horizontal scrollbar
SendMessageByNum List1.hwnd, _
LB_SETHORIZONTALEXTENT, maxWdth, 0
If Num = 0 Then Label1.Caption = "No Files Found"
End Sub
Private Sub searchForFiles( _
ByVal startPath$, ByVal match$)
Dim fPath$, fName$, fPathName$
Dim hfind&, nameLen%, matchLen%
Dim WFD As WIN32_FIND_DATA
Dim found As Boolean
fPath = startPath
If Right(fPath, 1) <> "\" Then
fPath = fPath & "\"
End If
matchLen = Len(match)
match = LCase$(match)
'The first API call is to FindFirstFile.
' Note that we get get all files with a "*"
' and not specify just the file extension
' because we need to get the directories too.
hfind = FindFirstFile(fPath & "*", WFD)
found = (hfind > 0)
Do While found
fName = TrimNull(WFD.cFileName)
nameLen = Len(fName)
fPathName = fPath & fName
If fName = "." Or fName = ".." Then
ElseIf WFD.dwFileAttributes And _
FILE_ATTRIBUTE_DIRECTORY Then
searchForFiles fPathName, match
ElseIf Check1.Value = vbUnchecked Then
'Match any protion of the filename found
' because the checkbox is unchecked
If InStr(fName, match) Then
AddAnItem fPathName
Else
DoEvents
End If
ElseIf matchLen > nameLen Then
'Don't do anything if found is too short
ElseIf LCase$(Right$(fName, matchLen)) _
= match Then
'We have an extension match
AddAnItem fPathName
Else
DoEvents
End If
'Subsequent API calls are to FindNextFile.
found = FindNextFile(hfind, WFD)
Loop
'Then close the findfile operation
FindClose hfind
End Sub
'Add an item to the listbox
Private Sub AddAnItem(f$)
Num = Num + 1
List1.AddItem f
Label1.Caption = Str$(Num) & " Files"
DoEvents
'Keep track of the longest name for the
' eventual horizontal scrollbar
If TextWidth(f) > maxWdth Then
maxWdth = TextWidth(f)
End If
End Sub
'The Find API's return strings terminated by the null
' character, Chr$(0). We must find that char and
' return the portion to the left that VB can use.
Private Function TrimNull$(ByVal Item As String)
Dim pos As Integer
pos = InStr(Item, Chr$(0))
If pos = 1 Then
Item = ""
ElseIf pos > 1 Then
Item = Left$(Item, pos - 1)
End If
TrimNull = Item
End Function
Private Sub Form_Load()
Move 1000, 1000, 3840, 5880
'NOTE: Combo1 height is read only at runtime
' please set it to 315 in properties window
Combo1.Move 2040, 2400, 1575
List1.Move 120, 3360, 3495, 2010
With Command1
.Move 240, 2400, 1575, 315
.Caption = "Search"
End With
With Check1
.Move 240, 2880, 1575, 255
.Caption = "Extensions"
.Value = vbChecked
End With
With Dir1
.Move 120, 120, 3495, 2115
.Path = "C:\"
End With
With Label1
.Move 2040, 2920, 1575, 255
.Caption = "0 Files"
End With
With Combo1
'You can add more file types here
.AddItem "mp3"
.AddItem "jpg"
.AddItem "gif"
.AddItem "txt"
.AddItem "htm"
.AddItem "exe"
'Adjust the default extension if you want
.Text = .List(0)
End With
End Sub
|