⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch24.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 4 页
字号:

void 
TDirStack::Push(TDirInfo *DirInfo)

{

  Add(DirInfo);

}



TDirInfo *TDirStack::Pop()

{

  void *Temp = Items[0];

  Delete(0);

  return (TDirInfo *)Temp;

}



// -- TFindDirs ----------------



__fastcall TFindDirs::TFindDirs(TComponent 
*AOwner, AnsiString AStartString)

: TComponent(AOwner)

{

  SetStartString(AStartString); // Don't set data store directly!

  FDirStack = NULL;

  FOnFoundDir = NULL;  

}



void __fastcall TFindDirs::SetStartString(AnsiString AStartString)

{

  
FStartString = AStartString; 

  FStartDir = ExtractFilePath(FStartString);

  FFileExt = ExtractFileExt(FStartString);

}



void __fastcall TFindDirs::Initialize(void)

{

  #ifdef DEBUG_FIND_DIRS

  if ((fp = fopen("c:\searchdirs.txt", 
"w+")) == NULL)

  {

    ShowMessage("Can't open debug file");

  }

  #endif

  if (FDirStack)

    delete FDirStack;

  FDirStack = new TDirStack;

  FCurDirectory = "";

  FFileMask = "*.*"; 

  #ifdef 
DEBUG_FIND_DIRS

  fprintf(fp, "%s %s %s \n", FStartDir.c_str(), FFileMask.c_str(), FFileExt.c_str());

  #endif

}



__fastcall TFindDirs::~TFindDirs()

{

  #ifdef DEBUG_FIND_DIRS

  fclose(fp);

  #endif

}



void 
TFindDirs::ProcessFile(TSearchRec FileData, AnsiString FileName)

{

  if (FOnFoundFile != NULL)

    FOnFoundFile(FileName);

  #ifdef DEBUG_FIND_DIRS

  fprintf(fp, "File found: %s\n", FileName);

  #endif

}



void 
TFindDirs::ProcessDir(TSearchRec FileData, AnsiString DirName)

{

  if (FOnFoundDir != NULL)

    FOnFoundDir(DirName);

  #ifdef DEBUG_FIND_DIRS

  fprintf(fp, "Dir found: %s\n", DirName);

  #endif

}



void 
TFindDirs::FoundADir(TSearchRec *FileData)

{

  AnsiString FullName;

  #ifdef DEBUG_FIND_DIRS

  fprintf(fp, "Dir found: %s\n", FileData->Name);

  #endif

  if ((FileData->Name != ".") &&

     (FileData->Name 
!= ".."))

  {

    TDirInfo *DirInfo = new TDirInfo;

    DirInfo->CurDirectory = AnsiString(FCurDirectory + FileData->Name + "\\");

    DirInfo->SearchRec = *FileData;

    #ifdef DEBUG_FIND_DIRS

    fprintf(fp, 
"DirInfo: %s\n", DirInfo->SearchRec.Name);

    fflush(fp);

    #endif

    FDirStack->Push(DirInfo);

  }

}



///////////////////////////////////////

// FoundAFile

///////////////////////////////////////

void 
TFindDirs::FoundAFile(TSearchRec *FileData)

{

  AnsiString FullName;



  if ((FFileExt == ".*") ||

      (UpperCase(ExtractFileExt(FileData->Name)) == UpperCase(FFileExt)))

  {

    FullName = FStartDir + FCurDirectory + 
FileData->Name;

    ProcessFile(*FileData, FullName);

  }

}



///////////////////////////////////////

// GetAllFiles

///////////////////////////////////////

void TFindDirs::GetAllFiles(AnsiString *StartDir)

{

  TSearchRec FileData;

  int 
Info;



  Info = FindFirst(StartDir->c_str(), faDirectory, FileData);

  while (Info == 0)

  {

    if (FileData.Attr == faDirectory)

      FoundADir(&FileData);

    else

      FoundAFile(&FileData);

    Info = FindNext(FileData);

  
}

  FindClose(&FileData.FindData);

}



///////////////////////////////////////

// SetupSearchString

///////////////////////////////////////

void TFindDirs::SetupSearchString()

{

  FSearchString = FStartDir + FCurDirectory + FFileMask;

  
#ifdef DEBUG_FIND_DIRS

  fprintf(fp, "FSearchString: %s \n", FSearchString);

  #endif

}



///////////////////////////////////////

// GetNextDirectory

///////////////////////////////////////

void TFindDirs::GetNextDirectory()

{

  
TDirInfo *FDirInfo = FDirStack->Pop();

  FCurDirectory = FDirInfo->CurDirectory;

  #ifdef DEBUG_FIND_DIRS

  fprintf(fp, "Next Directory: %s\n", FCurDirectory);

  fflush(fp);

  #endif

  ProcessDir(FDirInfo->SearchRec, FStartDir 
+ FCurDirectory);

  delete FDirInfo;

}



BOOL TFindDirs::SetupFirstDirectory()

{

  TSearchRec FileData;

  AnsiString SearchStr = FStartDir + FFileMask;



  int Info = FindFirst(SearchStr.c_str(), faDirectory, FileData);

  
FindClose(&FileData.FindData);

  if (Info == 0)

  {

    TDirInfo *DirInfo = new TDirInfo;

    DirInfo->CurDirectory = FCurDirectory;

    FileData.Name = FStartDir;

    DirInfo->SearchRec = FileData;

    FDirStack->Push(DirInfo);

    
return TRUE;

  }

  else

    return FALSE;

}



///////////////////////////////////////

// Run: FindFilesAndDirs

///////////////////////////////////////

void TFindDirs::Run(void)

{

  BOOL FDone = False;

  BOOL FirstTime = TRUE;



  
Initialize();

    

  if (!SetupFirstDirectory())

  {

    ShowMessage("Invalid Search String");

    return;

  }



  while (!FDone)

  {

    SetupSearchString();

    if (!FirstTime)

      GetAllFiles(&FSearchString);

    if 
(FDirStack->Count > 0)

      GetNextDirectory();

    else

      FDone = True;

    FirstTime = FALSE;

  }

  FDirStack->Free();

  FDirStack = NULL;

}



///////////////////////////////////////

// TFindDirsList //////////////////////


///////////////////////////////////////



__fastcall TFindDirsList::TFindDirsList(TComponent *AOwner,

  AnsiString AStartDir): TFindDirs(AOwner, AStartDir)

{

  FFileList = new TStringList;

  FFileList->Sorted = True;

  FDirList = new 
TStringList;

  FDirList->Sorted = True;

}



__fastcall TFindDirsList::~TFindDirsList()

{

  FFileList->Free();

  FDirList->Free();

}



void TFindDirsList::ProcessFile(TSearchRec FileData, AnsiString FileName)

{

  
FFileList->Add(FileName);

}



void TFindDirsList::ProcessDir(TSearchRec FileData, AnsiString DirName)

{

  FDirList->Add(DirName);

}



namespace Finddirs2

{

  void __fastcall Register()

  {

    TComponentClass classes[2] = 
{__classid(TFindDirs),

      __classid(TFindDirsList)};

    RegisterComponents("Unleash", classes, 1);

  }

}

</FONT></PRE>
<P>The database aspects of this program are important. You will find the files used
by the program in the 
<TT>Data</TT> directory on the CD that ships with this book.
As I explain in the readme file that accompanies the CD, you should set up an alias
called <TT>CUnleashed</TT> that points to these files. Needless to say, you should
recreate the data 
directory on your hard drive, and should not use the read-only
directory found on the CD, but should make sure they've been copied onto your hard
drive. The <TT>DatabaseName</TT> for the <TT>TDatabase</TT> object used in my version
of the program 
contains the string <TT>FileData</TT>, so you might get an error about
that alias if you try to run the program. However, you do not want to try to fix
the <TT>FileData</TT> alias, rather the one called <TT>CUnleashed</TT>. The data
module for the 
program is shown in Figure 24.2.</P>
<P>To use the program, first point it to a subdirectory on your hard disk. Then type
in a file mask in the edit control at the top of the form. For example, you might
type in <TT>c:\temp\*.cpp</TT> or simply 
<TT>c:\temp\*.*</TT>. Be sure to type in
the file mask. It would cause an error if you typed <TT>I:\</TT> instead of <TT>I:\*.*</TT>.
(In general, the program is not robust enough to check for many user errors.) When
you click the button at the bottom 
of the program, the code iterates through all
the directories beneath the one you pointed to and finds all the files that have
the extension you designated. The program then places these files in a list database.<BR>
<BR>
<A NAME="Heading16"></A><A 
HREF="24ebu02.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/24/24ebu02.jpg">FIGURE 24.2.</A><FONT COLOR="#000077">
</FONT><I>The data module for the SearchDirs program.</I>

<DL>
	<DT></DT>
</DL>



<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>I tested the 
<TT>TFindDirs</TT>
	component fairly extensively. For instance, I aimed it at the root of my C drive,
	which contains 1.12GB of space, with all but about 100MB used. The program ran fine
	against the thousands of files on that drive. I also aimed the 
component at nested
	directories containing long filenames, and again it handled the challenge without

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -