本文是對第20期中"遍歷文件夾並建成目錄樹"一文的補充。
CTreeCtrl是可是化編程中很實用的一個類,可以用於目錄結構、層次結構、屬性結構,尤其是在顯示文件目錄結構時更是應用廣泛。看了第20期北京林業大學的李少傑朋友的一篇"遍歷文件夾並建成目錄樹",覺得深有感觸,初學VC時確實CTreeCtrl類很難掌握;至於對"樹的遍歷",也是數據結構的一個難點。李朋友的那篇文章解決了如果用CTreeCtrl顯示目錄結構,在他程序中,沒有能夠完善解決如何遞歸未知層數的目錄的問題,(在CtreeCtrl的使用和函數的遞歸調用上有不足之處),我想對這個問題作一點補充。
我的這個程序可以搜任意層目錄,其輸出結果如下:
下面我談談怎麼編寫這個程序:
首先,也是用MFC AppWizard[exe]生成一個dialog base的框架,在上面放一個Tree控件,並創建一個成員函數m_Tree來指向這個控件。
之後,編寫遞歸搜索函數 void AddFile( CString StrPath, HTREEITEM faItem );最後,在OnInitDialog()中調用AddFile,這樣在程序已開始運行就顯示Tree。
詳細的內容請參考附帶的源代碼。
下面,我將著重講講如何編寫AddFile函數。對於文件目錄結構的遍歷,選用遞歸算法是不錯的。用遞歸方法對樹進行遍歷常用的有深度優先和廣度優先兩種搜索方法,由於我們要遍力整個樹,所以選用深度優先的算法是不錯的。因為在這裡,深度優先和廣度優先的時間復雜度一樣,但是深度優先比較節省堆棧資源。以下,就是采用深度優先搜索的AddFile函數,我將在程序中作進一步說明。
// 遞歸搜索文件路徑,采用深度優先搜索法void CFileTreeDlg::AddFile(CString StrPath, HTREEITEM faItem )
//StrPath為傳遞過來的目錄層次,本次函數調用中搜索的文件都是它的下一層的。
//faItem為傳遞過來的Tree節點,本次函數調用中添加的Tree節點都是它的子節點。
{
CFileFind OneFile;
CString FName, DirName;
BOOL BeWorking;
HTREEITEM NewItem;
DirName = StrPath+"*.*";
BeWorking = OneFile.FindFile( DirName );
while ( BeWorking ) { //BeWorking非零,指找了文件或目錄
//查找同級的目錄
BeWorking = OneFile.FindNextFile();
if ( OneFile.IsDirectory() && !OneFile.IsDots() ) //如果查找的結果是目錄又不是".."或"."
{
//向Tree1中添加目錄;
DirName = OneFile.GetFilePath();
FName = OneFile.GetFileTitle();
//IDC_TREE1
NewItem = m_Tree.InsertItem( FName, faItem ); //NewItem取得節點,其目的是為了下一層中
//添加節點方便,遞歸時把它傳過去。
//進入下一層遞歸調用。
AddFile(DirName, NewItem);
}
//退出遞歸時,到了這裡!!!
if ( !OneFile.IsDirectory() && !OneFile.IsDots() ) //如果查找結果是文件
{
//向Tree1中添加文件
FName = OneFile.GetFileTitle(); //注意這裡用的是GetFileTitle,因為
//這裡是添加文件。
m_Tree.InsertItem( FName, faItem );
}
}// end of while
OneFile.Close(); //記著用完CFileFild實例要關閉
}
以上程序在 VC6 professional + sp5 上通過,操作系統是 Win2000 professional。