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

Новая страница 1 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(Applet); 
end. 

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

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

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

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

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

Список методов и свойств для работы с этим обьектом:

Метод
Описание
procedure Clear; Очищает текущий список с файлами.
procedure ScanDirectory( const DirPath, Filter: String; Attr: DWord ); Сканирует директорию DirPath. Все передаваемые значения идентичны конструктору.
procedure Sort( Rules: array of TSortDirRules );

Сортировка списка файлов. Rules (условие сортировки) может быть следующим :

  • sdrNone - обойдемся без сортировки
  • sdrFoldersFirst - сначала идет каталог, а только затем файл.
  • sdrCaseSensitive
  • sdrByName - по имени
  • sdrByExt - по расширению
  • sdrBySize - по размеру
  • sdrBySizeDescending
  • drByDateCreate - по дате создания
  • sdrByDateChanged - по дате изменения
  • sdrByDateAccessed -по дате доступа
Свойство
Описание
property Items[ Idx: Integer ]: PWin32FindData Получить доступ к структуре PWin32FindData для файла идущего под номером Idx. Подробности об PWin32FindData смотрите в Win32.hlp и в примере " стандартного " создания списка фалов
property IsDirectory[ Idx: Integer ]: Boolean; Возвращает true если запись под номером Idx в списке не является файлом.
property Count: Integer;

Возвращает количество пунктов в списке

property Names[ Idx: Integer ]: string; Возвращает полное имя файла (или каталога) находящимся в списке под номером Idx.
property Path: string; Путь текущей просканированной директории.

Пример. Наверху в окне находится список дисков. Ниже находится список файлов и подкаталогов, находящихся в центральных каталогах этих дисков.

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 Кб (без сжатия и замены модулей).

Источник: http://bonanzas.rinet.ru , http://kol.mastak.ru



Опубликовал admin
5 Май, Понедельник 2003г.



Программирование для чайников.