unit FileDetailsStringGrid;

interface

uses
  SysUtils, Classes, Controls, Grids, Windows;

type
  TFileDetailsStringGrid = class(TCustomDrawGrid)
  private
    Cells :array of array of String;
    FDirectory :String;
    FMask :String;
    FileInfoList :array of TSearchRec;
    procedure ZapelnijSiatke;
    procedure UstalIloscWierszy(ARows :LongInt);
    function GetFilename :String;
    procedure SetDirectory(ADirectory :String);
    procedure SetMask(AMask :String);
  protected
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
  AState: TGridDrawState); override;
  public
    constructor Create(AOwner :TComponent); overload; override;
    constructor Create(AOwner :TComponent; ADirectory,AMask :String); overload;
    procedure Repaint; override;
    function GetFileDetails(ARow :LongInt) :TSearchRec;

    //upublicznianie wlasnosci
    property ColWidths;
    property RowHeights;
    property TabStops;

  published
    property Directory :String read FDirectory write SetDirectory;
    property Mask :String read FMask write SetMask;
    property Filename :String read GetFilename;

    //publikowanie wlasnosci
    property BorderStyle;
    property Col;
    property ColCount;
    property DefaultColWidth;
    property Row;
    property RowCount;
    property DefaultRowHeight;
    property DefaultDrawing;
    property FixedColor;
    property GridHeight;
    property GridWidth;
    property LeftCol;
    property TopRow;
    property VisibleRowCount;
    property VisibleColCount;
    property HitTest;
    property ScrollBars;
    property Selection;
  end;

procedure Register;

implementation

//umieszczanie tekstu w komórce siatki
procedure TFileDetailsStringGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
begin
if DefaultDrawing then
  Canvas.TextRect(ARect, ARect.Left+2, ARect.Top+2, Cells[ACol, ARow]);

inherited DrawCell(ACol, ARow, ARect, AState);
end;

procedure TFileDetailsStringGrid.UstalIloscWierszy(ARows :LongInt);
var i :LongInt;
begin
RowCount:=ARows;
SetLength(Cells,ColCount);
for i:=0 to ColCount-1 do SetLength(Cells[i],RowCount);
end;

constructor TFileDetailsStringGrid.Create(AOwner: TComponent);
const SZER=100;
begin
inherited Create(AOwner);

ColWidths[0]:=2*SZER;
ColWidths[1]:=2*SZER;
ColWidths[2]:=SZER;
ColWidths[3]:=2*SZER;

Options:=[goFixedVertLine,goFixedHorzLine,{goVertLine,}goHorzLine,
          goColSizing,goDrawFocusSelected,goColMoving,goRowSelect,goThumbTracking];

FMask:='*.*';
FDirectory:='.';

ColCount:=4;
FixedCols:=0;
FixedRows:=1;
UstalIloscWierszy(2);

//To powinno być w odpowiednim języku
Cells[0,0]:='Nazwa pliku';
Cells[1,0]:='Nazwa pliku (8.3)';
Cells[2,0]:='Rozmiar';
Cells[3,0]:='Data ostatniej modyfikacji';

ZapelnijSiatke;
end;

procedure TFileDetailsStringGrid.ZapelnijSiatke;
var
  sr :TSearchRec;
  wynik :Integer;
  numerWiersza,i :LongInt;
begin
numerWiersza:=0;
wynik:=FindFirst(FDirectory+'\'+FMask, faAnyFile and not faDirectory, sr);
if wynik<>0 then
  begin
  SetLength(FileInfoList,0);
  UstalIloscWierszy(2);
  for i:=0 to ColCount-1 do Cells[i,1]:='';
  SysUtils.FindClose(sr);
  Exit;
  end;

while wynik=0 do
  begin
  SetLength(FileInfoList,numerWiersza+1);
  FileInfoList[numerWiersza]:=sr;
  wynik:=FindNext(sr);
  if wynik=0 then Inc(numerWiersza);
  end;

UstalIloscWierszy(numerWiersza+2);
for numerWiersza:=0 to Length(FileInfoList)-1 do
  begin
  with FileInfoList[numerWiersza] do
    begin
    Cells[0,numerWiersza+1]:=Name;
    Cells[1,numerWiersza+1]:=FindData.cAlternateFileName;
    Cells[2,numerWiersza+1]:=IntToStr(Size);
    Cells[3,numerWiersza+1]:=DateTimeToStr(FileDateToDateTime(Time))
    end;
  end;

SysUtils.FindClose(sr);
end;

procedure TFileDetailsStringGrid.Repaint;
begin
ZapelnijSiatke;
inherited;
end;

function TFileDetailsStringGrid.GetFilename :String;
begin
if Length(FileInfoList)<=Row-FixedRows then Exit; //gdy pusta siatka
Result:=ExpandFileName(FileInfoList[Row-FixedRows].Name);
end;

function TFileDetailsStringGrid.GetFileDetails(ARow :LongInt) :TSearchRec;
begin
//argument to wiersz w siatce, a nie numer elementu tabeli
if (ARow<=FixedRows) or (ARow>=RowCount) then Exit;
if Length(FileInfoList)<=ARow-FixedRows then Exit; //gdy pusta siatka
Result:=FileInfoList[ARow-FixedRows];
end;

procedure TFileDetailsStringGrid.SetDirectory(ADirectory :String);
var dlg :Integer;
begin
//moze byc ., .., c:; pusty = .
//usuwanie \ z konca
dlg:=Length(ADirectory);
if dlg=0 then ADirectory:='.';
if ADirectory[dlg]='\' then SetLength(ADirectory,dlg-1);
FDirectory:=ADirectory;
Refresh;
end;

procedure TFileDetailsStringGrid.SetMask(AMask :String);
begin
FMask:=AMask;
Refresh;
end;

constructor TFileDetailsStringGrid.Create(AOwner :TComponent; ADirectory,AMask :String);
begin
Create(AOwner);
SetDirectory(ADirectory);
SetMask(AMask);
end;

procedure Register;
begin
  RegisterComponents('JM', [TFileDetailsStringGrid]);
end;

end.
