VCL - pierwsze kroki


Trochę o metodach

Do działania komponentu potrzebne jest jeszcze dodanie metody, której wywołanie uruchomi wykonywanie czynności określonych za pomocą omówionych wcześniej właściwości. Metodę tę nazwiemy Execute() i umieścimy w obszarze public, żeby była dostępna na zewnątrz komponentu. Metoda Execute() najpierw sprawdzi, jaką wybraliśmy operację, a następnie wywoła odpowiednią funkcję do jej wykonania. Ponieważ zdecydowaliśmy, że rodzaje operacji są typu wyliczeniowego, możemy teraz swobodnie korzystać z instrukcji warunkowej switch(). Oto ciało metody Execute():

void __fastcall TFilesExplorer::Execute(void)

{

switch (Operacja)

{

case 0:

Przeszukuj();

break;

case 1:

// kod do tworzenia katalogów lub plików

for(int i=0;i<ListaWejsciowa->Count;i++)

if(ExtractFileExt(ListaWejsciowa->

Strings[i])=="")

{

if(ForceDirectories(ListaWejsciowa->

Strings[i])) ListaWyjsciowa->

Add(ListaWejsciowa->Strings[i]);

}

else

{

if(FileCreate(ListaWejsciowa->

Strings[i])) ListaWyjsciowa->

Add(ListaWejsciowa->Strings[i]);

}

break;

case 2:

WykonajOperacje(FO_RENAME);

break;

case 3:

WykonajOperacje(FO_COPY);

break;

case 4:

WykonajOperacje(FO_MOVE);

break;

case 5:

WykonajOperacje(FO_DELETE);

break;

}

}

Powyżej widać, że zastosowaliśmy różne podejście do wykonywania poszczególnych operacji. Dla operacji przeszukiwania przygotowaliśmy oddzielną metodę Przeszukuj(), tworzenie plików i katalogów ze względu na swą prostotę zostało umieszczone bezpośrednio przy etykiecie case. Natomiast pozostałe operacje, których wywołanie różni się tylko zmianą parametru przekazywanego do struktury SHFILEOPSTRUCT, są wywoływane przez metodę WykonajOperację(rodzaj) z parametrem mówiącym o rodzaju czynności do wykonania.

Metoda Przeszukuj() ma za zadanie wyszukać pliki lub katalogi w lokalizacji podanej w ListaWej. Wyszukiwanie musi być wykonane dla każdej pozycji listy, ale nie należy zapominać, że operacja ta może obejmować również podkatalogi. Z tego powodu musimy zadeklarować kolejną metodę, która może sama się wywołać rekurencyjnie. Nie jest to, oczywiście, jedyne rozwiązanie, ale jest stosunkowo najprostsze. Wszystkie odnalezione pliki i katalogi zostaną umieszczone na liście ListaWyj. Oto metoda Przeszukuj:

void __fastcall TFilesExplorer::Przeszukuj(void)

{

for(int i=0;i<ListaWejsciowa->Count;i++)

PrzeszukajKatalog(ListaWejsciowa->Strings[i]);

};

Jak widać, metoda Przeszukuj wywoła funkcję PrzeszukajKatalog(element listy) dla każdego elementu listy. Natomiast metoda PrzeszukajKatalog musi w pierwszej kolejności wyszukać wszystkie podkatalogi danego katalogu i ponownie wywołać się rekurencyjnie dla każdego z nich. Dopiero wtedy może rozpocząć poszukiwanie elementu zgodnego z podaną maską. W ten sposób najpierw zostaną przeszukane najgłębsze podkatalogi, a dopiero potem płytsze. Drugie zadanie może być realizowane na wiele sposobów. Jeden z nich przedstawiamy poniżej:

void __fastcall TFilesExplorer::

PrzeszukajKatalog(AnsiString nazwa)

{

WIN32_FIND_DATA s;

if(o->PrzeszukujKatalogi)

{

AnsiString adres=ExtractFilePath(nazwa)+"*";

HANDLE uchwyt=FindFirstFile(adres.c_str(),&s);

while(FindNextFile(uchwyt,&s))

if(AnsiString(s.cFileName)!="..")

if((s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)>0)

PrzeszukajKatalog(ExtractFilePath(nazwa)+s.cFileName+"\\"+ExtractFileName(nazwa));

FindClose(uchwyt);

}

HANDLE uchwyt=FindFirstFile(nazwa.c_str(),&s);

while(FindNextFile(uchwyt,&s))

if(AnsiString(s.cFileName)!="..")

ListaWyjsciowa->Add(ExtractFilePath(nazwa)+s.cFileName);

FindClose(uchwyt);

};

VCL - pierwsze kroki

Instalacja komponentu w środowisku C++Builder.

Utworzona wcześniej klasa opcje ma pole PrzeszukujKatalogi, w którym przechowywana jest informacja o zgodzie na przeszukiwanie katalogów. Pierwszą czynnością jest właśnie sprawdzenie tego pola. Następnie z podanej lokalizacji wyodrębniamy ścieżkę do katalogu, od którego mamy zacząć poszukiwanie i podajemy maskę "*" informującą, że interesują nas wszystkie elementy. Kolejne etapy to zdobycie uchwytu do szukanych elementów za pomocą funkcji FindFirstFile(adres) i rozpoczęcie szukania ze sprawdzaniem, czy znaleziony element to katalog. Jeżeli tak, to funkcja wywołuje samą siebie, zmieniając tylko lokalizację poszukiwań według następującego schematu:

ExtractFilePath(nazwa) + s.cFileName + "\\" + ExtractFileName(nazwa)

Do pierwszego członu, który wyodrębnia obecny adres, dodawany jest znaleziony katalog oraz maska obiektu do szukania. Następnie w funkcji PrzeszukajKatalog uwalniamy uchwyt i wyszukujemy pliki podane w masce zgodnie z poznanym właśnie schematem.

Drugi człon instrukcji case metody Execute klasy TFilesExplorer odpowiada za tworzenie plików i katalogów. Aby uprościć kod przyjęliśmy następujące założenie. Jeżeli nazwa obiektu do utworzenia ma rozszerzenie to znaczy, że obiekt ma być plikiem, w przeciwnym wypadku - katalogiem. W efekcie nasz komponent nie pozwala utworzyć katalogu z rozszerzeniem. Aby usunąć to ograniczenie, wystarczy rozszerzyć listę dozwolonych operacji i napisać dwa oddzielne bloki kodu - jeden do tworzenia katalogów i drugi do plików. Do tworzenia plików używamy funkcji FileCreate, a do katalogów ForceDirectories. W przypadku tej ostatniej trzeba uważać, żeby nie podać jako parametru pustego argumentu. Przekazanie pustego ciągu znakowego spowoduje wygenerowanie wyjątku, który trzeba obsłużyć. Po każdej pomyślnej operacji tworzenia pliku lub katalogu ich nazwy są dopisywane do listy ListaWyj. Dzięki temu zawsze mamy pełny obraz efektów działania operacji.

Na tym zakończymy pierwszą część artykułu. Zostało nam jeszcze zaimplementowanie metody WykonajOperacje, a także dodanie kodu generującego zdarzenia. Za miesiąc dokończymy dzieło, wprowadzając do naszego komponentu również kilka dodatkowych usprawnień. Dla zainteresowanych kod gotowego komponentu dostępny jest już w miniportalu programistycznym PCWK_PROG na naszych płytach CD.