软件:VS2017
工程属性:MFC对话框(其他工程属性稍作修改也适用)
系统:windows10家庭版
1、利用CFileFind实现查找文件
2、利用递归实现全盘搜索
3、多线程实现父对话框搜索文件时,子对话框显示搜索进度
1、父对话框负责搜索文件,和分配多线程,所用函数代码如下
//全局变量定义
extern CString m_pass; //用来显示被找到的文件路径
extern int IShowTime1; //用来更新进度条
//父对话框类函数及变量声明
//由于静态函数无法使用动态变量,所以一下所有函数及变量多使用了静态变量/全局变量
static CString CFindFile(const TCHAR *szPath, const TCHAR *szFileName, CStringArray *paStrResult);
static CString load1;
static UINT ChangeProcessBox(LPVOID pParam);
static UINT FindFileBotton(LPVOID pParam);
//按下搜索路径按钮后执行该函数
UINT CAutoChangeBlackMapDlg::FindFileBotton(LPVOID pParam)
{
// TODO: 在此处添加实现代码.
TCHAR *szPath;
TCHAR *szFileName = _T("你要上搜索的文件名字,带后缀");
CStringArray paStrResult;
for (char x = 'Z'; x >= 'A'; x--) //全盘搜索
{
CString x1(x);
CString StrPath1 = x1 + _T(":\\");
if (PathIsDirectory((LPCTSTR)StrPath1) == FALSE)
{
x=x;
}
else
{
szPath = StrPath1.GetBuffer(StrPath1.GetLength());
StrPath1.ReleaseBuffer();
load1 = CAutoChangeBlackMapDlg::CFindFile(szPath, szFileName, &paStrResult); //核心搜索函数
}
IShowTime1++;
}
return 0;
}
//控制进度条变化
UINT CAutoChangeBlackMapDlg::ChangeProcessBox(LPVOID pParam)
{
// TODO: 在此处添加实现代码.
while (IShowTime1 != 26)
{
for (int i = 0; i < 1000; i++)
{
//Sleep(50);
}
}
return 0;
}
CString CAutoChangeBlackMapDlg::CFindFile(const TCHAR *szPath, const TCHAR *szFileName, CStringArray *paStrResult)
//递归搜索全盘文件
//第一个参数为要搜索的路径,比如"c:\\dir\\"或"c:\\dir"则在包括此目录的所有子目录下搜索
//第二个参数为要搜索的文件,比如"qq.txt",需要提供文件后缀,大小写不敏感
//第三个参数用于保存搜索到的文件的全路径,请构造一个CStringArray对象并传入地址
{
// TODO: 在此处添加实现代码.
ASSERT(paStrResult != NULL);
CString StrPath(szPath);
CString StrFileName(szFileName);
//检查路径字符串的最后一个字符是不是'\',不是则加上
if (StrPath[StrPath.GetLength() - 1] != _T('\\'))
StrPath += _T('\\');
CString StrFindPath = StrPath + _T("*.*");
//开始查找
CFileFind finder;
BOOL bWorking = finder.FindFile(StrFindPath);
while (bWorking)
{
bWorking = finder.FindNextFile();
//如果找到的是文件夹,递归进去
if (finder.IsDirectory() && !finder.IsDots())
{
CFindFile(StrPath + finder.GetFileName(), StrFileName, paStrResult);
}
//如果找到了文件,将绝对路径添加进字符串数组,大小写不敏感
if (finder.GetFileName().CompareNoCase(StrFileName) == 0)
{
paStrResult->Add(finder.GetFilePath());
}
}
//将字符串数组中的内容存储到字符串中
int iden = paStrResult->GetSize();
CString load;
if (iden == 0)
{
load = _T("1");
}
else if (iden > 1)
{
load = _T("2");
}
else
{
for (int i = 0; i < iden; i++)
{
load = load + paStrResult->GetAt(i);
}
}
return load;
}
//多线程分配
AfxBeginThread(FindFileBotton, this);
AfxBeginThread(ChangeProcessBox, this);
//这个地方是为了打开进度条的对话框,也就是子对话框
showTime dlg2; //showTime类是用来显示进度条的,在下面会展示该类里面的函数
dlg2.DoModal();
2、子对话框负责显示进度条,代码如下
//初始化进度条,在OnInitDialog函数中实现,这个函数是在类属性的添加虚函数中添加,不需要手动敲上去
m_process.SetRange(0, 26); //初始化进度条范围,因为有26个字母
下面这两个函数也不是手动敲的,具体的添加方式参考这两篇文章,OnShowWindow,OnTimer
void showTime::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialogEx::OnTimer(nIDEvent);
m_process.SetPos(IShowTime1);
if (IShowTime1 == 26)
{
OnOK();
}
}
void showTime::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialogEx::OnShowWindow(bShow, nStatus);
// TODO: 在此处添加消息处理程序代码
this->KillTimer(1);
this->SetTimer(1, 20, NULL);
}
https://www.2cto.com/kf/201303/194024.html
https://blog.csdn.net/blogcaicai01/article/details/47006879
https://blog.csdn.net/qq_33723441/article/details/54599022
http://blog.sina.com.cn/s/blog_4a4839570102v5ba.html
代码在本机调试没有问题,各位朋友在使用的时候可能需要按照自身的情况加以修改,本人技术有限,代码中会有隐含的bug,希望发现的朋友可以与本人联系,优化代码,互相讨论,共同进步。