MFC中CtreeCtrl控件实现三态复选的总结
来源:互联网 发布:学蛋糕的软件 编辑:程序博客网 时间:2024/06/05 05:31
对网上现有资料整理总结
网上所能查到的所有关于树形控件三态显示的做法都是添加一个已写好的CTreeCtrl类的派生类,但经过Q姐琢磨和测试,根本无需再创建一个派生类就能实现树形控件的三态复选,下面分享具体做法。
1.给树形控件绑定变量
CTreeCtrl m_tc;
2.添加三态显示框bmp资源,如下
3.添加树形控件三态显示效果相关函数
//.cpp文件
BOOL CxxxDlg::SetState(HTREEITEM hItem, UINT nState, UINT nStateMask, BOOL bSearch)
{
BOOL bReturn=m_tc.SetItemState( hItem, nState, nStateMask );
UINT iState = nState >> 12;
if(iState!=0)
{
if(bSearch) TravelChild(hItem, iState);
TravelSiblingAndParent(hItem,iState);
}
return bReturn;
}
void CxxxDlg::TravelChild(HTREEITEM hItem, int nState)
{
HTREEITEM hChildItem,hBrotherItem;
//查找子节点,没有就结束
hChildItem=m_tc.GetChildItem(hItem);
if(hChildItem!=NULL)
{
//设置子节点的状态与当前节点的状态一致
m_tc.SetItemState( hChildItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
//再递归处理子节点的子节点和兄弟节点
TravelChild(hChildItem, nState);
//处理子节点的兄弟节点和其子节点
hBrotherItem=m_tc.GetNextSiblingItem(hChildItem);
while (hBrotherItem)
{
//设置子节点的兄弟节点状态与当前节点的状态一致
int nState1 =m_tc.GetItemState( hBrotherItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=0)
{
m_tc.SetItemState( hBrotherItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
}
//再递归处理子节点的兄弟节点的子节点和兄弟节点
TravelChild(hBrotherItem, nState);
hBrotherItem=m_tc.GetNextSiblingItem(hBrotherItem);
}
}
}
void CtreeDlg::TravelSiblingAndParent(HTREEITEM hItem, int nState)
{
HTREEITEM hNextSiblingItem,hPrevSiblingItem,hParentItem;
//查找父节点,没有就结束
hParentItem=m_tc.GetParentItem(hItem);
if(hParentItem!=NULL)
{
int nState1=nState;//设初始值,防止没有兄弟节点时出错
//查找当前节点下面的兄弟节点的状态
hNextSiblingItem=m_tc.GetNextSiblingItem(hItem);
while(hNextSiblingItem!=NULL)
{
nState1 = m_tc.GetItemState( hNextSiblingItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=nState && nState1!=0) break;
else hNextSiblingItem=m_tc.GetNextSiblingItem(hNextSiblingItem);
}
if(nState1==nState)
{
//查找当前节点上面的兄弟节点的状态
hPrevSiblingItem=m_tc.GetPrevSiblingItem(hItem);
while(hPrevSiblingItem!=NULL)
{
nState1 = m_tc.GetItemState( hPrevSiblingItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=nState && nState1!=0) break;
else hPrevSiblingItem=m_tc.GetPrevSiblingItem(hPrevSiblingItem);
}
}
if(nState1==nState || nState1==0)
{
nState1 = m_tc.GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=0)
{
//如果状态一致,则父节点的状态与当前节点的状态一致
m_tc.SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
}
//再递归处理父节点的兄弟节点和其父节点
TravelSiblingAndParent(hParentItem,nState);
}
else
{
//状态不一致,则当前节点的父节点、父节点的父节点……状态均为第三态
hParentItem=m_tc.GetParentItem(hItem);
while(hParentItem!=NULL)
{
nState1 = m_tc.GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=0)
{
m_tc.SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK );
}
hParentItem=m_tc.GetParentItem(hParentItem);
}
}
}
}
4.添加树形控件单击响应事件NM_CLICK
void CxxxDlg::OnNMClickTreeTable(NMHDR* pNMHDR, LRESULT* pResult)
{
CPoint point;
UINT uFlag = 0;
GetCursorPos(&point);
m_tc.ScreenToClient(&point);
HTREEITEM hItem = m_tc.HitTest(point, &uFlag);
if((hItem) && (TVHT_ONITEM & uFlag))
{
m_tc.Select(hItem, TVGN_CARET | TVGN_DROPHILITE); //此做法为了不管鼠标点击的是复选框还是文字,都高亮此节点
if (TVHT_ONITEMSTATEICON & uFlag)
{
//nState: 0->无选择钮 1->没有选择 2->部分选择 3->全部选择
UINT nState = m_tc.GetItemState( hItem, TVIS_STATEIMAGEMASK ) >> 12;
nState=(nState==3)?1:3;
SetState( hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
}
*pResult=1;
}
else
*pResult = 0;
}
-------------------------------------------------over----------------------------------------------------------------
总结:以上代码与专门创建一个CtreeCtrl派生类最大的区别:
减少了代码量,根本没必要再创建一个CtreeCtrl派生类。
如想实现遍历效果
void CxxxDlg::TravelItem(HTREEITEM hTreeItem)
{
HTREEITEM hCurItem = m_tc.GetChildItem(hTreeItem);
HTREEITEM hNextItem;
CString strItemText("");
while(hCurItem)
{
//OutputDebugString(tree.GetItemText(hCurItem)); // 输出结点文本
strItemText = m_tc.GetItemText(hCurItem);
hNextItem = hCurItem;
TravelItem(hNextItem);
hCurItem = m_tc.GetNextSiblingItem(hCurItem);
}
m_tc.Expand(hTreeItem,TVE_EXPAND);
}
应用时如下:
TravelItem(m_tc.GetRootItem());
//-------------------------------补充功能:空格键实现复现功能----------------------------------
BOOL CxxxDlg::PreTranslateMessage( MSG* pMsg )
{
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_SPACE)
{
UINT btnID = GetWindowLong(pMsg->hwnd, GWL_ID);
if (btnID == IDC_TREE_TABLE)
{
HTREEITEM hItem = m_TreeCtrl_Table.GetSelectedItem();
if(hItem)
{
UINT nState = m_tc.GetItemState( hItem, TVIS_STATEIMAGEMASK ) >> 12;
nState=(nState==3)?1:3;
SetState( hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
}
return true;
}
}
}
return __super::PreTranslateMessage(pMsg);
}
//----持续改进中----
- MFC中CtreeCtrl控件实现三态复选的总结
- 关于MFC中树形控件(CTreeCtrl)复选框(CheckBox)的显示一致性解决方案
- 关于MFC中树形控件(CTreeCtrl)复选框(CheckBox)的显示一致性解决方案
- MFC中树控件CTreeCtrl的用法
- MFC中树控件CTreeCtrl的用法
- MFC中树控件CTreeCtrl的用法
- MFC中CTreeCtrl控件的简单使用
- MFC中树控件CTreeCtrl的用法
- mfc的CTreeCtrl控件实现windows的资源管理器
- 在MFC中应用CTreeCtrl控件的技巧
- 在MFC中应用CTreeCtrl控件的技巧
- 在MFC中应用CTreeCtrl控件的技巧(对话框重叠)
- 在MFC中应用CTreeCtrl控件的技巧
- 在MFC中应用CTreeCtrl控件的技巧
- 在MFC中应用CTreeCtrl控件的技巧 [vckbase]
- 在MFC中应用CTreeCtrl控件的技巧
- 在MFC中应用CTreeCtrl控件的技巧
- 在MFC中应用CTreeCtrl控件的技巧
- Objective-C学习备忘单
- Square Coins
- Duplicate Net Names Multiple Top Level Documents
- Struts2+Hibernate 实现增删改用户
- 测试面试: 对于一个产品测试你能联想到的所有测试类别
- MFC中CtreeCtrl控件实现三态复选的总结
- IOS笔记 #pragma mark的用法
- java web 中的绝对路径和相对路径
- 第四周阅读函数 (2)
- 让Emacs在保存时自动清除行尾空格及文件结尾空行
- JS-拖拽-碰撞-封装
- 系统更新完成后,IMEISVN自动加1,标识本次升级
- windows7环境下的局域网配置
- Extjs3中修改Store里proxy的URL的方法