Dokładnie tak samo, czyli musisz przeszukiwać katalogi w poszukiwaniu konkretnego pliku. W linku do porady, który podałem w swoim poprzednim poście jest opisane jak wyszukiwać pliki po nazwie i rozszerzeniu. Najwyraźniej nie przejrzałeś tej porady. Chyba nie oczekujesz jakiegoś cudownego sposobu na poszukiwanie pliku?!
Przerobiłem ten kod tak by wyszukiwał pliki i był w na tyle funkcjonalny na ile chciało mi się to zrobić:
namespace SearchSection {
BOOL bOnlyRoz;
String sRoz, sName;
void FindFile(TStrings *SLista, String sDir, String sFileName, BOOL bSubFolder)
{
TSearchRec sr;
if(FindFirst(sDir + "*.*", faAnyFile, sr) == 0)
{
do
{
if( ((sr.Attr & faDirectory) > 0) && (sr.Name != ".") &&
(sr.Name != "..") && bSubFolder )
{
FindFile(SLista, sDir + sr.Name + "\\", sFileName, bSubFolder);
}
if(sFileName == "*.*")
{
if((sr.Attr & faDirectory) == 0 && (sr.Name != ".") && (sr.Name != ".."))
SLista->Add(sDir + sr.Name);
}
else
{
if((sr.Attr & faDirectory) == 0 && SameText(sr.Name, sFileName) && !bOnlyRoz)
{
SLista->Add(sDir + sr.Name);
}
if(bOnlyRoz)
{
if((sr.Attr & faDirectory) == 0)
{
if(!sRoz.IsEmpty() && SameText(sRoz, ExtractFileExt(sr.Name) ))
SLista->Add(sDir + sr.Name);
if(!sName.IsEmpty())
{
int p = sr.Name.LastDelimiter(".");
if( SameText(sName, sr.Name.SubString(1, p - 1)) )
SLista->Add(sDir + sr.Name);
}
}
}
}
}
while(FindNext(sr) == 0);
FindClose(sr);
}
} }
TStrings *SearchFile(String sDir, String sFileName, BOOL bSubFolder)
{
::SetCursor(LoadCursor(NULL, IDC_WAIT));
using namespace SearchSection;
std::auto_ptr<TStringList> STempList(new TStringList());
if(sFileName.IsEmpty()) return STempList.get();
if(sDir.SubString(sDir.Length(), 1) != "\\") sDir = sDir + "\\";
sRoz = "", sName = "";
bOnlyRoz = false;
if(sFileName.SubString(1, 1) == "*")
{
bOnlyRoz = true;
sRoz = ExtractFileExt(sFileName);
}
if(sFileName.SubString(sFileName.Length(), 1) == "*")
{
bOnlyRoz = true;
int p = sFileName.LastDelimiter(".");
sName = sFileName.SubString(1, p - 1);
}
FindFile(STempList.get(), sDir, sFileName, bSubFolder);
Screen->Cursor = crDefault;
return STempList.release();
}
Kod można umieścić w dowolnym pliku. Najlepiej stworzyć sobie oddzielny moduł i tam go dać. O tworzeniu modułów, czyli plików z pogrupowanymi funkcjami, do wielokrotnego wykorzystania w wielu programach pisałem
w serwisie Cyfrowy
Baron, w dziale:
teoria tworzenie modułów.
Co się zaś tyczy wywołania przedstawionej wyżej funkcji do wyszukiwania plików to można to zrobić tak:
wyszukiwanie wszystkich plików w zadanym katalogu
(tutaj: c:\windows) oraz w podkatalogach:
ListBox1->Items->AddStrings( SearchFile("c:\\windows\\", "*.*", true) );
// lub:
ListBox1->Items = SearchFile("c:\\windows\\", "*.exe", true);
Przyjrzyjmy się argumentom funkcji
SearchFile:
TStrings *SearchFile(String sDir, String sFileName, BOOL bSubFolder)
Jak widać funkcja zwraca wartość typu
TStrings, więc zwrócona wartość pasuje do każdej listy tego typu, a więc zarówno do ListBox, ComboBox, czy Memo.
sDir - Pierwszy argument funkcji to wartość typu
String (AnsiString lub UnicodeString), poprzez ten argument należy podać lokalizację katalogu, w którym chcemy szukać pliku lub plików.
sFileName - Drugi argument to wartość typu
String (AnsiString lub UnicodeString) poprzez którą należy podać nazwę pliku. Można podać całą nazwę pliku, np: notepad.exe, wtedy program będzie szukał tylko pliku pasującego zarówno do nazwy jak i rozszerzenia. Można podać tylko nazwę pliku, ale zamiast rozszerzenia należy podać gwiazdkę, np: notepad.*. Program będzie szukał tylko plików z pasującą nazwą, ale z dowolnym rozszerzeniem. Można podać tylko rozszerzenie, ale zamiast nazwy należy podać gwiazdkę, np: *.exe. Program będzie szukał tylko plików z pasującym rozszerzeniem, ale z dowolną nazwą. Można podać tylko gwiazdki zamiast rozszerzenia i nazwy, np: *.*, program wyliczy wszystkie pliki w zadanym katalogu.
bSubFolder - Trzeci argument to zmienna typu
BOOL, poprzez którą należy określić, czy funkcja ma przeszukiwać tylko zadany katalog - wartość
false, czy ma przeszukiwać również podkatalogi w zadanym katalogu - wartość
true.
Funkcja zwraca wartości do listy, gdyż zwracanie do zmiennej nie ma większego sensu, ponieważ w zadanej lokalizacji może być więcej niż jeden poszukiwany plik, jeżeli przeszukujemy również podkatalogi. Można oczywiście wykorzystać tą funkcje do poszukiwania jednego konkretnego pliku, ale w takiej sytuacji nie należy przeszukiwać podkatalogów. Trzeba również podać pełną nazwę poszukiwanego pliku. Jak wiadomo w katalogu może występować tylko jeden plik o tej samej nazwie i rozszerzeniu:
Edit1->Text = SearchFile("c:\\windows\\", "notepad.exe", false)->Text.Trim();