📄 unit2.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "Unit1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall Unit2::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
//线程构造函数
__fastcall TSearchFileThread::TSearchFileThread(bool CreateSuspended,
AnsiString pFileDir,AnsiString pFilter,AnsiString pSeekText,
bool pSubdirEnabled): TThread(true)
{
//线程终止自动释放内存
FreeOnTerminate = true;
//初始化成员变量
mFileDir=pFileDir;
mFilter=pFilter;
mSeekText=pSeekText;
mSubdirEnabled=pSubdirEnabled;
//挂起方式启动线程
Resume();
}
//---------------------------------------------------------------------------
//线程Execute方法
void __fastcall TSearchFileThread::Execute()
{
//响应线程终止事件
OnTerminate=Form1->ThreadOnEnd;
//现程中断属性无效时持续循环
FindFile(mFileDir,mFilter,mSeekText,mSubdirEnabled);
}
//---------------------------------------------------------------------------
//自定义成员函数,查找指定子文件夹下符合搜索条件的文件,可被递归调用
bool __fastcall TSearchFileThread::FindFile(AnsiString FileDir,
AnsiString Filter,AnsiString SeekText,bool SubdirEnabled)
{
AnsiString str;
//定义查找文件API函数中用到的数据结构
WIN32_FIND_DATA FindFileData;
//取出文件目录名的最后一个字符
str=FileDir.SubString(FileDir.Length(),1);
//文件夹中第一、二条记录的情况
if(str==".")return true;
//文件目录名的最后一个字符不是“\”,添加“\”
//如FileName为“C:\Windows” 变换后为“C:\Windows\”
if(str!="\\")FileDir+="\\";
//拟查找的文件为“*.*”类型,即文件夹中所有文件
str=FileDir+AnsiString("*.*");
//用API函数查找第一个类型匹配的函数
HANDLE hFile=FindFirstFile(str.c_str(),&FindFileData);
//线程不被终止及找到文件时循环
while(!Terminated&&hFile)
{
//取文件全名,即路径名+文件名,此时尚不知是普通文件还是文件夹等
str=FileDir+FindFileData.cFileName;
//属普通文件的情况...
if((FindFileData.dwFileAttributes&0x00ff)==0x20)
{
//属文件类型匹配,且文件中包含待找文本的情况...
if(FilterFile(str,Filter)&&LocateFile(str,SeekText))
{
//str文件全名存到线程的成员变量OutputFileName
mOutputFileName = str;
//借助于同步函数Synchronize,将当前文件全名添加到主窗口的放置已
//找到文件列表的Tmemo控件,具体由自定义成员函数IntoFileList完成
//与VCL打交道必须用Synchronize,且要求IntoFileList无自变量无返回值
Synchronize(IntoFileList);
}
}
//允许“包含子文件夹”且当前文件全名为子目录的情况...
else if(SubdirEnabled&&(FindFileData.dwFileAttributes&0x00ff)==0x10)
{
//子目录下又遇到子目录,递归调用,即函数自己调用自己
FindFile(str,Filter,SeekText,SubdirEnabled);
}
//对应于API函数FindFirstFile,下面调用另一API函数查找后续的类型匹配文件
if(FindNextFile(hFile,&FindFileData)==false)
{
//再也找不到,跳出循环
break;
}
}
return true;
}
//---------------------------------------------------------------------------
//文件类型过滤,Filter可能为“*.*”“*.htm”等,不支持“?”弘代换字符
//FileName若为Filter指定的类型返回true,否则返回false
bool __fastcall TSearchFileThread::FilterFile(AnsiString FileName,
AnsiString Filter)
{
AnsiString str;
//Filter未指定过滤条件时,属类型匹配方式,返回true
if(Filter.IsEmpty())return true;
int pos=Filter.AnsiPos(".");
if(pos==0)
{
//属指定文件名的情况,仅当FileName与Filter相同,返回true
if(FileName==Filter)return true;
}
else
{
//取出类型串中文件扩展名部分,如“*.htm”的“.htm”
str=Filter.SubString(pos,Filter.Length());
//属于“*.*”的情况
if(str==".*")return true;
//调用取出文件名的扩展名的系统函数,判断文件类型是否相同
if(ExtractFileExt(FileName).UpperCase()==str.UpperCase())return true;
}
return false;
}
//---------------------------------------------------------------------------
//判断文件FileName是否包含文本SeekText,包含返回true,否则返回false
bool __fastcall TSearchFileThread::LocateFile(AnsiString FileName,
AnsiString SeekText)
{
//声明流式文件
TFileStream * pFile;
try
{
//只读方式打开文件,不能正确打开时抛出异常
pFile=new TFileStream(FileName,fmOpenRead);
}
catch(...)
{
//打开文件异常,中途退出,返回false,与不包含待查文本情况同
return false;
}
char *buffer;
try
{
//尝试方式申请分配与流式文件相同长度的内存缓冲区
buffer=new char[pFile->Size];
}
catch(...)
{
//内存分配申请失败,关闭流式文件
delete pFile;
//中途退出,返回false,与不包含待查文本情况同
return false;
}
//将流式文件全部读入内存缓冲区
pFile->Read(buffer,pFile->Size);
//将buffer构造为AnsiString串,并用其子串索引方法查找SeekText
int pos=AnsiString(buffer,pFile->Size).AnsiPos(SeekText);
//关闭流式文件
delete pFile;
//释放内存
delete buffer;
//文件中未找到待找文本,返回false
if(pos==0)return false;
//文件中已找到待找文本,返回true
return true;
}
//---------------------------------------------------------------------------
//搜索到符合条件的文件送主窗口列表框
void __fastcall TSearchFileThread::IntoFileList(void)
{
//文件名添加到主窗口的列表框中
Form1->ListBox1->Items->Add(mOutputFileName);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -