CTreeCtrl控件
更新CtreeCtrl状态的代码
添加带有CheckBox的Tree控件:
TreeCtrl.ModifyStyle(NULL,TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_CHECKBOXES); //设置Tree控件的样式
HTREEITEM hChina = TreeCtrl.InsertItem(_T("中国地图"), NULL, NULL);
HTREEITEM hHLJ = TreeCtrl.InsertItem(_T("黑龙江"), NULL, NULL, hChina);
添加点击CtreeCtrl控件的Click事件函数:
void CMyDlg::OnNMClickTree(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
DWORD dwPos = GetMessagePos();
CPoint point(LOWORD(dwPos), HIWORD(dwPos));
m_TreeCtrl.ScreenToClient(&point);
UINT nFlag;
HTREEITEM hTreeItem = m_TreeCtrl.HitTest(point, &nFlag);
//判断是否点在checkbox上 判断是否点在Item的文字上
if(nFlag == LVHT_TOLEFT || nFlag == TVHT_ONITEMLABEL)
{
if (!m_TreeCtrl.GetCheck(hTreeItem))
{
SelectChildItem(hTreeItem); //更新选中项的子项
SelectParentItem(hTreeItem); //更新选中项的父项
if (nFlag == TVHT_ONITEMLABEL)
{
m_TreeCtrl.SetCheck(hTreeItem);
}
}
else
{
UnSelectChildItem(hTreeItem); //更新去除选定项的子项
UnSelectParentItem(hTreeItem, true); //更新去除选定项的父项
if (nFlag == TVHT_ONITEMLABEL)
{
m_TreeCtrl.SetCheck(hTreeItem, 0);
}
}
}
*pResult = 0;
}
选中CtreeCtrl控件的Checkbox同时也要选中其所包含的所有子项:
void CMyDlg::SelectChildItem(HTREEITEM& hTreeItem)
{
HTREEITEM TreeChild = m_TreeCtrl.GetChildItem(hTreeItem);
while(NULL != TreeChild)
{
if (m_TreeCtrl.ItemHasChildren(TreeChild))
{
SelectChildItem(TreeChild);
}
m_TreeCtrl.SetCheck(TreeChild);
TreeChild = m_TreeCtrl.GetNextItem(TreeChild, TVGN_NEXT);
if (NULL == TreeChild)
{
break;
}
}
}
选中CtreeCtrl控件的Checkbox同时也要选中其所有父项:
void CMyDlg::SelectParentItem(HTREEITEM& hTreeItem)
{
HTREEITEM TreeParent = m_TreeCtrl.GetParentItem(hTreeItem);
while(NULL != TreeParent)
{
m_TreeCtrl.SetCheck(TreeParent);
TreeParent = m_TreeCtrl.GetNextItem(TreeParent, TVGN_PARENT);
if (NULL == TreeParent)
{
break;
}
}
}
取消选中CtreeCtrl控件的Checkbox同时也要取消选中其所包含的所有子项:
void CMyDlg::UnSelectChildItem(HTREEITEM& hTreeItem)
{
HTREEITEM TreeChild = m_TreeCtrl.GetChildItem(hTreeItem);
while(NULL != TreeChild)
{
if (m_TreeCtrl.ItemHasChildren(TreeChild))
{
UnSelectChildItem(TreeChild);
}
m_TreeCtrl.SetCheck(TreeChild, 0);
TreeChild = m_TreeCtrl.GetNextItem(TreeChild, TVGN_NEXT);
if (NULL == TreeChild)
{
break;
}
}
}
一个CTreeCtrl的Item的所有子项都取消选中,那么这个Item也要取消选中:
void CMyDlg::UnSelectParentItem(HTREEITEM& hTreeItem, bool bFirst)
{
HTREEITEM TreeParent = m_TreeCtrl.GetParentItem(hTreeItem);
if (NULL == TreeParent)
{
return;
}
HTREEITEM TreeChild = m_TreeCtrl.GetChildItem(TreeParent);
UINT nCheck = 0;
while(NULL != TreeChild)
{
if (m_TreeCtrl.GetCheck(TreeChild))
{
++nCheck;
}
TreeChild = m_TreeCtrl.GetNextItem(TreeChild, TVGN_NEXT);
if (NULL == TreeChild)
{
break;
}
}
if (bFirst) // 递归第一次进入
{
--nCheck;
}
if (0 == nCheck)
{
m_TreeCtrl.SetCheck(TreeParent, 0);
UnSelectParentItem(TreeParent, false);
}
}
CtreeCtrl的控件成员:
CtreeCtrl::GetNextItem
HTREEITEM GetNextItem(HTREEITEM hItem, UInt nCode)
hItem
树项的句柄
nCode
指示关系的类型。hItem的标志。其可能取值及含义如下:
- TVGN_CARET返回当前的选项
- TVGN_CHILD指定表项的子项
- TVGN_DROPHILITE返回拖动操作的目标项
- TVGN_FIRSTVISIBLE返回第一个可见项
- TVGN_NEXT返回指定项的下一个兄弟项
- TVGN_NEXTVISIBLE返回指定项的后一个可见项
- TVGN_PARENT返回指定项的父项
- TVGN_PREVIOUS返回指定项的前一个兄弟项
- TVGN_PREVIOUSVISIBLE返回指定项的前一个可见项
- TVGN_ROOT返回位于最高层的第一个表项
CTreeCtrl::InsertItem
HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct);
HTREEITEM InsertItem(UINT nMask,
LPCTSTR lpszItem,
int nImage,
int nSelectImage,
UINT nState,
UINT nStatemask,
LPARAM lParam,
HTREEITEM hParent,
HTREEITEM hInsertAfter);
HTREEITEM InsertItem(LPCTSTR lpszItem,
HTREEITEM hParent = TVI_ROOT,
HTREEITEM hInsertAfter = TVI_LAST)
HTREEITEM InsertItem(LPCTSTR lpszItem,
int nImage,
int nSelectedImage,
HTREEITEM hParent = TVI_ROOT,
HTREEITEM hInsertAfter = TVI_LAST)
参数:
lpIinsertStruct 指定要插入的树视图项目属性设置为TVIINSERTSTRUCT的指针
nMask 指定哪些属性的整数设置,
lpszitem 包含项目文本的字符串的地址
nImage 项目的图像的索引在树视图控件图形的列表
nSelectedIamge 项目中的选定图像的索引在视图控件图形的的列表
nState 为项目的状态指定值
nStateMask 指定的状态将被设置为
lParam 32位特定的值与项目
hParent 插入项的父级的句柄
hInsertAfter 要插入新项目会在其后面