1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101:
| type TFileSearchOptions = set of (fsoRecursive, fsoRelativePaths, fsoOnlyFilenames); TSearchFilesCallback = reference to procedure(const ACurrentPath: string);
function PathCombine(lpszDest: PWideChar; const lpszDir, lpszFile: PWideChar): PWideChar; stdcall; external 'shlwapi.dll' name 'PathCombineW';
procedure GetAllFilesEx(AFileList: TStrings; const AParentPath, ASearchPath, AMasks: string; const AExcludes: string = ''; ASearchOptions: TFileSearchOptions = [fsoRecursive]; AAttributes: Integer = faAnyFile; ACallback: TSearchFilesCallback = nil; AMinAge: TDateTime = 0; AMaxAge: TDateTime = 2 * MAXWORD); var CompletePath, ParentPath, SearchPath, CurrentMask, CurrentFilename: string; Search: TSearchRec; MaskList, ExcludeList, ExcludedFiles: TStringList; begin if ASearchPath <> '' then SearchPath := IncludeTrailingPathDelimiter(ASearchPath) else SearchPath := ''; if AParentPath <> '' then ParentPath := IncludeTrailingPathDelimiter(AParentPath) else ParentPath := ''; SetLength(CompletePath, MAX_PATH); PathCombine(PChar(CompletePath), PChar(ParentPath), PChar(SearchPath)); SetLength(CompletePath, StrLen(PChar(CompletePath)));
if Assigned(ACallback) then ACallback(CompletePath);
ExcludedFiles := TStringList.Create; try ExcludeList := TStringList.Create; try ExcludeList.StrictDelimiter := True; ExcludeList.CommaText := AExcludes; for CurrentMask in ExcludeList do if FindFirst(CompletePath + CurrentMask, AAttributes, Search) = 0 then begin repeat ExcludedFiles.Add(AnsiUpperCase(CompletePath + Search.Name)); until FindNext(Search) <> 0; FindClose(Search); end; finally ExcludeList.Free; end;
MaskList := TStringList.Create; try MaskList.StrictDelimiter := True; MaskList.CommaText := AMasks; for CurrentMask in MaskList do if FindFirst(CompletePath + CurrentMask, AAttributes, Search) = 0 then begin repeat CurrentFilename := CompletePath + Search.Name; if (ExcludedFiles.IndexOf(AnsiUpperCase(CurrentFilename)) < 0) and (Search.TimeStamp >= AMinAge) and (Search.TimeStamp <= AMaxAge) then begin if fsoRelativePaths in ASearchOptions then AFileList.Add(ExtractRelativePath(ParentPath, CurrentFilename)) else if fsoOnlyFilenames in ASearchOptions then AFileList.Add(Search.Name) else AFileList.Add(CurrentFilename); end; until FindNext(Search) <> 0; FindClose(Search); end; finally MaskList.Free; end; finally ExcludedFiles.Free; end;
if fsoRecursive in ASearchOptions then begin if FindFirst(CompletePath + '*.*', faDirectory, Search) = 0 then begin repeat if ((Search.Attr and faDirectory) = faDirectory) and (Search.Name[1] <> '.') then GetAllFilesEx(AFileList, AParentPath, SearchPath + Search.Name, AMasks, AExcludes, ASearchOptions, AAttributes, ACallback, AMinAge, AMaxAge); until FindNext(Search) <> 0; FindClose(Search); end; end; end; |