Листинг 4.26.
Поиск по дереву каталогов
function SearchInTree(folder, mask: String; flags: DWORD;
names: TStrings; addpath: Boolean = False): Boolean;
var
hSearch: THandle;
FindData: WIN32_FIND_DATA;
bRes: Boolean; //Если равен True, то нашли хотя бы один файл или каталог
begin
//Осуществляем поиск в текущей папке
bRes := SearchInFolder(folder, mask, flags, names, addpath);
//Продолжим поиск в каждом из подкаталогов
hSearch := FindFirstFile(PAnsiChar(folder + \'\*\'), FindData);
if (hSearch <> INVALID_HANDLE_VALUE) then
begin
repeat
if (String(FindData.cFileName) <> \'..\') and
(String(FindData.cFileName) <> \'.\') then
//Пропускаем . и ..
begin
if (FindData.dwFileAttributes and
FILE_ATTRIBUTE_DIRECTORY <> 0)
then
//Нашли подкаталог – выполним в нем поиск
if SearchInTree(folder + \'\\' + String(FindData.cFileName),
mask, flags, names, addpath)
then
bRes := True;
end;
until FindNextFile(hSearch, FindData) = False;
FindClose(hSearch);
end;
SearchInTree := bRes;
end;
В функции SearchlnTree не используется просмотр каталога folder вручную (при помощи API-функций) из соображений эффективности. Если захотите, можете реализовать поиск подкаталогов при помощи функции SearchlnFolder. Правда, при этом нужно будет завести дополнительный список (TStringList) для сохранения найденных в текущем каталоге подкаталогов. Элементы списка будут использоваться только один раз: для поиска в подкаталогах.
Возможный результат поиска с использованием функции SearchlnTree приводится на рис. 4.6.
Рис. 4.6. Поиск по дереву каталогов
С небольшими модификациями алгоритм рекурсивного обхода дерева каталогов, реализованный в листинге 4.25, можно использовать и при операциях, отличных от простого поиска: например, при копировании или удалении дерева каталогов. Для этого достаточно выполнять нужные операции над каждым найденным объектом.