VC++開發垃圾文件清理軟件之二:垃圾文件的掃描、顯示和清理


先說下哈,有人說要源代碼,源代碼在博文《VC++開發垃圾文件清理軟件之四:程序的界面設計與實現----按鈕控件界面》的最后給出下載地址供大家下載。

上一篇我們說明了程序的概述以及需求分析等,程序的初始化界面為:

                                                          界面圖

 

下面我們就是開始代碼實現了,下面先開始實現功能部分,即垃圾文件的掃描、顯示和清理。

功能的分析與設計:垃圾清理功能主要包括文件遍歷掃描、顯示已掃描到的文件以及垃圾文件的刪除清理等。用戶需要一邊進行文件掃描,另一邊可以對已經掃描到的垃圾文件進行清理操作。文件掃描通常會占用大量的時間,為了提高垃圾清理的可靠性和效率,應該使用多線程開發技術,即將文件掃描的任務放置在一個單獨的線程中即可

(1)創建一個基於對話框的工程,工程名稱為“ClearTmpFile”。

(2)向對話框中添加靜態文本框、按鈕、組合框、列表框、進度條等控件,效果如下:

                                                     控件布局圖

(3)在對話框類CClearTmpFileDlg中添加共有的主要數據成員,各成員功能見注釋部分:

 

CList<CString, CString> m_fileExtList;//記錄需要查找臨時文件擴展名
    bool m_bThreadExit;//線程是否退出
    bool m_bFinding;//是否查找進行中
    HANDLE m_hThread;//查找文件的線程句柄
    HANDLE m_hThread2;//bmp旋轉線程句柄
    CString m_szCurDisk;//查找的磁盤
    HANDLE m_hEvent;//事件對象,在對話框關閉時將提前結束查找
    bool m_bContinue;//判斷暫停或繼續按鈕操作
    DWORD GetDiskSize(char* strPath);//獲取磁盤容量(已使用的)
    DWORD m_dwDiskVol;//磁盤總容量大小,單位為KB
    DWORD m_dwScanedVol;//已掃描的文件的容量
    DWORD m_dwScanedTmpFileVol;//掃描到的臨時文件的容量大小
    DWORD m_dwScanedTmpFileNum;//掃描到的臨時文件的容量大小

(4)向對話框類中添加ResearchFile方法,判讀指定的目錄,將指定的垃圾文件類型顯示在掃描結果列表中。

void CClearTmpFileDlg::ResearchFile(char * pszPath)
{    
    char szTmp[MAX_PATH]={0};//定義一個臨時字符數組
    strcpy(szTmp,pszPath);
    if(szTmp[strlen(szTmp)-1]!='\\')//將目錄以“\\*.*”形式結尾
    {
        strcat(szTmp,"\\*.*");//連接字符串
    }
    else
    {
        strcat(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))
            {
                DWORD dwFileSize = (findData.nFileSizeHigh* (MAXDWORD+1) + findData.nFileSizeLow)/(1024);//獲取文件大小,單位為KB
                m_dwScanedVol += dwFileSize;//累計已掃描文件的容量大小,單位為KB
                //m_dwScanedVol = m_dwScanedVol/1024;//單位轉換為:MB
                //設置進度條進度
                m_progressCtl.SetPos((m_dwScanedVol/1024));
                char szFileName[MAX_PATH] = {0};//定義字符數組,存儲完整的文件名
                strcpy(szFileName,pszPath);//獲取完整文件名
                if(szFileName[strlen(szFileName)-1] != '\\')
                {
                    strcat(szFileName,"\\");
                }
                strcat(szFileName,(char *)findData.cFileName);
                
                if(IsTmpFile(szFileName))//判斷szFileName是否是臨時文件
                {
                    m_dwScanedTmpFileVol += dwFileSize;//累計掃描到的臨時文件容量大小,單位為KB
                    m_dwScanedTmpFileNum ++;//累計掃描到的臨時文件的數目
                    m_listBoxResults.AddString((LPCTSTR)szFileName);
                }
            }
            else//如果文件是一個目錄,則遞歸遍歷該目錄
            {
                if((strcmp((const char *)&findData.cFileName,"...")!=0) &&
                    (strcmp((const char *)&findData.cFileName,"..")!=0)&&
                    (strcmp((const char *)&findData.cFileName,".")!=0))
                {
                    char szFileName[MAX_PATH]={0};
                    strcpy(szFileName,pszPath);//獲取完整文件名
                    if(szFileName[strlen(szFileName)-1]!='\\')
                    {
                        strcat(szFileName,"\\");
                    }
                    strcat(szFileName,(char *)findData.cFileName);
                    //由於查找是在線程中進行的,這里判讀用戶是否退出線程,如果是則提前結束線程函數
                    if(m_bThreadExit)
                    {
                        FindClose(hFind);//關閉查找句柄
                        SetEvent(m_hEvent);//設置事件為有信號
                        return;
                    }
                    ResearchFile(szFileName);//遞歸調用
                }
            }
        }
    }
    FindClose(hFind);//關閉文件查找句柄
}

(5)定義線程函數,用來單獨執行掃描查找垃圾文件任務:

DWORD _stdcall FindTmpFile(LPVOID lpParameter)
{
    CClearTmpFileDlg* pDlg = (CClearTmpFileDlg*) lpParameter;//獲取線程參數
    WaitForSingleObject(pDlg->m_hEvent,INFINITE);//等待事件有信號
    CString dir = pDlg->m_szCurDisk.GetBuffer();//根據當前盤符目錄磁盤目錄
    char *s = (LPSTR)(LPCTSTR)dir;        
    pDlg->ResearchFile(s);    
    pDlg->Restore();
    pDlg->ShowResultText();//顯示掃描臨時文件的數目和大小    
    //恢復數據為初始狀態
    pDlg->m_dwScanedTmpFileVol = 0;
    pDlg->m_dwScanedTmpFileNum = 0;
    pDlg->m_fileExtList.RemoveAll();
    return 0;
}

(6)處理“立即掃描”或“開始”按鈕的單擊事件,創建一個新的線程執行掃描文件的任務:

//如果查找沒有結束,則不允許開始新的文件查找
    GetDlgItem(IDC_BEGIN)->ShowWindow(SW_HIDE);
    if(!m_bFinding && GetTmpExtName())//獲取文件擴展名
    {
        GetDlgItem(IDC_PROGRESS1)->ShowWindow(TRUE);//顯示進度條        
        GetDlgItem(IDC_LIST1)->ShowWindow(SW_SHOW);        
        m_bThreadExit  = FALSE;
        m_bFinding = TRUE;
        m_combox.GetWindowText(m_szCurDisk);//獲取當前盤符        
        // 初始化進度條相關數據
        m_dwDiskVol =GetDiskSize((LPSTR)(LPCTSTR)m_szCurDisk);//獲取當前磁盤的容量大小(已使用的)
        CString str;
        str.Format(_T("%d"),m_dwDiskVol/(1024));
        double iSize = atoi(str);
        m_progressCtl.SetRange32(0,m_dwDiskVol/1024);//初始化進度條,設置進度條的范圍,范圍為MB的數量
        if(m_hEvent!=NULL)
        {
            CloseHandle(m_hEvent);//關閉事件對象
            m_hEvent = NULL;
        }
        m_listBoxResults.ResetContent();//清空查找結果列表
        m_hEvent = CreateEvent(NULL,FALSE,TRUE,_T("Event"));//創建事件對象
        //創建一個線程,開始執行線程函數
        m_hThread = CreateThread(NULL,0,FindTmpFile,this,0,NULL);    
        m_hThread2 = CreateThread(NULL,0,RotatingImg,this,0,NULL);            
        UpdateData(FALSE);

(7)清理已掃描到的垃圾文件,即采用刪除文件策略,使用DeleteFile()方法:

void CClearTmpFileDlg::OnBnClickedDelall()
{//刪除已掃描到的垃圾文件
    CString strDel;
    CFile file;
    for(int i=0;i<m_listBoxResults.GetCount();i ++)
    {
        
        m_listBoxResults.GetText(i,strDel);
        GetDlgItem(IDC_TEST)->SetWindowText(strDel);
        DeleteFile(strDel);//刪除指定路徑的文件    
    }
    m_listBoxResults.ResetContent();
    GetDlgItem(IDC_TEST)->SetWindowText(_T("清理完畢!"));
    GetDlgItem(IDC_LIST1)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_BEGIN)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_BEGIN)->SetWindowText(_T("重新掃描"));
}

好了,到此差不多軟件的主要功能部分都已經開發完畢,大家已經看出來了,功能部分很簡單,就是對指定的文件格式進行掃描、顯示和清理。下面將進行對軟件界面的設計與開發。

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM