在樹狀結構中點選節點後,需取得該節點及所有子孫節點的文字集合。早期做法常查詢資料庫,導致回應緩慢。本文提供純記憶體遞迴函式 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;
}
演算法流程:
GetChildItem)。GetNextSiblingItem),直到 NULL 結束。
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 物料清單、組織架構等「點選節點顯示完整子樹資訊」的常見需求。