подскажите плз как осуществляется работа с TShellListView и TShellTreeView, конкретнее - необходимо указать директорию, у которой в нутри есть папки, для каждой из них сделать проверку SelectedFolder.SubFolders, если подпапок нет - совершить какое-либо действие, если же есть - то уйти вниз ещё на уровень и снова совершить предыдущее действие. Тоесть например:
в папке Black Lagoon ещё 2 папки в каждой из которых уже нет подпапок
а в папке !new1 есть ещё подпапки, в которых тоже могут быть подпапки
Подскажите или киньте ссылку на толковый мануал плиз
рекурсия
ммм я наверно оч туманно выразился ^__^ проблема в навигации - в TShellListView есть back, она вверх на уровень идёт, а вот как заставить его войти в папку?...
хмм ладно - а если у меня есть такой код
if (Lw.Selected.SubItems[5] = 'dir') then begin
procedure AddFile(path: string);
var SearchRec:TSearchRec;
begin
if path[length(path)] <> '\' then path := path + '\';
if FindFirst(path + '*.*', faAnyFile, SearchRec) = 0 then
repeat
if (SearchRec.Name = '.') or (SearchRec.Name = '..') then continue;
if SearchRec.Attr and faDirectory <> 0 then begin
AddFile(path + SearchRec.name)
end
else begin
Form1.Memo2.Lines.Add(path + SearchRec.name); // Для теста - просто вывел имена файлов ...
end;
until FindNext(SearchRec) <> 0;
end;
procedure TForm1.Button11Click(Sender: TObject);
begin
if ShellListView1.SelectedFolder.IsFolder then begin // Вообще-то этого достаточно
AddFile(ShellListView1.SelectedFolder.PathName);
end;
end;
volvo
домо аригато ^__^ опять спас
нащёт пяти - это я с книги брал и тупо переписал :[ вернее я не так понял что там написано было - думал чтото типа параметра файла который отвечает за папку, и недоумевал почему его назвали сабитемс
а вот такой вопросик - есть вот такая структура папки
в папке субтитров файлы на картинке справа
у меня стоит такая проверка для учёта папки
if (pos('.avi', SearchRec.Name))or(pos('.mkv', SearchRec.Name))or(pos('.VOB', SearchRec.Name))
or(pos('.ogm', SearchRec.Name))or(pos('.mp4', SearchRec.Name)) <> 0 then inc(vcount);
if (pos('.avi', SearchRec.Name) <> 0) and (pos('avi', Form1.Grid.Cells[4,gridcell-1]) = 0) then
begin
if Form1.Grid.Cells[4,gridcell-1] = '' then
begin
Image(path);
PathList.Add(path);
infill(path, AType);
end;
Form1.Grid.Cells[4,gridcell-1] := Form1.Grid.Cells[4,gridcell-1] + 'avi ';
end;
if
(pos('.avi', SearchRec.Name))or(pos('.mkv', SearchRec.Name))or(pos('.VOB', SearchRec.Name)) or
(pos('.ogm', SearchRec.Name))or(pos('.mp4', SearchRec.Name)) <> 0 then inc(vcount);
if (pos('.avi', SearchRec.Name) <> 0) ...все-таки я бы записал:
if UpperCase(ExtractFileExt(SearchRec.Name)) = 'AVI', мало ли, будет записано в другом регистре и все, не найдутся файлы...
kr3v3tkus, извини, не мог пройти мимо твоего кода. Там есть небольшая проблема с обходом директорий... Смотри, как можно это сделать чуть-чуть по-другому (постараюсь прокомментировать, если что непонятно - спрашивай...):
type
T = (_avi, _mkv, _vob, _ogm, _mp4); // все доступные типы видео-файлов
setT = set of T; // это - для отображения типов, присутствующих в отдельной папке
TRecs = record // информация о папке - путь к ней, число видео-файлов, и их типы
path: string;
count: integer;
types: setT;
end;
// это - строковое представление типов видеофайлов - их расширения...
const
strT: array[T] of string = (
'.avi', '.mkv', '.vob', '.ogm', '.mp4'
);
// дин. массив для хранения информации о папках
var
arr: array of TRecs;
// А вот тут - самое интересное: добавляем в массив новый фолдер
procedure MyAddFolderToContainer(the_path: string);
begin
SetLength(arr, Length(arr) + 1);
with arr[Length(arr) - 1] do begin
path := the_path;
count := 0;
types := [];
end;
end;
// добавляем новый файл
procedure MyAddFileToContainer(path: string);
var
ext: string;
iT: T;
i: integer;
the_set: setT;
begin
// сначала находим индекс элемента с нужным path-ом к нему
for i := 0 to Pred(Length(arr)) do begin
if LowerCase(ExtractFilePath(path)) = LowerCase(arr[i].path)
then break;
end;
// затем проверяем, к какому типу относится файл
ext := LowerCase(ExtractFileExt(path));
for iT := Low(T) to High(T) do
if strT[iT] = ext then begin
Include(the_set, iT); break;
end;
// и если это видео (если бы было НЕ видео, то the_set был бы пустым),
// то изменяем статистику. Ну, и дополнительные действия тоже можешь
// делать здесь, я только вывожу информацию о папках и количестве файлов в них
if the_set <> [] then begin
inc(arr[i].count);
arr[i].types := arr[i].types + the_set;
end;
end;
// ну, и собственно - рекурсия, которая осуществляет проход по всем директориям...
procedure MyAddFolderToGrid(path: string);
var SearchRec: TSearchRec;
begin
MyAddFolderToContainer(IncludeTrailingPathDelimiter(path + SearchRec.name));
if FindFirst(path + '*.*', faAnyFile, SearchRec) = 0 then
repeat
if (SearchRec.Name = '.') or (SearchRec.Name = '..') then continue;
if (SearchRec.Attr and faDirectory) <> 0 then begin // нашли папку - добавляем ее в контейнер
MyAddFolderToGrid(IncludeTrailingPathDelimiter(path + SearchRec.name));
end
else begin // нашли файл - добавляем файл
MyAddFileToContainer(path + SearchRec.name);
end;
until FindNext(SearchRec) <> 0;
end;
procedure TForm1.StartClick(Sender: TObject);
var
i: integer;
iT: T;
begin
SetLength(arr, 0);
// теперь здесь: по нажатию кнопки заполняем контейнер информацией
MyAddFolderToGrid(IncludeTrailingPathDelimiter(Shell.SelectedFolder.PathName));
// здесь можно отсортировать контейнер по любому полю, сделать все что нужно
// ...
// а потом - выводим информацию в грид
for i := 0 to pred(Length(arr)) do begin
with arr[i] do begin
StringGrid1.Cells[1, StringGrid1.FixedRows + i] := path;
StringGrid1.Cells[2, StringGrid1.FixedRows + i] := IntToStr(count);
for iT := Low(T) to High(T) do begin
if iT in types then begin
StringGrid1.Cells[3, StringGrid1.FixedRows + i] :=
StringGrid1.Cells[3, StringGrid1.FixedRows + i] + strT[iT];
end;
end;
end;
end;
SetLength(arr, 0);
end;
Просто привычка, можешь без нижнего подчеркивания делать. Главное - чтобы имя не повторяло никаких зарезервированных слов и идентификаторов, а с подчеркиванием вероятность этого значительно уменьшается.
блиин вольв а мыж тут каждый раз обнуляем SetLength(arr, 0); а вдруг нужно посчитать в разных папках? если не обнулять то косяки получаются
я имею ввиду: выбираем папку. делаем StartClick, вдруг надо на другом диске ещё папку обойти - мы снова делаем StartClick и тут получается что заново заполняются count и types
ну вот у меня он на первый взгляд если по папке добавлять то ко всем types нижних элементов ещё свои прикручивает =\ просто тады поставлю обнуление types на новые файлы
зы хмм ток чёт немогу понять где -___-
просто вот так получаеца если по папке добавлять
procedure TForm1.StartClick(Sender: TObject);Ну, и процедуры стали методами класса формы:
var
i: integer;
iT: T;
begin
// SetLength(arr, 0); - перенесено в FormCreate()
MyAddFolderToGrid(IncludeTrailingPathDelimiter(Shell.SelectedFolder.PathName));
for i := 0 to pred(Length(arr)) do begin
with arr[i] do begin
StringGrid1.Cells[1, StringGrid1.FixedRows + i] := path;
StringGrid1.Cells[2, StringGrid1.FixedRows + i] := IntToStr(count);
StringGrid1.Cells[3, StringGrid1.FixedRows + i] := ''; // <--- Вот это добавлено
for iT := Low(T) to High(T) do begin
if iT in types then begin
StringGrid1.Cells[3, StringGrid1.FixedRows + i] :=
StringGrid1.Cells[3, StringGrid1.FixedRows + i] + strT[iT];
end;
end;
end;
end;
// SetLength(arr, 0); - перенесено в FormDestroy()
end;
...
private
{ Private declarations }
arr: array of TRecs;
procedure MyAddFolderToContainer(the_path: string);
procedure MyAddFileToContainer(path: string);
procedure MyAddFolderToGrid(path: string);
...
блин сори туплю - перенёс я в Private их и он не хочет( пишет
Ну, перенести-то заголовки перенес, а изменить в реализации:
procedure TForm1.MyAddFolderToGrid(path: string); // <---
...
*окончательно чуствует себя идиотом и уползает под кровать* сенк
можно последний вопрос?
вот если в папке нет файлов - вот сюда вставить проверку?
Я что, просто так сказал
// теперь здесь: по нажатию кнопки заполняем контейнер информацией
MyAddFolderToGrid(IncludeTrailingPathDelimiter(Shell.SelectedFolder.PathName));
// здесь можно отсортировать контейнер по любому полю, сделать все что нужно
// ...