Результатом работы функции SearchlnFolder является заполнение списка names именами или, если значение параметра addpath равно True, полными путями найденных файлов и каталогов. Значение параметра flags (битовая маска атрибутов) формируется так же, как для функции SetFileAttributes. Только одновременно можно установить любые интересующие программиста атрибуты. При нахождении хотя бы одного файла или каталога SearchlnFolder возвращает значение True.
В функции поиска проверка соответствия атрибутов найденных файлов и каталогов производится при помощи дополнительной функции MatchAttrs. Код этой функции приведен в листинге 4.24.
Листинг 4.24.
Фильтр атрибутов
function MatchAttrs(flags, attrs: DWORD): Boolean;
begin
MatchAttrs := (flags and attrs) = flags;
end;
Может показаться, что проверка из одной строки – слишком слабый аргумент для создания отдельной функции. В рассматриваемом примере отдельная функция MatchAttrs выделена для того, чтобы сделать отсеивание файлов (и папок) по атрибутам более очевидным.
В листинге 4.24 приводится реализация нестрогого фильтра: он принимает файл или папку, если они имеют все установленные в flags атрибуты, независимо от наличия файла или папки дополнительных атрибутов. Так, если мы задали flags:= FILE_ATTRIBUTE_READONLY, то будут найдены как файлы, так и каталоги, а также скрытые, системные и прочие файлы, также имеющие атрибут FILE_ATTRIBUTE_READONLY. Для реализации строгого фильтра можно заменить выражение в функции MatchAttrs простым равенством: flags = attrs.
Возможный результат поиска с использованием функции SearchlnFolder приводится на рис. 4.5.
Рис. 4.5. Поиск в заданной папке
Пример вызова функции SearchlnFolder (для показанного на рис. 4.5 приложения) приведен в листинге 4.25.
Листинг 4.25.
Использование функции SearchlnFolder
//Запуск поиска файла в заданной папке
procedure TForm2.Button1Click(Sender: TObject);
var
flags: DWORD;
begin
//Формируем набор атрибутов (по установленным флажкам на форме)
flags := 0;
if (chkDirs.Checked) then flags := flags or FILE_ATTRIBUTE_DIRECTORY;
if (chkHidden.Checked) then flags := flags or FILE_ATTRIBUTE_HIDDEN;
if (chkSystem.Checked) then flags := flags or FILE_ATTRIBUTE_SYSTEM;
if (chkReadOnly.Checked) then flags := flags or FILE_ATTRIBUTE_READONLY;
if (chkArchive.Checked) then flags := flags or
FILE_ATTRIBUTE_ARCHIVE;
lblFound.Caption := \'Поиск…\
lstFiles.Clear;
Refresh;
//Поиск (файлы записываются прямо в список на форме)
if not SearchInFolder(txtFolder.Text, txtMask.Text, flags,
lstFiles.Items)
then
lblFound.Caption := \'Поиск не дал результатов\'
else
lblFound.Caption := \'Найдено объектов: \' +
IntToStr(lstFiles.Count);
end;
Поиск по всему дереву каталогов
В листинге 4.26 приводится одна из возможных реализаций рекурсивного поиска по дереву каталогов. Алгоритм поиска работает следующим образом.
1. Выполняется поиск в папке folder (все найденные файлы или папки добавляются в список names).
2. Функция SearchlnTree вызывается для каждого подкаталога BfoLder для продолжения поиска в поддереве, определяемом подкаталогом.