Cоздание списка файлов

Не так уж и часто, но бывает надо в программе получить список файлов или поддиректорий в каталоге. Для тех, кто использует KOL и MCK открываются аж 3 способа решения этой проблемы. Правда нормальный, по моему мнению, все-таки только один :) Рассмотрим все.

1-й способ. " Традиционный ."

Традиционно пользуются 3-мя API функциями: FindFirstFile (ищет первый файл из списка файлов), FindNextFile (ищет следующий файл) , FindClose (прекращение поиска). Обычно первые 2-е функции заменются их VCL-суррогатами FindFirst, FindNext. Для нас, они не совсем приемлемы, так как для того чтобы воспользоваться этими функциями, надо подключить библиотеку Sysutils. А это как известно добавляет лишний жирок в наши атлетически сложенные программы :-). Пример на чистом API с примесью KOL.
program Primer12;   
   
uses   
 windows,   
 messages,   
 kol;   
   
{$R *.RES}   
var   
 form:Pcontrol;   
 // ----- элементы интерфейса -----   
 List:PControl;   
 // -----------------------------  
 FindHandle : THandle;   
 FindData : TWin32FindData;   
 b:boolean;   
 s:string;   
begin   
 Applet:=NewApplet('Список файлов');   
 form:=NewForm(Applet,'Список файлов').SetSize(300,400);   
 form.CenterOnParent ;   
 List := NewListBox(form,[]).SetAlign(caClient);   
   
 // устанавливаем атрибуты файла   
 FindData.dwFileAttributes := FILE_ATTRIBUTE_NORMAL;   
 // ищем первый файл в каталоге C:\  
 FindHandle := FindFirstFile('C:\*.*',FindData);   
 // если все Ok, тогда продолжаем   
 if FindHandle <> INVALID_HANDLE_VALUE then   
 begin   
  b:=true;   
  while b do   
   begin   
    s:=FindData.cFileName;   
    // всякие точки и двоеточия нам не нужны   
    if (s<>'..') and (s<>'.') then   
       List.Add(s);   
    b:=FindNextFile(FindHandle,FindData);   
   end;   
 end;   
 FindClose(FindHandle);   
   
 run(Applet);   
end.

Пояснения на счет атрибутов для искомых файлов:
FILE_ATTRIBUTE_ARCHIVE - архивный файл.
FILE_ATTRIBUTE_COMPRESSED - сжатый файл или папка.
FILE_ATTRIBUTE_HIDDEN - скрытый файл.
FILE_ATTRIBUTE_NORMAL - обычный файл.
FILE_ATTRIBUTE_OFFLINE - данные файла недоступны. Указывает, что данные файлы были физически перемещены.
FILE_ATTRIBUTE_READONLY - файл только для чтения.
FILE_ATTRIBUTE_SYSTEM - системный файл.
FILE_ATTRIBUTE_TEMPORARY - временный файл.
FILE_ATTRIBUTE_DIRECTORY - директория

2-й способ. "В лоб."

Несмотря на простоту представленного кода эту операцию можно сделать еще проще т.к. ListBox сам может показать файлы в определенной директории. Для этого надо обратится к свойству AddDirList. Пример еще меньше.
program Primer12_2;   
   
uses   
 windows,   
 messages,   
 kol;   
   
{$R *.RES}   
var   
 form:Pcontrol;   
 // ----- элементы интерфейса -----   
 List:PControl;   
 // ------------------------------   
begin   
 Applet:=NewApplet('Список файлов');   
 form:=NewForm(Applet,'Список файлов').SetSize(300,400);   
 form.CenterOnParent ;   
 List := NewListbox(form,[]).SetAlign(caClient);   
 List.AddDirList('C:\*.*',FILE_ATTRIBUTE_NORMAL);   
 run(Ap   plet);   
end.

Это конечно интересный способ получать список файлов, но не функциональный :) Не создавать ведь на окне каждый раз ListBox или СomboBox (он тоже имеет это же свойство), чтобы получить список файлов. Да и почему-то выводимый список файлов в виде " коротких имен " (т.е. как будто в DOS). Скорее всего Владимир Кладов добавил это свойство как интересную фичу и не более.

3-й способ. " Как положено "

Ну и самое интересное :) В KOL есть объект предназначенный для создания списка фалов. Это PDirList. Вот его конструктор:

function NewDirList( const DirPath, Filter: String; Attr: DWORD ): PDirList;


DirPath - сканируемая директория
Filter - фильтр для файлов или каталогов
Attr - атрибуты

Пример. Наверху в окне находится список дисков. Ниже находится список файлов и подкаталогов, находящихся в центральных каталогах этих дисков.
program Primer12_3;   
   
uses   
 windows,   
 messages,   
 kol;   
   
{$R *.RES}   
var   
 form:Pcontrol;   
 // ----- элементы интерфейса -----   
 ListFile,   
 ListDrv:PControl;   
 // ------------------------------   
 FileL:pDirList;   
   
 i,j:integer;   
   
 DriveBits: set of 0..25;   
 DriveNum:integer;   
 DriveChar:char;   
   
///////////////////////////////////////////////////////////////////////////   
Procedure SelDrv ( Dummy : Pointer; Sender : PControl );   
var   
 s:string;   
begin   
s:= ListDrv.Text ;   
   
if FileL=nil then   
 FileL := NewDirList(s,'*.*',FILE_ATTRIBUTE_NORMAL)   
else   
 begin   
  FileL.Clear ;   
  FileL.ScanDirectory(s,'*.*',FILE_ATTRIBUTE_NORMAL);   
 end;   
 FileL.Sort([sdrByName]);    
   
 ListFile.Clear;   
 if FileL.Count > 0 then   
  for i:=0 to FileL.Count-1 do   
   ListFile.add(FileL.Names[i]);   
end;   
///////////////////////////////////////////////////////////////////////////   
begin   
 Applet:=NewApplet('Список файлов');   
 form:=NewForm(Applet,'Список файлов').SetSize(250,300);   
 form.CenterOnParent ;   
 Form.Font.FontName := 'MS Sans Serif';   
 Form.Font.FontHeight := 9;   
   
 //----------- "рисуем" интерфейс -----------------------   
 ListDrv := NewComboBox(form,[]).SetAlign(caTop);   
 ListFile := NewListbox(form,[]).SetAlign(caClient);   
 //------------------------------------------------------   
   
 Integer(DriveBits) := GetLogicalDrives; // получаем номера дисков   
 i:=0;   
 j:=0;   
   
 // узнаем список дисков   
 for DriveNum := 0 to 25 do   
  if DriveNum in DriveBits then   
   begin   
     DriveChar := Char(DriveNum + Ord('a'));   
     DriveChar := UpCase(DriveChar);   
     ListDrv.Add(DriveChar+':\');   
     if DriveChar='C' then j:=ListDrv.Count-1; // узнаем каким в очереди идет диск С:\   
   end;   
   
 ListDrv.CurIndex := j;   
 ListDrv.OnChange := TOnEvent( MakeMethod( nil, @SelDrv ) );   
 SelDrv(nil,nil); // показываем файлы на текущем диске   
 run(Applet);   
end.

Размер кода 1,8 Кб. Размер программы 34,5 Кб (без сжатия и замены модулей).
Теги:
Cоздание файлов
Добавлено: 31 Мая 2018 22:09:30 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...