Piszę moduł odpowiedzialny za sprawdzenie, czy w danym katalogu (i jego podkatalogach) są inne katalogi i pliki.
Moduł pisany jest w środowisku Borland C++ Builder 6.
Wyniki są wypisywane w tabeli StringGrid1. Dalsze szczegóły o założeniach modułu opisuję niżej.
Program oparłem na funkcji napisanej przez Cyfrowego Barona o nazwie: FindDir.
Funkcja FindDir (ta oryginalna) posiada w pewnej wersji algorytm rekurencji, który umożliwia właśnie operację o którą mi chodzi, tzn. wypisanie wszystkich podkatalogów (i plików) a nie tylko tych podkatalogów z katalogu podanego w szukanej ścieżce (pole Edit1).
Odpowiednikiem funkcji FindDir w mojej aplikacji jest funkcja ScanDir, której jednak nie udaje mi się napisać w taki sposób, aby stosowała algorytm rekurencyjny z założeniami jakie ma spełniać mój moduł.
Zanim napiszę o założeniach modułu pozwólcie, że opiszę tabelę StringGrid1.
Tabela StringGrid1 w moim module posiada 5 kolumn. Idąc od lewej do prawej, są to:
- liczba porządkowa ("L.p."),
- nazwa skanowanego obecnie katalogu ("Skanowany katalog" - uwaga! to nie jest sr.Name),
- informacja czy wewnątrz skanowanego katalogu są podkatalogi ("Są w nim katalogi?"),
- informacja czy wewnątrz skanowanego katalogu są pliki ("Są w nim pliki?"),
- "Ścieżka do skanowanego katalogu"
Dane do tabeli są wczytywane ze struktury info - zdefiniowanej i zadeklarowanej na początku modułu Unit1.cpp
Do tej struktury trafiają dane pochodzące z cyklicznego przeglądania zawartości katalogu, którego nazwa wraz ze ścieżką dostępu została wpisana do pola edycyjnego Edit1.
Założenia modułu skanowania:
1. Moduł ma umożliwić wypisanie wszystkich podkatalogów i plików, z każdego jednego podkatalogu względem tego katalogu wpisanego w polu edycyjnym Edit1
2. Moduł ma wyświetlać w 3-ciej (licząc od 1) kolumnie czy w katalogu, który jest obecnie przeglądany (listingowany?-może to lepsze słowo) jest katalog, a w 4-tej kolumnie czy jest plik. Nazwa zarówno katalogu, czy to pliku nie ma być wyświetlana. Ma być jedynie informacja czy są jakieś katalogi lub/i pliki (algorytm dobrnął do końca gałęzi drzewa danego podkatalogu).
Mam problem z umiejscowieniem rekurencyjnego wywołania funkcji ScanDir (w ciele jej samej-wiadomo)...
Próbowałem już wielu sposobów i coś robię nie tak! Za nic nie mogę wpaść co robię nie tak... - Pomóżcie!!! Proszę!!!
Oto mój kod pliku nagłówkowego - Unit1.h:
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TPanel *Panel1;
TButton *Button1;
TStringGrid *StringGrid1;
TEdit *Edit1;
TLabel *Label1;
TLabel *Label2;
TButton *Button2;
void __fastcall Button1Click(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall WypiszNaglowekTabeli(TStringGrid *StringGrid1);
void __fastcall WypelnijTabele(TStringGrid *StringGrid1, String Dir);
void __fastcall ScanDir(TStringGrid *StringGrid1, String Dir);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Oto mój kod pliku źródłowego - Unit1.cpp:
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
struct info_str
{
String skan_dir;
String is_dirs_inside;
String is_files_inside;
String path_2_skan_dir;
};
info_str info;
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WypiszNaglowekTabeli(TStringGrid *StringGrid1)
{
StringGrid1->Cells[0][0]="L.p.";
StringGrid1->Cells[1][0]="Skanowany katalog";
StringGrid1->Cells[2][0]="Są w nim katalogi?";
StringGrid1->Cells[3][0]="Są w nim pliki?";
StringGrid1->Cells[4][0]="Ścieżka do skanowanego katalogu";
// StringGrid1->FixedRows=1;
}
void __fastcall TForm1::WypelnijTabele(TStringGrid *StringGrid1, String Dir)
{
StringGrid1->RowCount = StringGrid1->RowCount + 1;
StringGrid1->Cells[0][StringGrid1->RowCount-1] = StringGrid1->RowCount-1;
StringGrid1->Cells[1][StringGrid1->RowCount-1] = info.skan_dir;
StringGrid1->Cells[2][StringGrid1->RowCount-1] = info.is_dirs_inside;
StringGrid1->Cells[3][StringGrid1->RowCount-1] = info.is_files_inside;
if (Dir.Length()>0 && Dir.Length()<=6)
{
/* gdyby skanowany był cały dysk np. C:\ */
info.path_2_skan_dir=ExtractFileDir(Dir);
}
else
{
info.path_2_skan_dir=ExtractFileDir(Dir)+"\\";
}
info.is_files_inside="brak plików";
info.is_dirs_inside="brak katalogów";
}
void __fastcall TForm1::ScanDir(TStringGrid *StringGrid1, String Dir)
{
TSearchRec sr;
// StringGrid1->RowCount = 1; // niech nie zaczyna od nagłówka! tylko od następnego wiersza
Dir=Dir+"*.*";
if (FindFirst(Dir, faAnyFile, sr) == 0)
{
do
{
if (sr.Name!="." && sr.Name!="..")
{
// info.skan_dir=ExtractFileDir(Dir);
info.skan_dir=ExtractFileName(info.skan_dir);
if ((sr.Attr & faArchive) == sr.Attr)
{
info.is_files_inside="pliki są";
}
if ((sr.Attr & faDirectory) == sr.Attr)
{
info.is_dirs_inside="katalogi są";
}
}
} // do while
while (FindNext(sr) == 0);
// ScanDir(StringGrid1, Dir);
WypelnijTabele(StringGrid1, Dir);
// StringGrid1->RowCount=StringGrid1->RowCount +1;
StringGrid1->RowCount++;
FindClose(sr);
}
else
{
// nie wiem jaki sensowny komunikat
// tutaj umieścić... :/
ShowMessage("FindFirst(Dir, faAnyFile, sr) != 0");
}
WypiszNaglowekTabeli(StringGrid1);
// StringGrid1->FixedRows=1;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
for (int y=0; y<StringGrid1->RowCount; y++)
{
StringGrid1->Rows[y]->Clear();
}
StringGrid1->RowCount=0;
ScanDir(StringGrid1, Edit1->Text);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Edit1->Text="C:\\";
WypiszNaglowekTabeli(StringGrid1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Application->Terminate();
}
Naprawdę bardzo mocno proszę! - POMÓŻCIE!!!
Pozdrawiam! samurai-jerry
P.S. W załączniku wysyłam kod źrodłowy + plik.exe
P.S.2. Piszę post tutaj (Bazy danych), ponieważ w dalszych założeniach moduł ten ma realizować założenia bazy danych.