Логотип
Vicking.narod.ru
Программирование
Исходные тексты и утилиты

Пишем компонент для поиска файлов


Гостевая книга
 
 


Часто приходится в своих программах использовать поиск файлов. Применять каждый раз функции FindFirst, FindNext и FindClose порой неудобно. Для это решил создать компонент, который будет вызывать их вместо меня. И так приступим.

Раз это компонент, то он должен все наследовать от класса TComponent. Создаем новый компонент, выбрав в среде команду Component >> New Component... Указав наследуемый класс и название нашего компонента, создаем модуль.

Теперь надо определиться, какие свойства, методы и события будут у компонента. Во-первых, нужно указать где и что искать. Для этого понадобятся два свойства типа strings, которые будут хранить путь для поиска и маску поиска:

  property Root: string read FRoot write FRoot;
property Mask: string read FMask write FMask;

Для использования масок подключим модуль Masks. Хотя применение регулярных выражение оказывает большее быстродействие, но в нашем случае это не сыграет никакой роли. Теперь создадим объект маски:

type
  TFileSearch = class(TComponent)
  private
    FRoot: string;
    FMask: string;
    FMskObj: TMask;  // объект маски
  public
    destructor Destroy; override;  // перегружаем деструктор
    constructor Create(AOwner: TComponent); override; // и конструктор
  published
    property Root: string read FRoot write FRoot;
    property Mask: string read FMask write FMask;
  end;

Деструктор перегружаем для того, чтобы удалить маску при удалении компонента. А в конструкторе инициализируем все свойства. Нам потребуется свойство Active для запуска поиска, событие, наступающее в момент нахождения файла, и сам метод поиска. Через свойство Active мы можем не только запускать поиск, но и останавливать его. Теперь наш класс будет выглядеть следующим образом:

type
  TFindFileEvent = procedure (FullFileName: string; SearchRec: TSearchRec) of object;

type
  TFileSearch = class(TComponent)
  private
    FActive: Boolean;
    FRoot: string;
    FOnFindFile: TFindFileEvent;
    FMask: string;
    FMskObj: TMask;
    procedure SetActive(const Value: Boolean);
  protected
    Procedure FindFiles(Path: string);
  public
    property Active: Boolean read FActive write SetActive;
    destructor Destroy; override;
    constructor Create(AOwner: TComponent); override;
  published
    property Root: string read FRoot write FRoot;
    property OnFindFile: TFindFileEvent read FOnFindFile write FOnFindFile;
    property Mask: string read FMask write FMask;
  end;

Метод FindFiles объявлен в секции protected на случай, если мы захотим перегрузить его. Свойство Active объявляем в секции public для того, чтобы оно не было доступно в инспекторе объектов. Теперь перейдем к реализации методов и начнем с метода Create:

constructor TFileSearch.Create(AOwner: TComponent);
begin
  inherited;
  // инициализируем свойства
  Root := ExtractFileDir(Application.ExeName);
  Mask := '*.*';
  FActive := False;
  FMskObj := nil;
end;

Затем перейдем к методу FindFiles, в котором мы и применим функции FindFirst, FindNext и FindClose.

procedure TFileSearch.FindFiles(Path: string);
var
  sr: TSearchRec;
begin
  if not Active then Exit;  //Завершаем поиск, если не активен
  // ищем первый файл
  if FindFirst(Path+'\*.*',faAnyFile,sr) = 0 then
  begin
    repeat
    if not Active then Exit;
    if sr.Name = '.' then Continue;  // если это этаже папка
    if sr.Name = '..' then Continue; // или родительская, то пропускаем
    
    // Если файл соответствует маске, то генерируем событие
    if FMskObj.Matches(AnsiUpperCase(sr.Name)) then
      if Assigned(FOnFindFile)  then FOnFindFile(Path+'\'+sr.Name,sr);
    if (sr.Attr and faDirectory)<>0  then FindFiles(Path+'\'+sr.Name);
    until FindNext(sr) <> 0 // ищем следующий файл
  end;
  FindClose(sr);   // закрываем поиск
  FActive := false;  // и останавливаем его
end;

Реализуем метод для установки свойства Active:

procedure TFileSearch.SetActive(const Value: Boolean);
begin
  FActive := Value;
  if Active then
  begin
    // удаляем старую маску и создаем новую
    if FMskObj <> nil then FMskObj.Free;
    FMskObj := TMask.Create(AnsiUpperCase(Mask));
    FindFiles(Root); // поиск
  end;

end;

И последний метод - деструктор Destroy:

destructor TFileSearch.Destroy;
begin
  // удаляем маску
  if FMskObj <> nil then FMskObj.Free;
  inherited;
end;

Теперь рассмотрим событие OnFindFile.

Аргумент
Описание
FullFileName Содержит полный путь к найденному файлу
SearchRec Вся информация о найденном файле.

Теперь осталось компонент инсталлировать и использовать. Хочу надеяться, что выше изложенный материал кому-нибудь поможет.


© Зинкевич Виктор, 2005 г.

 



Hosted by uCoz