1、实现选中TreeControl中的某个复选框,子节点的复选框自动选中:
2、如上例,当点击根节点Windows前的复选框时,它的所有子节点前面的复选框都被选中;
3、实现该功能的思路是:当用户勾选某个复选框时,遍历该节点的子节点,将所有的子节点复选框状态改为和点击复选框的状态(点击后)一致;其中有两个实现的难点:
(1)如何确定用户勾选了复选框,以及具体勾选了那个复选框;
关于本条,参见文章:http://blog.csdn.net/wwkaven/article/details/40821463
(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;
}
5、示例工程:http://download.csdn.net/detail/wwkaven/8123169