课上完了连老师见都没见一面QAQ....记录一下该小项目

效果如下:



1、实现文件搜索功能,并封装为类

  1. 1)首先是文件搜索类Rapidfinder的构造函数和析构函数和文件信息初始化函数和文件路径规格化函数;重新初始化文件函数
  2. CRapidFinder::CRapidFinder(HWND MainHwnd, CString MatchName, CString MatchDir)
  3. {
  4. m_hThrds = NULL;
  5. InitializeCriticalSection(&m_gCriticalSection);
  6. ThreadSet();
  7. FinderSet(MainHwnd, MatchName, MatchDir);
  8. }
  9. CRapidFinder::~CRapidFinder()
  10. {
  11. DeleteCriticalSection(&m_gCriticalSection);
  12. if (m_hExitEvent)CloseHandle(m_hExitEvent);
  13. }
  14. //初始化搜索文件信息
  15. void CRapidFinder::FinderSet(HWND MainHwnd, CString MatchName, CString MatchDir)
  16. {
  17. FinderReset();
  18. m_MainhWnd = MainHwnd;
  19. if (!MatchName.IsEmpty())
  20. {
  21. MatchName.MakeUpper();
  22. MatchDir.MakeUpper();//makerupper()将CString字符转化为一个大写的字符串。
  23. m_strFileName = MatchName;
  24. m_Option |= OP_FILENAME;//按位或后赋值,OP_FILENAME为0x01
  25. }
  26. m_strFileDir = MatchDir;
  27. m_hExitEvent = CreateEvent(NULL, TRUE, FALSE, L"RAPIDFINDER");//创建事件,手动设置信号,初始化为未激发
  28. CreatePathList();//规格化文件路径
  29. }
  30. //初始化创建线程的信息
  31. void CRapidFinder::ThreadSet(LONG MaxThreadCount, int priority)
  32. {
  33. m_Priority = priority;
  34. m_ActiveCount = m_MaxThreadCount = MaxThreadCount;
  35. if (m_hThrds)delete[]m_hThrds;//释放线程句柄数组
  36. m_hThrds = new HANDLE[MaxThreadCount];
  37. }
  38. //重新初始化文件
  39. void CRapidFinder::FinderReset()
  40. {
  41. m_lpText = NULL;
  42. m_NextVal = NULL;
  43. m_Option = 0;
  44. m_strFileName = "";
  45. m_strFileDir = "";
  46. m_DirList.RemoveAll();
  47. ResetEvent(m_hExitEvent);//重置为未激发态
  48. m_ExitCode = ERR;
  49. }
  50. //规格化文件路径
  51. void CRapidFinder::CreatePathList()
  52. {
  53. Trim(m_strFileDir);
  54. if (m_strFileDir.IsEmpty())
  55. {
  56. SetErrNo(0); return;
  57. }
  58. int np = 0, op = 0;
  59. CString str;
  60. //当有多个路径同时选择时(即用;分隔)
  61. while ((np = m_strFileDir.Find(';', op)) != -1)
  62. {
  63. str = Trim(m_strFileDir.Mid(op, np - op));
  64. str.TrimRight('\\');//消除“\\”
  65. if (!str.IsEmpty())m_DirList.AddTail((LPCTSTR)str);
  66. op = np + 1;
  67. }
  68. str = Trim(m_strFileDir.Mid(op, m_strFileDir.GetLength() - op));
  69. str.TrimRight('\\');
  70. if (!str.IsEmpty())m_DirList.AddTail((LPCTSTR)str);
  71. }
  72. 构造函数用来初始化临界区,初始化线程信息(线程优先级、最大线程数、线程句柄数组),初始化搜索文件信息(目录,文件名);
  73. 析构函数退出临界区,关闭事件句柄;
  74. 2)文件搜索函数的第二部分就是:判断搜索方式的MatchProc函数(是按文件名还是特定字符串);查询指定文件里是否包含特定字符的FindTextFromFile()函数;预先处理特定字符串的CalNextPos()函数
  75. //判断搜索文件时的方式,是按文件名还是包含字符
  76. BOOL __fastcall CRapidFinder::MatchProc(CString& findpath)
  77. {
  78. CString fname(findpath);
  79. int pos = fname.ReverseFind('\\');
  80. fname.MakeUpper();
  81. if ((m_Option & OP_FILENAME) && (fname.Find(m_strFileName, pos + 1) == -1))return false;
  82. if ((m_Option & OP_FILETEXT) && !FindTextFromFile(findpath))return false;
  83. return true;
  84. }
  85. //查询文件里是否包含我们指定的字符
  86. BOOL __fastcall CRapidFinder::FindTextFromFile(CString& findpath)
  87. {
  88. CFile file;
  89. if (NULL == file.Open(findpath.GetBuffer(0), CFile::modeRead | CFile::typeBinary))return false;
  90. BYTE* Buffer = new BYTE[512];
  91. int nRead;
  92. if (!(nRead = file.Read(Buffer, 512))) { file.Close(); return false; }//如果读回字节数为0,则关闭Cfile
  93. int i = 0, j = 0;
  94. while (j < m_TextSize)
  95. if (j == -1 || Buffer[i] == m_lpText[j])//判断是否包含我们指定的字符
  96. {
  97. if (++i == nRead)//如果读回字节数为1,则只需要一轮循环集合
  98. {
  99. /*PeekAndPump();*/
  100. if (!(nRead = file.Read(Buffer, 512))) { file.Close(); return false; }
  101. i = 0;
  102. }
  103. j++;
  104. }
  105. else j = m_NextVal[j];
  106. file.Close();
  107. return true;
  108. }
  109. //决定是否从下一位字符再开始匹配。比如在“aab”中搜索“ab”,当在“aab”中有重复的字符时给每一位字符设置一个是否进行到下一位匹配的标志
  110. int* CRapidFinder::CalNextPos()
  111. {
  112. int j = 0, k = -1;
  113. m_NextVal[0] = -1;
  114. while (j < m_TextSize - 1)
  115. if ((k == -1) || (m_lpText[j] == m_lpText[k]))
  116. {
  117. j++; k++;
  118. if (m_lpText[j] != m_lpText[k])m_NextVal[j] = k;
  119. else m_NextVal[j] = m_NextVal[k];
  120. }
  121. else k = m_NextVal[k];
  122. return m_NextVal;
  123. }
  124. 3)第三部分就是多线程的处理,包括主线程函数MainThreadProc()、子线程函数ThreadProc()、启动子线程函数StartFinder()、暂停函数PauseFinder()、停止函数StopFinder()、暂停后继续函数ResumeFinder();
  125. //主线程函数,为每个线程分配搜索任务
  126. DWORD WINAPI CRapidFinder::MainThreadProc(LPVOID lpParam)
  127. {
  128. //新建一个finder对象来存储文件信息
  129. CRapidFinder* finder = (CRapidFinder*)lpParam;
  130. resume:
  131. //Reset,重新开始
  132. ResetEvent(finder->m_hExitEvent);//重置m_hExitEvent,使之处于未激发态
  133. finder->m_ExitCode = ERR;
  134. finder->m_ActiveCount = finder->m_MaxThreadCount;
  135. PostMessage(finder->m_MainhWnd, WM_THREADCOUNT, (WPARAM)(finder->m_ActiveCount), NULL);
  136. //启动子线程
  137. for (int i = 0; i < finder->m_MaxThreadCount; i++)
  138. finder->m_hThrds[i] = StartThread(ThreadProc, lpParam);
  139. WaitForMultipleObjects(finder->m_MaxThreadCount, finder->m_hThrds, TRUE, INFINITE);//等待所有线程返回
  140. for (int i = 0; i < finder->m_MaxThreadCount; i++)
  141. CloseHandle(finder->m_hThrds[i]); //关闭所有线程句柄
  142. //查看线程退出原因
  143. switch (finder->m_ExitCode)
  144. {
  145. case PAUSE:SendMessage(finder->m_MainhWnd, WM_THREADPAUSE, NULL, NULL);
  146. ResetEvent(finder->m_hExitEvent);//重置为未激发态,为暂停后重新开始做准备
  147. //等待继续查找
  148. WaitForSingleObject(finder->m_hExitEvent, INFINITE);
  149. goto resume;
  150. //下面两个类似,一个是直接退出,一个是执行完退出
  151. case EXIT:SendMessage(finder->m_MainhWnd, WM_THREADEXIT, EXIT, NULL);
  152. finder->FinderReset();
  153. break;;
  154. case STOP:SendMessage(finder->m_MainhWnd, WM_THREADEXIT, STOP, NULL);
  155. finder->FinderReset();
  156. break;
  157. default:finder->SetErrNo(1); return 0;
  158. }
  159. return 1;
  160. }
  161. //启动子线程的函数
  162. HANDLE CRapidFinder::StartThread(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParam)
  163. {
  164. DWORD ThreadID;//线程id
  165. CRapidFinder* finder = (CRapidFinder*)lpParam;//文件搜索类对象
  166. HANDLE htmp = CreateThread(NULL, 0, lpStartAddress, lpParam, CREATE_SUSPENDED, &ThreadID);
  167. BOOL re = SetThreadPriority(htmp, finder->m_Priority);
  168. ASSERT(re);
  169. ResumeThread(htmp);
  170. return htmp;
  171. }
  172. 上述两个函数相互配合,创建指定数目的子线程(在StartFinder()函数初始化子线程信息,创建子线程);主线程使用WaitForMultipleObjects函数等待所有子线程返回,在全部返回后关闭所有句柄;
  173. 并且主线程还监听和处理子线程的状态,根据m_ExitCode判断子线程是处于暂停、停止还是暂停后继续的状态(即文件搜索中的暂停、停止、暂停后继续的功能),然后通过设置m_hExitEvent事件对象的激发状态来控制子线程的工作;
  174. 2、文件搜索中的开始、暂停、暂停后继续、停止函数
  175. //开始查找
  176. BOOL CRapidFinder::StartFinder()
  177. {
  178. if (m_DirList.IsEmpty()) { SetErrNo(0); return FALSE; }
  179. PostMessage(m_MainhWnd, WM_THREADCOUNT, (WPARAM)m_ActiveCount, NULL);
  180. DWORD ThreadID;
  181. //创建主线程
  182. HANDLE hMainThread = CreateThread(NULL, 0, MainThreadProc, (LPVOID)this, CREATE_SUSPENDED, &ThreadID); //线程是在挂起状态下创建的,并且在调用ResumeThread函数之前不会运行 。
  183. ASSERT(hMainThread);
  184. BOOL re = SetThreadPriority(hMainThread, m_Priority);//调整优先级
  185. ASSERT(re);//作用是如果它的条件返回错误,则终止程序执行
  186. ResumeThread(hMainThread);
  187. CloseHandle(hMainThread);
  188. return TRUE;
  189. }
  190. //暂停查找
  191. void CRapidFinder::PauseFinder()
  192. {
  193. if (m_ExitCode == PAUSE)return;
  194. m_ExitCode = PAUSE;
  195. SetEvent(m_hExitEvent);//发出m_hExitEvent信号
  196. Sleep(40);
  197. }
  198. //继续查找
  199. void CRapidFinder::ResumeFinder()
  200. {
  201. SetEvent(m_hExitEvent);
  202. }
  203. //停止查找
  204. void CRapidFinder::StopFinder()
  205. {
  206. if (m_ExitCode == STOP)return;
  207. if (m_ExitCode == PAUSE)
  208. {
  209. ResumeFinder();//重新开始
  210. Sleep(40);//延时
  211. }
  212. m_ExitCode = STOP;
  213. SetEvent(m_hExitEvent);
  214. }
  215. StartFinder()中创建主线程;暂停、暂停后继续、停止都是通过改变m_hExitEvent的激发状态来实现
  216. 因为创建m_hExitEvent事件时:CreateEvent(NULL, TRUE, FALSE, L"RAPIDFINDER");是手动重置激发状态,所以在主函数的个状态的处理逻辑里每次都需要先用resetEvent()重置激发态

2、MFC界面

主要用到了mfc的按钮控件、Edit控件和list控件

主要界面布局如上

相关成员的定义:

事件处理程序(函数)的实现

1)MFC类的初始化,对相关成员变量赋初值;以及对话框界面的初始化(设置菜单,图标),另外还使用到了CListCtrl控件来显示搜索到的文件信息

  1. CFinderDemoDlg::CFinderDemoDlg(CWnd* pParent /=NULL/)
  2. : CDialog(CFinderDemoDlg::IDD, pParent)
  3. {
  4. //{{AFX_DATA_INIT(CFinderDemoDlg)
  5. m_ActiveCount = _T("0");
  6. m_folder = _T("");//C:\;D:\;E:\;F:");
  7. m_count = _T("0");
  8. m_findfolder = _T("");
  9. m_text = _T("");
  10. m_filename = _T("");
  11. m_threadcount = 10;
  12. m_priority = 0;
  13. //}}AFX_DATA_INIT
  14. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  15. m_folder=GetAllDriverList();
  16. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);//图标
  17. }
  18. //初始化对话框
  19. BOOL CFinderDemoDlg::OnInitDialog()
  20. {
  21. CDialog::OnInitDialog();
  22. // IDM_ABOUTBOX must be in the system command range.
  23. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  24. ASSERT(IDM_ABOUTBOX < 0xF000);
  25. m_ListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_TRACKSELECT|LVS_EX_FLATSB|LVS_EX_UNDERLINEHOT|LVS_EX_GRIDLINES);//具体参考https://docs.microsoft.com/zh-cn/windows/win32/Controls/extended-list-view-styles
  26. m_ListCtrl.InsertColumn(0,T("文件名"),LVCFMT_IMAGE|LVCFMT_LEFT,80,80);//插入一列
  27. m_ListCtrl.InsertColumn(1,T("路径"),LVCFMT_LEFT,180);
  28. m_ListCtrl.InsertColumn(2,T("大小"),LVCFMT_LEFT,80);
  29. m_ListCtrl.InsertColumn(3,T("类型"),LVCFMT_LEFT,80);
  30. m_ListCtrl.SetHoverTime(500);//设置列表视图控件的当前逗留时间
  31. finder.ThreadSet(30);
  32. m_ListCtrl.SetRedraw();//数据更新时闪烁
  33. UIControl(false);
  34. CMenu* pSysMenu = GetSystemMenu(FALSE);// 返回当前使用窗口菜单的拷贝的句柄。该拷贝初始时与窗口菜单相同,但可以被修改。
  35. if (pSysMenu != NULL)
  36. {
  37. CString strAboutMenu;
  38. strAboutMenu.LoadString(IDS_ABOUTBOX);
  39. if (!strAboutMenu.IsEmpty())
  40. {
  41. pSysMenu->AppendMenu(MF_SEPARATOR);//画一条水平区分线
  42. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);//将IDM_ABOUTBOX添加到菜单中
  43. }
  44. }
  45. //设置图标
  46. SetIcon(m_hIcon, TRUE); // 设置大图标
  47. SetIcon(m_hIcon, FALSE); // 设置小图标
  48. // TODO: Add extra initialization here
  49. return TRUE; // return TRUE unless you set the focus to a control
  50. }

2)数据交换函数和消息响应函数

将控件的值传给类中的将变量的值显示到控件上;以及对相关消息的响应函数(如开始、暂停、显示“正在查找的文件”的函数…)

  1. void CFinderDemoDlg::DoDataExchange(CDataExchange* pDX)
  2. {
  3. CDialog::DoDataExchange(pDX);
  4. //{{AFX_DATA_MAP(CFinderDemoDlg)
  5. //将控件的值传递给指定变量假设为类型1,将变量的值传递给控件假设为类型2
  6. DDX_Control(pDX, IDC_LIST, m_ListCtrl);//类型2
  7. DDX_Control(pDX, IDC_STOP, m_stop);//将IDC_STOP窗口的值传递给m_stop
  8. DDX_Control(pDX, IDC_PAUSE, m_pause);//类型1
  9. DDX_Control(pDX, IDC_START, m_start);//类型1
  10. DDX_Text(pDX, IDC_ACTIVE_THREAD, m_ActiveCount);//将m_ActiveCount的值显示到IDC_ACTIVE_THREAD窗口
  11. DDX_Text(pDX, IDC_FOLDER, m_folder);//类型1
  12. DDX_Text(pDX, IDC_COUNT, m_count);//类型2
  13. DDX_Text(pDX, IDC_FINDING_FOLDER, m_findfolder);//将m_findfolder的值显示到IDC_FINDING_FOLDER窗口
  14. DDX_Text(pDX, IDC_INCLUDE_TEXT, m_text);//类型1
  15. DDX_Text(pDX, IDC_FILENAME, m_filename);//类型1
  16. DDX_Text(pDX, IDC_THREAD_NO, m_threadcount);//类型1
  17. //DDX_Text(pDX, IDC_PRIORITY, m_priority);
  18. //}}AFX_DATA_MAP
  19. }
  20. BEGIN_MESSAGE_MAP(CFinderDemoDlg, CDialog)//添加消息响应函数,为每个消息处理函数加入一个入口。
  21. ON_WM_SYSCOMMAND()//系统消息
  22. ON_WM_PAINT()//绘图消息
  23. ON_WM_QUERYDRAGICON()//查询icon消息
  24. ON_BN_CLICKED(IDC_STOP, OnStop)//停止
  25. ON_BN_CLICKED(IDC_START, OnStart)//开始
  26. ON_BN_CLICKED(IDC_PAUSE, OnPause)//暂停
  27. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)//选择文件
  28. ON_EN_CHANGE(IDC_THREAD_NO, OnChangeThreadNo)//设置线程数
  29. ON_MESSAGE(WM_THREADEXIT, OnFindExit)//查找时停止
  30. ON_MESSAGE(WM_THREADCOUNT, OnFindThreadCount)
  31. ON_MESSAGE(WM_FINDERITEM , OnFindItem)
  32. ON_MESSAGE(WM_THREADPAUSE, OnFindPause)//查找时暂停
  33. ON_MESSAGE(WM_FINDERFOLDER, OnFindingFolder)//正在查找
  34. ON_EN_CHANGE(IDC_FOLDER, &CFinderDemoDlg::OnEnChangeFolder)
  35. END_MESSAGE_MAP()

3)文件相关函数,OnBrowse()选择在哪个路径进行查找文件;修改查找文件的线程数的OnChangeThreadNo()函数;

点击选择文件按钮,触发OnBrowse事件处理函数,打开选择文件路径的面板;在mfc界面上设置线程数目,通过值交换函数,将控件上的值赋给相关类的成员变量,再通过OnChangeThreadNo()函数修改创建线程是默认设置的线程数目为新的值

  1. //选择查找文件路径
  2. void CFinderDemoDlg::OnBrowse()
  3. {
  4. // TODO: Add your control notification handler code here
  5. BROWSEINFO bi;
  6. char dispname[MAX_PATH], path[MAX_PATH];
  7. ITEMIDLIST* pidl;
  8. //
  9. bi.hwndOwner = m_hWnd;
  10. bi.pidlRoot = 0;
  11. bi.pszDisplayName = dispname;
  12. bi.lpszTitle = "请选择查找目录:";
  13. bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_DONTGOBELOWDOMAIN;
  14. bi.lpfn = 0;
  15. bi.lParam = 0;
  16. bi.iImage = 0;
  17. if (pidl = SHBrowseForFolder(&bi))
  18. {
  19. SHGetPathFromIDList(pidl, path);
  20. m_folder = CString(path);
  21. if (m_folder.IsEmpty())m_folder = GetAllDriverList();
  22. UpdateData(false);
  23. }
  24. }
  25. //当用户未指定查找路径时的默认路径
  26. CString CFinderDemoDlg::GetAllDriverList()
  27. {
  28. CString tmp = _T("D:"), Dir;//D:
  29. for (int i = 1; i <= 25; i++)
  30. {
  31. Dir = CString("D:" + i) + _T(":");
  32. if (GetDriveType(Dir.GetBuffer(0)) == DRIVE_NO_ROOT_DIR)continue;//判断该路径是否是有效的
  33. tmp += ";" + Dir;
  34. }
  35. return tmp;
  36. }
  37. //修改默认的线程数为我们MFC界面选择的线程数
  38. void CFinderDemoDlg::OnChangeThreadNo()
  39. {
  40. int count=GetDlgItemInt(IDC_THREAD_NO);
  41. if(count<1||count>99){count=10;SetDlgItemInt(IDC_THREAD_NO,count);}
  42. //finder.ThreadSet(count,finder.GetThreadPrioriy());
  43. finder.ThreadSet(count, m_priority);
  44. }

4)开始、暂停、停止查找文件的函数

  1. //开始
  2. void CFinderDemoDlg::OnStart()
  3. {
  4. // TODO: Add your control notification handler code here
  5. // ::SendMessage(GetSafeHwnd(),WM_THREADCOUNT,(WPARAM)100,NULL);
  6. UpdateData(true);//刷新控件的值到变量
  7. m_count = _T("0");
  8. m_ActiveCount = _T("0");
  9. count = 0;
  10. m_imglist.DeleteImageList();
  11. m_imglist.Create(16, 16, ILC_MASK | ILC_COLORDDB, 1, 100);//新建一个图像列表,然后用add添加图标(这里在OnFindItem函数使用到了)
  12. m_ListCtrl.SetImageList(&m_imglist, LVSIL_SMALL);//再将该列表中的图像绑定到m_ListCtrl列表控件上
  13. m_ListCtrl.DeleteAllItems();
  14. UpdateData(false);//将变量刷新到控件进行显示
  15. finder.FinderSet(GetSafeHwnd(), m_filename, m_folder);
  16. finder.FindWithText(m_text, m_text.GetLength());
  17. finder.StartFinder();
  18. UIControl(true);//开始后就调用UIControl进制相关控件接收鼠标或键盘消息
  19. }
  20. //暂停
  21. void CFinderDemoDlg::OnPause()
  22. {
  23. // TODO: Add your control notification handler code here
  24. static BOOL ispause = true;
  25. if (ispause)
  26. {
  27. m_pause.SetWindowText("继续");//如果是暂停状态就将按钮修改为“继续”
  28. finder.PauseFinder();
  29. ispause = false;
  30. }
  31. else
  32. {
  33. m_pause.SetWindowText("暂停");
  34. finder.ResumeFinder();
  35. ispause = true;
  36. }
  37. }
  38. //停止
  39. void CFinderDemoDlg::OnStop()
  40. {
  41. // TODO: Add your control notification handler code here
  42. finder.StopFinder();
  43. }
  44. //弹出框
  45. LRESULT CFinderDemoDlg::OnFindExit(WPARAM wparam, LPARAM lparam)
  46. {
  47. m_pause.SetWindowText("暂停");
  48. UIControl(false);
  49. if (wparam == 1)AfxMessageBox("停止查找!");//:AfxMessageBox比MessageBox简单一些,因为它是一个全局函数所以不需要对应的一个窗口类,但是不能控制消息框标题
  50. else AfxMessageBox("查找结束!");
  51. m_ListCtrl.RedrawItems(0, count - 1);//暂停时只显示现在查到的
  52. return 0;
  53. }
  54. LRESULT CFinderDemoDlg::OnFindPause(WPARAM wparam, LPARAM lparam)
  55. {
  56. AfxMessageBox("用户暂停!");
  57. return 0;
  58. }

5)界面更新函数,如更新当前活动线程数,查找到符合的文件数目,开始、暂停、停止的按钮状态,显示正在查找的文件,显示已经找到的符合的文件

  1. LRESULT CFinderDemoDlg::OnFindExit(WPARAM wparam,LPARAM lparam)
  2. {
  3. m_pause.SetWindowText("暂停");
  4. UIControl(false);
  5. if(wparam==1)AfxMessageBox("停止查找!");//:AfxMessageBox比MessageBox简单一些,因为它是一个全局函数所以不需要对应的一个窗口类,但是不能控制消息框标题
  6. else AfxMessageBox("查找结束!");
  7. m_ListCtrl.RedrawItems(0,count-1);//暂停时只显示现在查到的
  8. return 0;
  9. }
  10. LRESULT CFinderDemoDlg::OnFindPause(WPARAM wparam,LPARAM lparam)
  11. {
  12. AfxMessageBox("用户暂停!");
  13. return 0;
  14. }
  15. //查找到的文件的文件信息
  16. LRESULT CFinderDemoDlg::OnFindItem(WPARAM wparam,LPARAM lparam)
  17. {
  18. m_count.Format("%d",++count);
  19. UpdateData(false);
  20. CString pathname=*((CString *)wparam);
  21. CFileStatus Status;
  22. CFile::GetStatus(pathname,Status);
  23. CString Unit="Byte";
  24. float flen=(float)Status.m_size;
  25. if(flen>1024)
  26. {
  27. flen/=1024;
  28. if(flen<1024){Unit="KB";}
  29. else{flen/=1024;Unit="MB";}
  30. }
  31. CString Size;
  32. Size.Format("%1.2f",flen);
  33. int pos=pathname.ReverseFind('');
  34. SHFILEINFO sfi;
  35. if (::SHGetFileInfo (pathname, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO),SHGFI_USEFILEATTRIBUTES | SHGFI_DISPLAYNAME | SHGFI_TYPENAME |SHGFI_ICON|SHGFI_SMALLICON ))
  36. {
  37. //更新mfc界面的list框显示
  38. m_imglist.Add(sfi.hIcon);
  39. m_ListCtrl.InsertItem(count-1,sfi.szDisplayName,count-1);
  40. m_ListCtrl.SetItemText(count-1,1,pathname.Mid(0,pos));
  41. m_ListCtrl.SetItemText(count-1,2,(Size+Unit));
  42. m_ListCtrl.SetItemText(count-1,3,sfi.szTypeName);
  43. }
  44. m_ListCtrl.Update(count-1);
  45. PeekAndPump();
  46. return 0;
  47. }
  48. //在MFC界面显示当前活动的线程数
  49. LRESULT CFinderDemoDlg::OnFindThreadCount(WPARAM wparam,LPARAM lparam)
  50. {
  51. m_ActiveCount.Format("%ld",LONG(wparam));
  52. UpdateData(FALSE);
  53. return 0;
  54. }
  55. //在mfc界面显示当前正在查询的文件路径
  56. LRESULT CFinderDemoDlg::OnFindingFolder(WPARAM wparam,LPARAM lparam)
  57. {
  58. m_findfolder=*((CString *)wparam);
  59. UpdateData(false);
  60. return 0;
  61. }
  62. /控制相关控件的状态
  63. void CFinderDemoDlg::UIControl(BOOL bOp)//start with true;
  64. {
  65. m_start.EnableWindow(!bOp);
  66. m_stop.EnableWindow(bOp);
  67. m_pause.EnableWindow(bOp);
  68. GetDlgItem(IDC_THREAD_NO)->EnableWindow(!bOp);//EnableWindow函数允许/禁止指定的窗口或控件接受鼠标和键盘的输入
  69. GetDlgItem(IDC_SPIN_THREAD_NO)->EnableWindow(!bOp);
  70. }

windows核心编程课程实践---多线程文件搜索器(MFC界面)的更多相关文章

  1. 【Windows核心编程】一个使用内存映射文件进行进程间通信的例子

    进程间通信的方式有很多种,其底层原理使用的都是内存映射文件. 本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信. 进程1 按钮[Create  mappin ...

  2. 《windows核心编程系列》十六谈谈内存映射文件

    内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了 ...

  3. C++Windows核心编程读书笔记

    转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...

  4. 【转】《windows核心编程》读书笔记

    这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...

  5. windows核心编程---第八章 使用内核对象进行线程同步

    使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...

  6. 《Windows核心编程》第一讲 对程序错误的处理

    一个Windows函数通常都有一个有意义的返回值类型,它标志着这个函数的运行状态,即函数运行成功与否.windows常用的函数类型如下图: 从系统内部来讲,当一个Windows函数检测到一个错误时,它 ...

  7. 《Windows核心编程》读书笔记 上

    [C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...

  8. 【Windows】windows核心编程整理(上)

    小续 这是我11年看<windows核心编程>时所作的一些笔记,现整理出来共享给大家 windows核心编程整理(上) windows核心编程整理(下) 线程的基础知识 进程是不活泼的,进 ...

  9. 《windows核心编程系列》十七谈谈dll

    DLL全称dynamic linking library.即动态链接库.广泛应用与windows及其他系统中.因此对dll的深刻了解,对计算机软件开发专业人员来说非常重要. windows中所有API ...

随机推荐

  1. A. Guest From the Past(数学推式子)

    \(n元,买塑料杯子a元,买玻璃杯子b元,但玻璃杯子用完后可以卖c元\) \(求最多买的杯子.\) \(---------------------------分割------------------- ...

  2. 【Scala】利用akka实现Spark启动通信

    文章目录 思路分析 步骤 一.创建maven工程,导包 二.master进程代码开发 三.worker进程代码开发 思路分析 1.首先启动master,然后依次启动worker 2.启动worker时 ...

  3. 标准IDOC同步采购订单

    目录 1功能说明    4 2功能实现    4 2.1创建逻辑系统并分配集团(SALE)    4 2.2维护RFC目标(SM59)    5 2.3在发送端创建模型视图(BD64)    5 2. ...

  4. 局域网ip地址扫描_v1版本

    局域网ip地址扫描 工作中,我们有时需要对局域网中ip地址使用情况进行统计.可以使用shell脚本进行扫. 脚本功能: 在线使用IP写入list_online.txt文件 未在线IP写入list_of ...

  5. Android ListView 代码1

    目录 ListView效果 一.ListView的简单用法 二.定制ListView的界面 目标 步骤 1.定义一个实体类作为ListView适配器的适配对象. 2.为ListView的子项指定我们的 ...

  6. Linux 面试最常问的十个问题

    如果你要去面试一个Linux系统运维工程师的职位,下面这十个最常见的问题一定要会,否则你的面试可能就危险了.这些都是比较基本的问题,大家要理解,不能光死记硬背. 1.如何查看系统内核的版本 这里有两种 ...

  7. java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized的报错问题

    url的问题 这个是根据使用的数据库版本不同而出现的错误,mysql8.0以上版本在使用URL时如果使用的语句是 url=jdbc:mysql://localhost:3306/book 是会报错的, ...

  8. java ->Date、DateFormat、Calendar类

    Date类概述 类 Date 表示特定的瞬间,精确到毫秒. 毫秒概念:1000毫秒=1秒 毫秒的0点: System.currentTimeMillis()  相当于Date d = new Date ...

  9. 04 返回静态文件的函数web框架

    04 返回静态文件的函数web框架 服务器server端python程序(函数版): import socket server = socket.socket() server.bind((" ...

  10. mysql小白系列_05 日常操作

    mysql启动/关闭 my.cnf的调用顺序 [root@docker02 bin]# ./mysql --help Default options are read from the followi ...