home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / chktra1g / cfindfil.cls
Encoding:
Visual Basic class definition  |  1999-02-04  |  10.2 KB  |  383 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "CFindFile"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Attribute VB_Description = "Find's Files"
  15. Attribute VB_Ext_KEY = "SavedWithClassBuilder" ,"Yes"
  16. Attribute VB_Ext_KEY = "Top_Level" ,"Yes"
  17. Attribute VB_Ext_KEY = "RVB_UniqueId" ,"3652270F012F"
  18. Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes"
  19. Option Explicit
  20. 'Class Written By:  GDuncan
  21. '              On:  8/11/98
  22. 'Description:       Class provides an interface to the Win32 Find functions
  23. 'Dependences:       Win32 platform
  24.  
  25. ' '-- Usage Example
  26. 'Declarations
  27. 'Dim WithEvents clsFind As CFindFile
  28. 'Private Sub Search()
  29. '  Dim asfiles As Variant
  30. '  Dim lLoop As Long
  31. '  Dim lCount As Long
  32. '  Dim bResult as Boolean
  33. '
  34. '  Set clsFind = New CFindFile
  35. '
  36. '  clsFind.Path = "D:\" 'UNC Paths are supported
  37. '  clsFind.FileSpec = "FOLDER.MDB" 'Wild Cards are also supported
  38. '
  39. '  bResult = clsFind.FindAll(asfiles)
  40. '
  41. '  If VarType(asfiles) = (vbArray + vbString) Then
  42. '    lCount = UBound(asfiles)
  43. '    For lLoop = 0 To lCount
  44. '      Debug.Print asfiles(lLoop)
  45. '    Next lLoop
  46. '  End If
  47. 'End Sub
  48. '
  49. 'Private Sub clsFind_BeginFindFiles()
  50. '  'staStatusBar.Panels.Item("Status").Text = "Begining Search"
  51. 'End Sub
  52. '
  53. 'Private Sub clsFind_EndFindFiles(FileCount As Long)
  54. '  'staStatusBar.Panels.Item("Status").Text = "Found " & CStr(FileCount) & " Files"
  55. 'End Sub
  56. '
  57. 'Private Sub clsFind_FoundFile(FileName As String, Cancel As Boolean)
  58. '  'staStatusBar.Panels.Item("Status").Text = "Found File: " & FileName
  59. '  'staStatusBar.Refresh
  60. 'End Sub
  61. ' '-- End of Usage Example
  62.  
  63. ' If the function succeeds, the return value is a search handle
  64. ' used in a subsequent call to FindNextFile or FindClose
  65.  
  66. Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
  67.  
  68.  
  69. ' Rtns True (non zero) on succes, False on failure
  70.  
  71. Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
  72.  
  73. ' Rtns True (non zero) on succes, False on failure
  74.  
  75. Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
  76.  
  77.  
  78. Private Const MaxLFNPath = 260
  79.  
  80. 'FindFirstFile failure rtn value
  81.  
  82. Private Const INVALID_HANDLE_VALUE = -1
  83.  
  84. ' SearchDirs() constants
  85.  
  86. Private Const vbBackslash = "\"
  87.  
  88. Private Const vbAllFiles = "*.*"
  89.  
  90. Private Const vbKeyDot = 46
  91.  
  92. Private Type FILETIME
  93.   dwLowDateTime As Long
  94.   dwHighDateTime As Long
  95. End Type
  96.  
  97. Private Type WIN32_FIND_DATA
  98.   dwFileAttributes As Long
  99.   ftCreationTime As FILETIME
  100.   ftLastAccessTime As FILETIME
  101.   ftLastWriteTime As FILETIME
  102.   nFileSizeHigh As Long
  103.   nFileSizeLow As Long
  104.   dwReserved0 As Long
  105.   dwReserved1 As Long
  106.   cFileName As String * MaxLFNPath
  107.   cShortFileName As String * 14
  108. End Type
  109.  
  110.  
  111. Private WFD As WIN32_FIND_DATA
  112.  
  113. Private hItem&
  114.  
  115. Private hFile&
  116.  
  117. 'local variable(s) to hold property value(s)
  118.  
  119. Private msFileSpec        As String
  120.  
  121. Private msPath            As String
  122.  
  123. Private mbSearching       As Boolean
  124.  
  125. Private mbRecursive       As Boolean
  126.  
  127. Private mlRecursiveLevels As Long
  128.  
  129. Private mbUseFileSpec     As Boolean
  130.  
  131. Private mlTotalDirs       As Long
  132.  
  133. Private mlTotalFiles      As Long
  134.  
  135. ' *****************
  136. ' Events
  137. ' *****************
  138.  
  139. Public Event BeginFindFiles()
  140.  
  141. Public Event EndFindFiles(FileCount As Long)
  142.  
  143. Public Event FoundFile(FileName As String, Cancel As Boolean)
  144.  
  145. ' *****************
  146. ' Public Properties
  147. ' *****************
  148.  
  149. Public Property Let Path(ByVal vData As String)
  150.     msPath = vData
  151. End Property
  152.  
  153.  
  154. Public Property Get Path() As String
  155.   Path = msPath
  156. End Property
  157.  
  158.  
  159. Public Property Let FileSpec(ByVal vData As String)
  160.   msFileSpec = vData
  161. End Property
  162.  
  163.  
  164. Public Property Get FileSpec() As String
  165.   FileSpec = msFileSpec
  166. End Property
  167.  
  168.  
  169. Private Property Let Searching(ByVal vData As Boolean)
  170.     mbSearching = vData
  171. End Property
  172.  
  173.  
  174. Public Property Get Searching() As Boolean
  175.     Searching = mbSearching
  176. End Property
  177.  
  178. ' *********************
  179. ' Public Functions/Subs
  180. ' *********************
  181.  
  182. Public Function FindAll(FileListArray As Variant) As Boolean
  183. Attribute FindAll.VB_Description = "FindAll\r\nFind all Files mathcing the FileSpec and Path Properties"
  184.   Dim asfiles() As String
  185.   ReDim asfiles(0)
  186.   On Error GoTo eop_error
  187.   
  188.   If FindFiles(asfiles()) Then
  189.     FileListArray = asfiles()
  190.     FindAll = True
  191.   Else
  192.     FindAll = False
  193.   End If
  194.  
  195. eop_error:
  196.   Select Case Err.Number
  197.     Case Is > 0
  198.       FindAll = False
  199.       Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
  200.   End Select
  201. eop_exit:
  202.  
  203. End Function
  204.  
  205. ' ******************
  206. ' Private Properties
  207. ' ******************
  208.  
  209. Private Property Let Recursive(ByVal vData As Boolean)
  210.   'Future Property
  211.   mbRecursive = vData
  212. End Property
  213.  
  214.  
  215. Private Property Get Recursive() As Boolean
  216.   'Future Property
  217.   FileSpec = mbRecursive
  218. End Property
  219.  
  220.  
  221. Private Property Let RecursiveLevels(ByVal vData As Long)
  222.   'Future Property
  223.   mlRecursiveLevels = vData
  224. End Property
  225.  
  226.  
  227. Private Property Get RecursiveLevels() As Long
  228.   'Future Property
  229.   FileSpec = mlRecursiveLevels
  230. End Property
  231.  
  232. ' **********************
  233. ' Private Functions/Subs
  234. ' **********************
  235.  
  236. Private Function FindFiles(asFoundFiles() As String) As Boolean
  237.   ' If we're running & we got a click, it's because DoEvents in
  238.   ' either the SearchDirs() or SearchFileSpec() proc let it happen.
  239.   ' Tell the proc to stop. Once SearchDirs() has un-recursed itself
  240.   ' we'll finish off below where we left off...
  241.   Dim drvbitmask&, maxpwr%, pwr%
  242.   FindFiles = False
  243.   If Searching Then
  244.     Searching = False
  245.     GoTo eop_exit
  246.   End If
  247.   On Error Resume Next
  248.   
  249.   ' A parsing routine could be implemented here for
  250.   ' multiple file spec searches, i.e. "*.bmp,*.wmf", etc.
  251.   ' See the MS KB article Q130860 for information on how
  252.   ' FindFirstFile() does not handle the "?" wildcard char correctly !!
  253.   If Len(FileSpec) = 0 Then GoTo eop_exit
  254.   
  255.   If Len(Path) = 0 Then GoTo eop_exit
  256.   
  257.   mbSearching = True
  258.   mbUseFileSpec = True
  259.   
  260.   RaiseEvent BeginFindFiles
  261.   
  262.   Call SearchDirs(Path, asFoundFiles())
  263.   
  264.   Searching = False
  265.   mbUseFileSpec = False
  266.   
  267.   mlTotalFiles = UBound(asFoundFiles)
  268.   RaiseEvent EndFindFiles(mlTotalFiles)
  269.   
  270.   FindFiles = True
  271.     
  272. eop_exit:
  273.     
  274. End Function
  275.  
  276. ' This is were it all happens...
  277.  
  278. ' You can use the values in returned in the
  279. ' WIN32_FIND_DATA structure to virtually obtain any
  280. ' information you want for a particular folder or group of files.
  281.  
  282. ' This recursive procedure is similar to the Dir$ function
  283. ' example found in the VB3 help file...
  284.  
  285.  
  286. Private Sub SearchDirs(CurPath$, asFoundFiles() As String) ' curpath$ is passed w/ trailing "\"
  287.   ' These can't be static!!! They must be
  288.   ' re-allocated on each recursive call.
  289.   Dim dirs%, dirbuf$(), i%
  290.   
  291.   ' This proc to be cancelled by the user.
  292.   ' It's not necessary to have this in the loop
  293.   ' below since the loop works so fast...
  294.   DoEvents
  295.   
  296.   If Not Searching Then GoTo eop_exit
  297.   
  298.   ' This loop finds *every* subdir and file in the current dir
  299.   hItem& = FindFirstFile(CurPath$ & vbAllFiles, WFD)
  300.   
  301.   If hItem& <> INVALID_HANDLE_VALUE Then
  302.     Do
  303.       ' Tests for subdirs only...
  304.       If (WFD.dwFileAttributes And vbDirectory) Then
  305.           
  306.         ' If not a  "." or ".." DOS subdir...
  307.         If Asc(WFD.cFileName) <> vbKeyDot Then
  308.           ' This is executed in the mnuFindFiles_Click()
  309.           ' call though it isn't used...
  310.           mlTotalDirs = mlTotalDirs + 1
  311.           ' This is the heart of a recursive proc...
  312.           ' Cache the subdirs of the current dir in the 1 based array.
  313.           ' This proc calls itself below for each subdir cached in the array.
  314.           ' (re-allocating the array only once every 10 itinerations improves speed)
  315.           If (dirs% Mod 10) = 0 Then ReDim Preserve dirbuf$(dirs% + 10)
  316.           dirs% = dirs% + 1
  317.           dirbuf$(dirs%) = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)
  318.         End If
  319.       
  320.         ' File size and attribute tests can be used here, i.e:
  321.         ' ElseIf (WFD.dwFileAttributes And vbHidden) = False Then  'etc...
  322.         
  323.         ' Get a total file count for mnuFolderInfo_Click()
  324.       ElseIf Not mbUseFileSpec Then
  325.         mlTotalFiles = mlTotalFiles + 1
  326.       End If
  327.     
  328.     ' Get the next subdir or file
  329.     Loop While FindNextFile(hItem&, WFD)
  330.         
  331.     ' Close the search handle
  332.     Call FindClose(hItem&)
  333.   
  334.   End If
  335.   ' When UseFileSpec% is set mnuFindFiles_Click(),
  336.   ' SearchFileSpec() is called & each folder must be
  337.   ' searched a second time.
  338.   If mbUseFileSpec Then
  339.     Call SearchFileSpec(CurPath$, asFoundFiles())
  340.   End If
  341.  
  342.   ' Recursively call this proc & iterate through each subdir cached above.
  343.   For i% = 1 To dirs%
  344.     SearchDirs CurPath$ & dirbuf$(i%) & vbBackslash, asFoundFiles()
  345.   Next i%
  346. eop_exit:
  347.  
  348. End Sub
  349.  
  350.  
  351. Private Sub SearchFileSpec(CurPath$, asFoundFiles() As String)
  352.   'curpath$ is passed w/ trailing "\"
  353.   ' This procedure *only*  finds files in the
  354.   ' current folder that match the FileSpec$
  355.   Dim Cancel As Boolean
  356.   Dim sTempFile As String
  357.   hFile& = FindFirstFile(CurPath$ & FileSpec, WFD)
  358.   If hFile& <> INVALID_HANDLE_VALUE Then
  359.         
  360.     Do
  361.       ' Use DoEvents here since we're loading a ListBox and
  362.       ' there could be hundreds of files matching the FileSpec$
  363.       DoEvents
  364.       If Not mbSearching Then GoTo eop_exit
  365.       
  366.       ReDim Preserve asFoundFiles(UBound(asFoundFiles) + 1)
  367.       sTempFile = CurPath$ & Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)
  368.       asFoundFiles(UBound(asFoundFiles)) = sTempFile
  369.       
  370.       Cancel = False
  371.       RaiseEvent FoundFile(sTempFile, Cancel)
  372.       mbSearching = Not Cancel
  373.           
  374.       ' Get the next file matching the FileSpec$
  375.     Loop While FindNextFile(hFile&, WFD)
  376.     ' Close the search handle
  377.     Call FindClose(hFile&)
  378.   End If
  379.  
  380. eop_exit:
  381.  
  382. End Sub
  383.