制作一个多线程文件搜索器

软件简介:一个多线程的文件搜索器

(一)准备工作

使用工具:VC++ 6.0

所需知识:入门C++,一点windows编程知识,一点MFC知识

(二)大致实现

用MFC来设置软件的界面,windows编程作为核心编程(调用windows API),C++设计软件功能逻辑

(三)软件截图

 

 

 

 

 

 

 

 

 

(四)细致流程

       (1)用vc++6.0创建一个基于对话框的MFC程序

 

 

 

 

 

 

 

   (2)软件主界面设计 按下图设置软件的主界面

各个控件的类型及其属性:

 

 主窗口属性:

 

 

 

 (五)下面添加各个控件的事件代码

  1、首先要设置一下列表框的样式:    

    在这之前首先要绑定一个列表控件变量https://blog.csdn.net/o396032767/article/details/84802699   变量名为m_ResultLIst

    在FileFinderDlg.cpp的初始化界面函数BOOL CFileFinderDlg::OnInitDialog()中加入一下代码

1 m_ResultLIst.SetExtendedStyle(m_ResultLIst.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
2     m_ResultLIst.InsertColumn(0,"查找结果",LVCFMT_LEFT,830);

  2、设置默认搜索位置

    FileFinderDlg.cpp的初始化界面函数BOOL CFileFinderDlg::OnInitDialog()中加入

    

GetDlgItem(IDC_EDIT1)->SetWindowText("C:\\");

  3、在FileFinderDlg.h头文件中新建一个类,用于线程传递参数(因为参数太多,所以新建一个类)

    

 1 class CFindItem
 2 {
 3 public:
 4     CString m_PathFind;//路径
 5     CString m_FName;//文件名
 6     HWND m_hMainDlg;
 7     CFindItem()
 8     {
 9         m_PathFind.Empty();
10         m_FName.Empty();
11         m_hMainDlg = NULL;
12     }
13     CFindItem(CFindItem &tItem)
14     {
15         m_PathFind = tItem.m_PathFind;
16         m_FName = tItem.m_FName;
17         m_hMainDlg = tItem.m_hMainDlg;
18     }
19 };

  4、在FileFinderDlg.cpp中定义5个全局变量

long g_FindCount=0;//表示文件数
long g_ThreadNum=0;//表示当前线程数
bool g_bFinding=false;//表示当前状态
CString st1;
CString st2;

  5、定义一个自定义消息,用来多线程中的消息传递

    (1)、在FileFinderDlg.h中添加 #define WM_ADD_ITEM (WM_USER+110)

    (2)、在FileFinderDlg.cpp中添加ON_MESSAGE(WM_ADD_ITEM,OnAddItem)

      

 

     (3)、在FileFinderDlg.h中添加afx_msg LRESULT OnAddItem(WPARAM wParam,LPARAM lParam);

 

 

注意:添加的代码一定要在AFX_DATA后面,否则会导致打开类向导失败

    (4)、在FileFinderDlg.cpp中添加消息响应函数

1 LRESULT CFileFinderDlg::OnAddItem(WPARAM wParam,LPARAM lParam)
2 {
3     CString strPath = (LPCTSTR)lParam;
4     
5     m_ResultLIst.InsertItem(m_ResultLIst.GetItemCount(),strPath);//把搜索到的文件路径显示到list框中
6 
7     return 0;
8 }     

 

6、-3-按钮 的点击事件,它的作用是点击后让用户选择在哪个路径搜索文件,并显示到 -6-编辑框上,代码如下

 1 void CFileFinderDlg::OnButton1() 
 2 {
 3     // TODO: Add your control notification handler code here
 4 
 5     TCHAR szPath[MAX_PATH]={0};
 6     BROWSEINFO mBroInfo={0};
 7     mBroInfo.hwndOwner = m_hWnd;
 8     ITEMIDLIST *pidl = SHBrowseForFolder(&mBroInfo);
 9     if(SHGetPathFromIDList(pidl,szPath))
10     {
11         SetDlgItemText(IDC_EDIT1,szPath); //把文件路径显示到ID为IDC_EDIT1的编辑框上
12     }
13     CoTaskMemFree(pidl);    
14 }

截图:

 

 7、创建一个定时器用来后面实时显示当前的线程数与搜索到的文件数

    1、在窗口初始化函数中添加SetTimer(1,100,NULL);

    代码如下:

 1 void CFileFinderDlg::OnTimer(UINT nIDEvent) 
 2 {
 3     st2.Format("%d",g_FindCount);
 4     st1.Format("%d",g_ThreadNum);
 5     GetDlgItem(IDC_EDIT3)->SetWindowText(st1);//显示文件数
 6     GetDlgItem(IDC_EDIT4)->SetWindowText(st2);//显示当前线程数
 7     // TODO: Add your message handler code here and/or call default
 8     if(g_ThreadNum>0)//如果正在搜索,则搜索,编辑框等不可选取,反之
 9     {
10         GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);
11         GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE);
12         GetDlgItem(IDC_BUTTON5)->EnableWindow(FALSE);
13         GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
14         GetDlgItem(IDC_BUTTON2)->EnableWindow(true);
15     }    
16     else
17     {
18         GetDlgItem(IDC_EDIT1)->EnableWindow(true);
19         GetDlgItem(IDC_EDIT2)->EnableWindow(true);
20         GetDlgItem(IDC_BUTTON5)->EnableWindow(true);
21         GetDlgItem(IDC_BUTTON1)->EnableWindow(true);
22         GetDlgItem(IDC_BUTTON2)->EnableWindow(false);
23     }
24     CDialog::OnTimer(nIDEvent);
25 }

8、-4-开始 按钮的点击事件,点击后开始搜索文件,并把搜索结果显示到-12-列表框中,代码如下:

 1 void CFileFinderDlg::OnButton5() 
 2 {
 3     
 4     CString str1,str2;
 5     GetDlgItemText(IDC_EDIT1,str1);//获取ID为IDC_EDIT1 | IDC_EDIT2 上的内容
 6     GetDlgItemText(IDC_EDIT2,str2);
 7     if(str1.IsEmpty() || str2.IsEmpty() )//判断编辑框是否为空
 8     {
 9         AfxMessageBox("搜索目录与目标文件不能为空!");//如果文件目录或文件名为空,则弹出消息框并直接返回,否则程序崩溃
10         return;
11     }
12     
13     g_bFinding = true;
14     g_FindCount=0;
15     g_ThreadNum=0;
16 
17     m_ResultLIst.DeleteAllItems();//搜索开始时先清空列表框
18 
19     CFindItem *pItem = new CFindItem();//新建一个类
20     GetDlgItemText(IDC_EDIT1,pItem->m_PathFind);//获取编辑框的搜索路径与文件名保存在类成员变量中
21     GetDlgItemText(IDC_EDIT2,pItem->m_FName);
22     pItem->m_hMainDlg = GetSafeHwnd();//获取窗口的安全句柄
23 
24     AfxBeginThread(FindProc,pItem);//创建一个工作线程
25 }

9、编辑线程入口函数 在按钮-5-事件响应函数上方输入

 1 UINT _cdecl FindProc(LPVOID pParam)
 2 {
 3     InterlockedIncrement(&g_ThreadNum);//原子操作,线程同步,线程数加1
 4     
 5     CFindItem *pItem = (CFindItem*)pParam;//接收参数
 6 
 7     CString strRootPath = pItem->m_PathFind;
 8     if(strRootPath[strRootPath.GetLength()-1]!='\\')//在c++中路径要使用‘\\’
 9         strRootPath = strRootPath+"\\";
10 
11     CFileFind mFinder;//新建文件搜索类
12 
13     BOOL bFind = mFinder.FindFile(strRootPath+"*.*");//查找一个目录中的指定文件
14     while(bFind && g_bFinding)
15     {
16         bFind = mFinder.FindNextFile();
17         if(mFinder.IsDots())
18         {
19             continue;
20         }
21         else if(mFinder.IsDirectory())//如果找到的是文件夹,那么就新建一个搜索线程
22         {
23             CFindItem *pSubItem = new CFindItem(*pItem);
24             pSubItem->m_PathFind = mFinder.GetFilePath();
25             AfxBeginThread(FindProc,pSubItem);
26         }
27         else //找到的是文件
28         {
29             CString strFileName = mFinder.GetFileName();
30             if(strFileName.CompareNoCase(pItem->m_FName)==0)
31             {
32                 CString strPath = mFinder.GetFilePath();
33             
34                 SendMessage(pItem->m_hMainDlg,WM_ADD_ITEM,0,(LPARAM)(LPCTSTR)strPath);//发送一个消息
35                 InterlockedIncrement(&g_FindCount);//文件数加一
36         
37             }
38         }
39     }
40     mFinder.FindFile();
41 
42     delete pParam;
43     InterlockedDecrement(&g_ThreadNum);//线程数
44     //s1.Format("%d",g_ThreadNum);
45     //GetDlgItem(IDC_EDIT3)->SetWindowText(s1);
46     return 0;
47 }

10、-5-暂停按钮响应函数

1 void CFileFinderDlg::OnButton2() 
2 {
3     // TODO: Add your control notification handler code here
4     
5     g_bFinding = false;//g_fFinding为false则停止线程的创建,停止文件的搜索
6 }

 

posted @ 2020-10-25 21:26  SALTED____FISH  阅读(213)  评论(0)    收藏  举报