以下代码演示了如何用WindowsAPI函数遍历指定驱动器、目录的所有文件。其思路是:调出浏览文件夹窗口让用户指定所要搜索的起始路径,然后用查找文件的API函数遍历该目录下及其包含的子目录下的所有文件。本例需要:一个按钮,一个TextBox和一个ListBox,其中,TextBox应设置为多行。 核心代码参照API-Guide的两个例子程序,特此声明。
OptionExplicit
'查找第一个文件的API PrivateDeclareFunctionFindFirstFileLib"kernel32"Alias"FindFirstFileA"(ByVallpFileNameAsString,lpFindFileDataAsWIN32_FIND_DATA)AsLong '查找下一个文件的API PrivateDeclareFunctionFindNextFileLib"kernel32"Alias"FindNextFileA"(ByValhFindFileAsLong,lpFindFileDataAsWIN32_FIND_DATA)AsLong '获取文件属性的API PrivateDeclareFunctionGetFileAttributesLib"kernel32"Alias"GetFileAttributesA"(ByVallpFileNameAsString)AsLong '关闭查找文件的API PrivateDeclareFunctionFindCloseLib"kernel32"(ByValhFindFileAsLong)AsLong '以下为调用浏览文件夹窗口的API PrivateDeclareSubCoTaskMemFreeLib"ole32.dll"(ByValhMemAsLong) PrivateDeclareFunctionlstrcatLib"kernel32"Alias"lstrcatA"(ByVallpString1AsString,ByVallpString2AsString)AsLong PrivateDeclareFunctionSHBrowseForFolderLib"shell32"(lpbiAsBrowseInfo)AsLong PrivateDeclareFunctionSHGetPathFromIDListLib"shell32"(ByValpidListAsLong,ByVallpBufferAsString)AsLong
'常量 ConstMAX_PATH=260 ConstMAXDWORD=&HFFFF ConstINVALID_HANDLE_VALUE=-1 ConstFILE_ATTRIBUTE_ARCHIVE=&H20 ConstFILE_ATTRIBUTE_DIRECTORY=&H10 ConstFILE_ATTRIBUTE_HIDDEN=&H2 ConstFILE_ATTRIBUTE_NORMAL=&H80 ConstFILE_ATTRIBUTE_READONLY=&H1 ConstFILE_ATTRIBUTE_SYSTEM=&H4 ConstFILE_ATTRIBUTE_TEMPORARY=&H100 ConstBIF_RETURNONLYFSDIRS=1 PrivateTypeFILETIME dwLowDateTimeAsLong dwHighDateTimeAsLong EndType
'定义类(用于查找文件) PrivateTypeWIN32_FIND_DATA dwFileAttributesAsLong ftCreationTimeAsFILETIME ftLastAccessTimeAsFILETIME ftLastWriteTimeAsFILETIME nFileSizeHighAsLong nFileSizeLowAsLong dwReserved0AsLong dwReserved1AsLong cFileNameAsString*MAX_PATH cAlternateAsString*14 EndType
'定义类(用于浏览文件夹窗口) PrivateTypeBrowseInfo hWndOwnerAsLong pIDLRootAsLong pszDisplayNameAsLong lpszTitleAsLong ulFlagsAsLong lpfnCallbackAsLong lParamAsLong iImageAsLong EndType
'自定义函数 FunctionStripNulls(OriginalStrAsString)AsString If(InStr(OriginalStr,Chr(0))>0)Then OriginalStr=Left(OriginalStr,InStr(OriginalStr,Chr(0))-1) EndIf StripNulls=OriginalStr EndFunction
'自定义函数 FunctionFindFilesAPI(pathAsString,SearchStrAsString,FileCountAsInteger,_ DirCountAsInteger) DimFileNameAsString'文件名 DimDirNameAsString'子目录名 DimdirNames()AsString'目录数组 DimnDirAsInteger'当前路径的目录数 DimiAsInteger'循环计数器变量 DimhSearchAsLong'搜索句柄变量 DimWFDAsWIN32_FIND_DATA DimContAsInteger IfRight(path,1)<>"\"Thenpath=path&"\" '搜索子目录 nDir=0 ReDimdirNames(nDir) Cont=True hSearch=FindFirstFile(path&"*",WFD) IfhSearch<>INVALID_HANDLE_VALUEThen DoWhileCont DirName=StripNulls(WFD.cFileName) If(DirName<>".")And(DirName<>"..")Then IfGetFileAttributes(path&DirName)AndFILE_ATTRIBUTE_DIRECTORYThen dirNames(nDir)=DirName DirCount=DirCount 1 nDir=nDir 1 ReDimPreservedirNames(nDir) EndIf EndIf Cont=FindNextFile(hSearch,WFD)'获取下一个子目录 Loop Cont=FindClose(hSearch) EndIf '遍历目录并累计文件总数 hSearch=FindFirstFile(path&SearchStr,WFD) Cont=True IfhSearch<>INVALID_HANDLE_VALUEThen WhileCont FileName=StripNulls(WFD.cFileName) If(FileName<>".")And(FileName<>"..")Then FindFilesAPI=FindFilesAPI (WFD.nFileSizeHigh*MAXDWORD) WFD.nFileSizeLow FileCount=FileCount 1 List1.AddItempath&FileName EndIf Cont=FindNextFile(hSearch,WFD)'获取下一个文件 Wend Cont=FindClose(hSearch) EndIf '如果子目录存在则遍历之 IfnDir>0Then Fori=0TonDir-1 FindFilesAPI=FindFilesAPI FindFilesAPI(path&dirNames(i)&"\",_ SearchStr,FileCount,DirCount) Nexti EndIf EndFunction
'查找按钮代码 SubCommand1_Click() DimSearchPathAsString,FindStrAsString DimFileSizeAsLong DimNumFilesAsInteger,NumDirsAsInteger DimiNullAsInteger,lpIDListAsLong,lResultAsLong DimsPathAsString,udtBIAsBrowseInfo WithudtBI '设置浏览窗口 .hWndOwner=Me.hWnd '返回选中的目录 .ulFlags=BIF_RETURNONLYFSDIRS EndWith
'调出浏览窗口 lpIDList=SHBrowseForFolder(udtBI) IflpIDListThen sPath=String$(MAX_PATH,0) '获取路径 SHGetPathFromIDListlpIDList,sPath '释放内存 CoTaskMemFreelpIDList iNull=InStr(sPath,vbNullChar) IfiNullThen sPath=Left$(sPath,iNull-1) EndIf EndIf
Screen.MousePointer=vbHourglass List1.Clear SearchPath=sPath'选中的目录为搜索的起始路径 FindStr="*.*"'搜索所有类型的文件(此处可另作定义) FileSize=FindFilesAPI(SearchPath,FindStr,NumFiles,NumDirs) Text1.Text="查找到的文件数:"&NumFiles&vbCrLf&"查找的目录数:"&_ NumDirs 1&vbCrLf&"文件大小总共为:"&vbCrLf&_ Format(FileSize,"#,###,###,##0")&"字节" Screen.MousePointer=vbDefault EndSub->
|