Windows遍歷全盤所搜檔案,並通過多執行緒顯示搜尋進度(C++/C)
阿新 • • 發佈:2018-11-08
程式設計軟體,系統
軟體: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,希望發現的朋友可以與本人聯絡,優化程式碼,互相討論,共同進步。