首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 樹狀控件遞迴收集子節點文字:高效替代資料庫查詢

     編輯:關於VC++

在樹狀結構中點選節點後,需取得該節點及所有子孫節點的文字集合。早期做法常查詢資料庫,導致回應緩慢。本文提供純記憶體遞迴函式 ReturnTreeChilds,直接遍歷 CTreeCtrl 節點收集文字,效能大幅提升。

核心遞迴函式

CString CTreeDataDlg::ReturnTreeChilds(HTREEITEM hParent) { CString strResult; // 1. 取得目前節點文字 strResult = m_ctrlTree.GetItemText(hParent); // 2. 取得第一個子節點 HTREEITEM hChild = m_ctrlTree.GetChildItem(hParent); while (hChild) { // 2.1 若有子節點 → 遞迴處理 if (m_ctrlTree.GetChildItem(hChild)) strResult += _T(",") + ReturnTreeChilds(hChild); else strResult += _T(",") + m_ctrlTree.GetItemText(hChild); // 2.2 移至下一個兄弟節點 hChild = m_ctrlTree.GetNextSiblingItem(hChild); } return strResult; }

演算法流程:

  1. 將目前節點文字存入結果字串。
  2. 取得第一個子節點 (GetChildItem)。
  3. While 迴圈遍歷所有兄弟節點:
    • 判斷是否有子節點:有 → 遞迴呼叫;無 → 直接附加文字。
    • 取得下一個兄弟節點 (GetNextSiblingItem),直到 NULL 結束。
  4. 回傳累積的逗號分隔字串。

整合到選取變更事件

void CTreeDataDlg::OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTV = (NM_TREEVIEW*)pNMHDR; HTREEITEM hSel = m_ctrlTree.GetSelectedItem(); HTREEITEM hParent = m_ctrlTree.GetParentItem(hSel); // 更新選取節點圖示 (選取狀態) m_ctrlTree.SetItemImage(hSel, 1, 1); // 取得父節點文字 (若有需要) CString strParentText = m_ctrlTree.GetItemText(hParent); // 核心:收集目前節點及所有子孫文字 if (m_ctrlTree.GetChildItem(hSel)) m_strEdit = ReturnTreeChilds(hSel); // 有子節點 → 遞迴 else m_strEdit = m_ctrlTree.GetItemText(hSel); // 葉節點 → 直接取文字 UpdateData(FALSE); // 顯示到 Edit Control *pResult = 0; }

優勢分析

指標資料庫查詢法記憶體遞迴法
回應速度慢 (網路延遲 + SQL 執行)極快 (純記憶體操作)
資料一致性需同步機制即時反映樹狀狀態
程式複雜度高 (SQL、Connection、Recordset)低 (單一遞迴函式)
適用場景資料量極大、需持久化查詢中小型樹狀結構、即時互動

注意事項

  • 樹節點數量超過數萬時,遞迴深度可能導致堆疊溢位,建議改用非遞迴堆疊模擬或分頁載入。
  • 回傳字串若過長,考慮改用 CStringArray 或 std::vector<CString> 回傳集合,避免字串拼接效能問題。
  • 若樹狀資料來源本身為資料庫,建議啟動時一次性載入記憶體建樹,後續操作皆在記憶體進行。

本技巧適用於目錄管理、BOM 物料清單、組織架構等「點選節點顯示完整子樹資訊」的常見需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved