在 MFC 對話框應用程序中,需要遞歸遍歷指定目錄及其子目錄,將所有文件和文件夾結構以 Tree Control(樹形控件)形式展示。
CTreeCtrl 控件,設置屬性 TVS_HASLINES、TVS_LINESATROOT、TVS_HASBUTTONS 以顯示連接線與展開按鈕。void PopulateTree(HTREEITEM hParent, const CString& strPath),使用 CFileFind 查找文件/目錄。m_treeCtrl.InsertItem 添加節點,目錄節點設置 TVIF_CHILDREN 標志以顯示「+」號。TVN_ITEMEXPANDING 通知,動態加載子目錄內容(延遲加載提高性能)。void CMyDialog::PopulateTree(HTREEITEM hParent, const CString& strPath)
{
CFileFind finder;
CString strSearch = strPath + _T("\\*.*");
BOOL bWorking = finder.FindFile(strSearch);
while (bWorking)
{
bWorking = finder.FindNextFile();
if (finder.IsDots()) continue;
HTREEITEM hItem = m_treeCtrl.InsertItem(finder.GetFileName(), hParent, TVI_LAST);
if (finder.IsDirectory())
{
m_treeCtrl.SetItemData(hItem, (DWORD_PTR)new CString(finder.GetFilePath()));
// 插入佔位符以顯示「+」號
m_treeCtrl.InsertItem(_T(""), hItem);
}
}
finder.Close();
}
// 响应 TVN_ITEMEXPANDING
void CMyDialog::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR);
if (pNMTreeView->action == TVE_EXPAND)
{
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
CString* pPath = (CString*)m_treeCtrl.GetItemData(hItem);
if (pPath)
{
// 移除佔位符
HTREEITEM hChild = m_treeCtrl.GetChildItem(hItem);
while (hChild)
{
HTREEITEM hNext = m_treeCtrl.GetNextSiblingItem(hChild);
m_treeCtrl.DeleteItem(hChild);
hChild = hNext;
}
// 遞歸加載真實子項
PopulateTree(hItem, *pPath);
}
}
*pResult = 0;
}
SHGetFileInfo 獲取系統圖標,為文件/目錄設置圖片列表(SetImageList)。CString 指針防止內存洩漏。完整項目示例可參考 CSDN 博客:MFC Tree Control 目錄遍歷實現