当前位置:C++技术网 > 资讯 > 清理垃圾文件软件源代码解析2

清理垃圾文件软件源代码解析2

更新时间:2015-11-13 21:58:47浏览次数:1+次

线程是个好东西啊!在这里,我们就是利用线程来实现临时文件查找。

下面我们接着处理"开始按钮"单击事件:


void CClearTmpFileDlg::OnFindfile()				//查找临时文件
{
	if (!m_bFinding && GetTmpExtName())	//获取文件扩展名
	{
		m_bThreadExit = FALSE;
		m_bFinding = TRUE;

		m_Disk.GetWindowText(m_szCurDisk);
		if (m_hEvent != NULL)
		{
			CloseHandle(m_hEvent);
			m_hEvent = NULL;
		}
		m_FindList.ResetContent();
		m_hEvent = CreateEvent(NULL, FALSE, TRUE, "Event");
		m_hThread = CreateThread(NULL, 0, FindTmpFile, this, 0, NULL);
		m_FindResult1.SetWindowText("查找进行中...");
	}
}
消息响应函数的实现及声明我在《清理垃圾文件软件源代码解析1》解释了,我们在电脑磁盘中查询临时垃圾文件是通过什么?就是文件后缀,因此,单击事件的第一句代码就是获取文件后缀名,在这里,我们有需要另外声明一个函数GetTmpExtName来查找并获取我们的在列表框中选中的文件后缀。



BOOL CClearTmpFileDlg::GetTmpExtName()
{
	FreeFilterList();				//移除所有内容
	BOOL  bHasChecked = FALSE;	//是否有项目被选中
	int nItemCount = m_ExtList.GetCount();
	for (int i = 0; i<nItemCount; i++)		//遍历项目
	{
		if (m_ExtList.GetCheck(i) == BST_CHECKED)	//项目被选中
		{
			bHasChecked = TRUE;
			char *szText = new char[20];
			memset(szText, 0, 20);
			m_ExtList.GetText(i, szText);			//获取列表中临时文件扩展名
			m_FilterList.AddTail(szText);			//向列表尾添加数据
		}
	}
	return bHasChecked;
}
这个函数的主要实现代码与"全选"按钮的单击事件代码一样。就是判断有没有被选中,至于m_FilterList.AddTail(szText);我稍后会做解释,你现在不需要管。bHasChecked 作为返回值判断是否选择临时文件后缀。
我们回到"开始"按钮单击事件函数代码。程序运行到第一句代码之后就是跳到了GetTmpExtName函数,这个函数执行完后就会到"开始"按钮单击事件。在这里我们创建了线程对象Event这个对象与互斥器的原理差不多,都是实现线程同步。你如果不会线程,可以看看我写的线程系列的文章,搜索145742784这个作者名,查找与线程,互斥器有关的文章。下面我们进入线程函数:
DWORD __stdcall FindTmpFile(LPVOID lpParameter)
{
	CClearTmpFileDlg* pDlg = (CClearTmpFileDlg*)lpParameter;
	WaitForSingleObject(pDlg->m_hEvent, INFINITE);
	pDlg->ResearchFile(pDlg->m_szCurDisk.GetBuffer(0));
	pDlg->m_FindResult1.SetWindowText("查找结束!");

	pDlg->m_bFinding = FALSE;
	pDlg->m_hThread = NULL;
	SetEvent(pDlg->m_hEvent);
		return 0;
}
第一句代码你有没有疑问?很简单,这个函数是调用函数,它的参数是形参。我们需要获得与对话框类有关的参数,以这个参数来获取对话框类中的成员方法或变量。因此强制类型转换为对话框类的对象。这里的代码除了pDlg->ResearchFile(pDlg->m_szCurDisk.GetBuffer(0));
这句其他的都很容易。这句代码就是将我们带进ResearchFile函数,下面我们就进入这个函数:
void CClearTmpFileDlg::ResearchFile(char *pszPath)		//遍历磁盘目录,查找临时文件
{
	char szTmp[MAX_PATH] = { 0 };
	strcpy_s(szTmp, pszPath);
	if (szTmp[strlen(szTmp) - 1] != '\\')
	{
		strcat_s(szTmp, "\\*.*");
	}
	else
	{
		strcat_s(szTmp, "*.*");
	}
	WIN32_FIND_DATA findData;
	memset(&findData, 0, sizeof(WIN32_FIND_DATA));
	HANDLE hFind = FindFirstFile(szTmp, &findData);
	if (m_bThreadExit)
	{
		FindClose(hFind);
		SetEvent(m_hEvent);
		return;
	}
	if (hFind != INVALID_HANDLE_VALUE)
	{
		while (FindNextFile(hFind, &findData) == TRUE)
		{
			if (m_bThreadExit)
			{
				FindClose(hFind);
				SetEvent(m_hEvent);
				return;
			}
			if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			{
				char szFileName[MAX_PATH] = { 0 };
				//获取完整文件名
				strcpy_s(szFileName, pszPath);
				if (szFileName[strlen(szFileName) - 1] != '\\')
				{
					strcat_s(szFileName, "\\");
				}
				strcat_s(szFileName, findData.cFileName);
				//判断szFileName是否是临时文件
				if (IsTmpFile(szFileName))
				{
					m_FindList.AddString(szFileName);
				}
			}
			else
			{
				if ((strcmp(findData.cFileName, "...") != 0) &&
					(strcmp(findData.cFileName, "..") != 0) &&
					(strcmp(findData.cFileName, ".") != 0))
				{
					char szFileName[MAX_PATH] = { 0 };
					//获取完整文件名
					strcpy_s(szFileName, pszPath);
					if (szFileName[strlen(szFileName) - 1] != '\\')
					{
						strcat_s(szFileName, "\\");
					}
					strcat_s(szFileName, findData.cFileName);
					if (m_bThreadExit)
					{
						FindClose(hFind);
						SetEvent(m_hEvent);
						return;
					}
					ResearchFile(szFileName);
				}
			}
		}
	}
	FindClose(hFind);
}
在这里,我先不讲解代码原理。线程在这个工程里面就是主函数代码之外再开辟一块,来查找临时处理文件,接着处理它们。


同时请你们先看看我写的这篇文章《WIN32_FIND_DATA结构体及文件查找程序小解