工控编程吧
标题:
84上位机VC MFC树视图三种节点状态效果
[打印本页]
作者:
qq263946146
时间:
2015-12-14 20:59
标题:
84上位机VC MFC树视图三种节点状态效果
(, 下载次数: 4)
上传
点击文件名下载附件
84上位机VC MFC树视图三种节点状态效果
功能展示
树视图节点有不同状态的复选框效果,可以让用户更多清楚的了解自己当前的操作情况,我们当前这例程就来实现三种不同状态的节点功能,效果如图;
要点提示
树状视图的复选框是通过图像状态索引绘制,我们先设计一个位图,包含视图项的各个状态,再将位图添加械CImageList中,然后调用CTreeCtrl的SetImageList()就可以设置位图状态索引;
实现功能
1.新建基于对话框的应用程序
2.派生一个自己的类class CStateTreeCtrl : publicCTreeCtrl;给类添加三个函数 voidRansackParentAndChild(HTREEITEM hItem,UINT State);
void RansackChild(HTREEITEM hItem,UINT State);
BOOL SetItemState(HTREEITEM hItem, UINT State, UINTStateMask, BOOL IsSearch=TRUE);
再添加nLButtonDown(UINTnFlags, CPoint point) 和voidCStateTreeCtrl:
reSubclassWindow() 函数,下面是这五个函数的函数体
void CStateTreeCtrl::PreSubclassWindow()
{
ModifyStyle(0,TVS_CHECKBOXES|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT|TVS_FULLROWSELECT,0);
CTreeCtrl::PreSubclassWindow();
}
void CStateTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
HTREEITEM hItemInfo =HitTest(point, &nFlags);
//TVHT_ONITEMSTATEICON表示用户定义的视图项的图标状态
if ( nFlags &TVHT_ONITEMSTATEICON )
{
//State: 0无状态 1没有选择 2部分选择 3全部选择
//12到15位表示视图项的图像状态索引
UINT State = GetItemState( hItemInfo, TVIS_STATEIMAGEMASK ) >> 12;
State=(State==3)?1:3;
SetItemState( hItemInfo, INDEXTOSTATEIMAGEMASK(State), TVIS_STATEIMAGEMASK );
}
else
CTreeCtrl::OnLButtonDown(nFlags, point);
}
复制代码
//遍历子节点
void CStateTreeCtrl::RansackChild(HTREEITEM hItem, UINT State)
{
HTREEITEM hChildItem,hBrotherItem;
//查找子节点
hChildItem=GetChildItem(hItem);
if(hChildItem!=NULL)
{
//将所有子节点的状态设置与父节点相同
CTreeCtrl::SetItemState( hChildItem, INDEXTOSTATEIMAGEMASK(State), TVIS_STATEIMAGEMASK );
//再递归处理子节点的子节点
RansackChild(hChildItem, State);
//搜索子节点的兄弟节点
hBrotherItem=GetNextSiblingItem(hChildItem);
while (hBrotherItem)
{
//设置子节点的兄弟节点状态与当前节点的状态一致
int nState = GetItemState( hBrotherItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState!=0)
{
CTreeCtrl::SetItemState( hBrotherItem, INDEXTOSTATEIMAGEMASK(State), TVIS_STATEIMAGEMASK );
}
//再递归处理兄弟节点
RansackChild(hBrotherItem, State);
hBrotherItem=GetNextSiblingItem(hBrotherItem);
}
}
}
void CStateTreeCtrl::RansackParentAndChild(HTREEITEM hItem, UINT State)
{
HTREEITEM hNextItem,hPrevItem,hParentItem;
//查找父节点,没有就结束
hParentItem=GetParentItem(hItem);
if(hParentItem!=NULL)
{
UINT nState1=State;//设初始值,防止没有兄弟节点时出错
//查找当前节点的所有兄弟节点,如果所有兄弟节点状态都相同,
//设置父节点的状态
复制代码
//查找当前节点下面的兄弟节点的状态
hNextItem=GetNextSiblingItem(hItem);
while(hNextItem!=NULL)
{
nState1 = GetItemState( hNextItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=State && nState1!=0) break;
else hNextItem=GetNextSiblingItem(hNextItem);
}
if(nState1==State)
{
//查找当前节点上面的兄弟节点的状态
hPrevItem=GetPrevSiblingItem(hItem);
while(hPrevItem!=NULL)
{
nState1 = GetItemState( hPrevItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=State && nState1!=0) break;
else hPrevItem=GetPrevSiblingItem
(hPrevItem);
}
}
if(nState1==State || nState1==0)
{
nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=0)
{
//如果状态一致,则父节点的状态与当前节点的状态一致
CTreeCtrl::SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(State), TVIS_STATEIMAGEMASK );
}
//再递归处理父节点的兄弟节点和其父节点
RansackParentAndChild(hParentItem,State);
}
else
{
//状态不一致,则当前节点的父节点、父节点的父节点……状态均为第三态
hParentItem=GetParentItem(hItem);
while(hParentItem!=NULL)
{
nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=0)
{
CTreeCtrl::SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK );
}
hParentItem=GetParentItem(hParentItem);
}
}
}
}
复制代码
while(hParentItem!=NULL)
{
nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
if(nState1!=0)
{
CTreeCtrl::SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK );
}
hParentItem=GetParentItem(hParentItem);
}
}
}
}
//设置节点状态
BOOL CStateTreeCtrl::SetItemState(HTREEITEM hItem, UINT State, UINT StateMask, BOOL IsSearch)
{
BOOL ret=CTreeCtrl::SetItemState( hItem, State, StateMask );
UINT nState =State >> 12;
if(nState!=0)
{
if(IsSearch)
RansackChild(hItem, nState);
RansackParentAndChild(hItem,nState);
}
return ret;
}
复制代码
4.最后是这个自定义类的使用;主对话框中添加数着视图关联变量 CStateTreeCtrl m_Tree;添加两变量 CImageList m_ImageList; CImageList m_StateList;
5.初始化给树状视图添加数据
m_ImageList.Create(IDB_BITMAP1,16,1,RGB(255,255,255));
m_StateList.Create(IDB_BITMAP2,12,1,RGB(255,255,255));
m_Tree.SetImageList(&m_ImageList,TVSIL_NORMAL);
m_Tree.SetImageList(&m_StateList,TVSIL_STATE);
TV_INSERTSTRUCT hInsert;
hInsert.hParent=NULL;
hInsert.hInsertAfter=TVI_LAST;
hInsert.item.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT|TVIF_STATE;
hInsert.item.hItem=NULL;
hInsert.item.state=INDEXTOSTATEIMAGEMASK( 1 );
复制代码
hInsert.item.stateMask=TVIS_STATEIMAGEMASK;
hInsert.item.cchTextMax=6;
hInsert.item.iSelectedImage=1;
hInsert.item.cChildren=0;
hInsert.item.lParam=0;
hInsert.item.pszText="工控编程";
hInsert.item.iImage=0;
HTREEITEM hRoot=m_Tree.InsertItem(&hInsert);
m_Tree.SetItemState( hRoot, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK );
hInsert.hParent=hRoot;
hInsert.item.iImage=0;
hInsert.item.pszText="欧姆龙PLC编程";
m_Tree.InsertItem(&hInsert);
hInsert.hParent=hRoot;
hInsert.item.pszText="三菱PLC编程";
HTREEITEM h1=m_Tree.InsertItem(&hInsert);
hInsert.hParent=hRoot;
hInsert.item.pszText="西门子PLC编程";
m_Tree.InsertItem(&hInsert);
hInsert.hParent=hRoot;
hInsert.item.pszText="松下PLC编程";
m_Tree.InsertItem(&hInsert);
hInsert.hParent=hRoot;
hInsert.item.pszText="罗克韦尔PLC编程";
m_Tree.InsertItem(&hInsert);
hInsert.hParent=hRoot;
hInsert.item.pszText="其他编程";
HTREEITEM h2=m_Tree.InsertItem(&hInsert);
hInsert.hParent=h2;
hInsert.item.pszText="上位机VC编程";
m_Tree.InsertItem(&hInsert);
hInsert.hParent=h2;
hInsert.item.pszText="触摸屏编程";
m_Tree.InsertItem(&hInsert);
hInsert.hParent=h2;
hInsert.item.pszText="贝加莱PLC编程";
m_Tree.InsertItem(&hInsert);
hInsert.hParent=h2;
hInsert.item.pszText="组态编程";
m_Tree.InsertItem(&hInsert);
<div style="text-align: center;"><span style="line-height: 1.5;"><b><font size="4">我们来演示下实现过程</font></b></span></div>
复制代码
[iqiyi]http://player.video.qiyi.com/de8e90ffaca7e86c1f0ceac0a8a31e33/0/0/w_19rt6m2lop.swf-albumId=5019107109-tvId=5019107109-isPurchase=0-cnId=12[/iqiyi]
(, 下载次数: 0)
上传
点击文件名下载附件
[note]1[/note]
欢迎光临 工控编程吧 (https://www.gkbc8.com/)
Powered by Discuz! X3.4