unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, StdCtrls, shellapi;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    ListView1: TListView;
    procedure FormShow(Sender: TObject);
    procedure ListView1DblClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    function AddFile(FileMask: string; FFileAttr:DWORD): Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  function SlashSep(Path, FName: string): string;
  function FileTimeToDateTimeStr(FileTime: TFileTime): string;

implementation

{$R *.DFM}

//Эта процедура проверяет наличие в конце пути к файлу значка '\'.
//Если этого значка нет, то он добавляется.
function SlashSep(Path, FName: string): string;
begin
 if Path[Length(Path)] <> '\' then
  Result := Path + '\' + FName
 else Result := Path + FName;
end;

//Функция переводит время и дату из формата TFileTime в
//формат понятный челувеку.
function FileTimeToDateTimeStr(FileTime: TFileTime): string;
var
 LocFTime: TFileTime;
 SysFTime: TSystemTime;
 DateStr: string;
 TimeStr: string;
 FDateTimeStr: string;
 Dt, Tm: TDateTime;
begin
 FileTimeToLocalFileTime(FileTime, LocFTime);
 FileTimeToSystemTime(LocFTime, SysFTime);
 try
  with SysFTime do
   begin
    Dt := EncodeDate(wYear, wMonth, wDay);
    DateStr := DateToStr(Dt);
    Tm := EncodeTime(wHour, wMinute, wSecond, wMilliseconds);
    Timestr := TimeToStr(Tm);
    FDateTimeStr := DateStr + '   ' + TimeStr;
   end;
  Result := DateTimeToStr(StrToDateTime(FDateTimeStr));
 except
  Result := '';
 end;
end;

function TForm1.AddFile(FileMask: string; FFileAttr:DWORD): Boolean;
var
 ShInfo: TSHFileInfo;
 attributes: string;
 FileName: string;
 hFindFile: THandle;
 SearchRec: TSearchRec;

 function AttrStr(Attr: integer): string;
  begin
   Result := '';
   if (FILE_ATTRIBUTE_DIRECTORY and Attr) > 0 then Result := Result + '';
   if (FILE_ATTRIBUTE_ARCHIVE and Attr) > 0 then Result := Result + 'A';
   if (FILE_ATTRIBUTE_READONLY and Attr) > 0 then Result := Result + 'R';
   if (FILE_ATTRIBUTE_HIDDEN and Attr) > 0 then Result := Result + 'H';
   if (FILE_ATTRIBUTE_SYSTEM and Attr) > 0 then Result := Result + 'S';
  end;

begin
 ListView1.Items.BeginUpdate;
 ListView1.Items.Clear;

 Result := False;
 hFindFile := FindFirst(FileMask, FFileAttr, SearchRec);
 if hFindFile <> INVALID_HANDLE_VALUE then
  try
   repeat
    with SearchRec.FindData do
     begin

      if (SearchRec.Name = '.') or (SearchRec.Name = '..') or
      (SearchRec.Name = '') then continue;

      FileName := SlashSep(Edit1.Text, SearchRec.Name);
      SHGetFileInfo(PChar(FileName), 0, ShInfo, SizeOf(ShInfo),
                      SHGFI_TYPENAME or SHGFI_SYSICONINDEX);
      Attributes := AttrStr(dwFileAttributes);
      //Добавляю новый элемент
      with ListView1.Items.Add do
       begin
        //Присваиваю его имя
        Caption := SearchRec.Name;
        //Присваиваю индекс из системного списка изображений
        ImageIndex := ShInfo.iIcon;
        //Присваиваю размер
        SubItems.Add(IntToStr(SearchRec.Size));
        SubItems.Add((ShInfo.szTypeName));
        SubItems.Add(FileTimeToDateTimeStr(ftLastWriteTime));
        SubItems.Add(attributes);
        SubItems.Add(Edit1.Text + cFileName);
        if (FILE_ATTRIBUTE_DIRECTORY and dwFileAttributes) > 0 then
         SubItems.Add('dir')
        else
         SubItems.Add('file');
       end;
      Result := True;
     end;
    until (FindNext(SearchRec) <> 0);
   finally
    FindClose(SearchRec);
   end;
 ListView1.Items.EndUpdate;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 AddFile(Edit1.Text+'*.*',faAnyFile)
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
begin
//Это директория?
 if (ListView1.Selected.SubItems[5] = 'dir') then
  begin
//Если да, то прибавить имя выделенной директории к пути
//и перечитать файлы из неё.   
   Edit1.Text:=Edit1.Text+ListView1.Selected.Caption+'\';
   AddFile(Edit1.Text+'*.*',faAnyFile)
  end
 else
//Если нет, то это файл и я его запускаю.
  ShellExecute(Application.MainForm.Handle, nil,
      PChar(Edit1.Text+ListView1.Selected.Caption), '',
      PChar(Edit1.Text), SW_SHOW);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Edit1.Text := Copy(Edit1.Text, 1, Length(Edit1.Text) - 1);
 Edit1.Text := ExtractFilePath(Edit1.Text);
 AddFile(Edit1.Text+'*.*',faAnyFile);

end;

procedure TForm1.FormCreate(Sender: TObject);
var
 SysImageList: uint;
 SFI: TSHFileInfo;
begin
 //Создаю списки маленьких и больших иконок.
 ListView1.LargeImages:=TImageList.Create(self);
 ListView1.SmallImages:=TImageList.Create(self);

//Запрашиваю большие иконки
 SysImageList := SHGetFileInfo('', 0, SFI,
 SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
 if SysImageList <> 0 then
  begin
//Присваиваю системные иконки в ListView1
   ListView1.Largeimages.Handle := SysImageList;
   ListView1.Largeimages.ShareImages := TRUE;
  end;
//Запрашиваю маленькие иконки
 SysImageList := SHGetFileInfo('', 0, SFI, SizeOf(TSHFileInfo),
    SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
 if SysImageList <> 0 then
  begin
   ListView1.Smallimages.Handle := SysImageList;
   ListView1.Smallimages.ShareImages := TRUE;
  end;
end;

end.
