MFC TreeControl複選框:選中某個節點的複選框後,自動選中子節點的複選框
阿新 • • 發佈:2019-02-17
1、實現選中TreeControl中的某個複選框,子節點的複選框自動選中:
2、如上例,當點選根節點Windows前的複選框時,它的所有子節點前面的複選框都被選中;
3、實現該功能的思路是:當用戶勾選某個複選框時,遍歷該節點的子節點,將所有的子節點複選框狀態改為和點選複選框的狀態(點選後)一致;其中有兩個實現的難點:
(1)如何確定使用者勾選了複選框,以及具體勾選了那個複選框;
(2)如何改變所有子節點的複選框;沒有什麼好辦法,只有通過遍歷,然後一項一項的修改;在此提一點,如果TreeControl的節點可能很多,最好不要用遞迴演算法,以防止棧溢位;
(3)最後一點,只要編寫程式碼都會發現,在此提一下:
那就是,在NM_CLICK訊息的響應函式中是,雖然滑鼠點選了某個複選框,但是此時該複選框的狀態實際上還沒改變;
注意:滑鼠點選CheckBox時,訊息的順序是 NM_CLICK —> LVN_ITEMCHANGED,即CheckBox的狀態是在 NM_CLICK訊息函式結束後才會發生變化,在NM_CLICK中使用GetCheck無效(或者說獲得的複選框狀態是相反的)。
4、關鍵程式碼:用棧實現的遍歷函式:
int ChildNodeChanged(HTREEITEM hitemNode, BOOL nState) { stack <HTREEITEM> stackTreeItem; HTREEITEM hitemNext = m_ctlTree.GetChildItem(hitemNode); stackTreeItem.push(hitemNext); while ( !stackTreeItem.empty() ) { hitemNext = stackTreeItem.top(); stackTreeItem.pop(); while ( hitemNext != NULL ) { if ( nState == BST_CHECKED ) { m_ctlTree.SetCheck(hitemNext); } else { m_ctlTree.SetCheck(hitemNext, BST_UNCHECKED); } HTREEITEM hitemChild = m_ctlTree.GetChildItem(hitemNext); if ( hitemChild != NULL ) { stackTreeItem.push(hitemChild); } hitemNext = m_ctlTree.GetNextItem(hitemNext, TVGN_NEXT); } } return 0; }