深入学习TTreeView组件

土著巫师 2006-01-05 09:10:02
最近在做一个小程序,里面用到TTreeView组件,本想这么一个常用组件不应该有什么问题;可是客户希望能够有CheckBox显示,其功能就象我们平时安装软件选择不同的部份一样,父节点可能有三态(选择,部份选择,没有选择);针对这种情况我就用了一个TImageList组件,里面放上三个图标分别代表选择,部份选择,没有选择状态,并且设置TreeView的StateImages为前面设置好的TImageList组件.可是怪事多多:

1、如果ImageList里的三个图标的下标从0,1,2计数,树显示时图形根本就显示不出来。后来在网上找了一个文章,说必须在0位置放一个不用的图标,我的图标为1,2,3序号,一试果然显示OK了。昏。

2、我是在TreeView的OnClick事件里,找到当前被选择的节点,然后改变这个节点的显示标图;如果MOUSE选中的是叶子节点(也就是它没有子节点了)图标改变了正常显示出来,可是如果选中的节点自身有子节点,怎么也改变不了它的StateIndex值(图标显示当然也不正常啦)。在程序中调试时发现给这个节点的StateIndex赋值不了。:( 更昏。
//---------------------------------------------------------------------------

//事先在设计器里建立了一个三层的树,点击第三层没问题,每二层和第一层都不行:(
//贴一部分代码出来(TreeView的OnClick事件):
void __fastcall TFormUser::tvGoodsGroupClick(TObject *Sender) //tvGoodsGroup为TreeView
{
TPoint Point;

GetCursorPos(&Point);
Point = tvGoodsGroup->ScreenToClient(Point);
if(tvGoodsGroup->GetHitTestInfoAt(Point.x, Point.y).Contains(htOnStateIcon))
ToggleTreeViewCheckBoxes(tvGoodsGroup->Selected);
}
//---------------------------------------------------------------------------

//改变节点StateIndex值函数,先定义了cCheckAll和cCheckNone为ImageList里图标的索引
void __fastcall TFormUser::ToggleTreeViewCheckBoxes(TTreeNode *Node)
{
if(Node)
{
if(!Node->HasChildren)
{
if(Node->StateIndex == cCheckNone) Node->StateIndex = cCheckAll; //ok
else Node->StateIndex = cCheckNone; //ok
}
else
{
//先判断原来的状态图标索引值
if(Node->StateIndex == cCheckAll) Node->StateIndex == cCheckNone;//改变不了,象没执行
else Node->StateIndex == cCheckAll;//改变不了,象没执行
}
}
}
//---------------------------------------------------------------------------

//“革命尚未成功,同志们尚需努力”,这么点事,不会要把VCL源代码拿出来瞧一瞧,重新写
//过吧。闷。超级闷。
...全文
280 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lvjack 2006-01-08
  • 打赏
  • 举报
回复
唉,上次俺也……
呵呵建议编译器对这种情况警告一下,不知borland采纳否:)
caizhen2000_82 2006-01-06
  • 打赏
  • 举报
回复
呵呵,正常正常!!那咱只有接分了!!
constantine 2006-01-06
  • 打赏
  • 举报
回复
汗,没什么,偶尔写错很正常
现在有时写代码pascal的跟C++的我也又是会写错,老是忘记环境
其实3态树有控件的
土著巫师 2006-01-06
  • 打赏
  • 举报
回复
来看笑话的都有分啦,同志们,当个笑话来顶吧.
土著巫师 2006-01-06
  • 打赏
  • 举报
回复
一觉醒来,方知人间多美好.:)
各位看观,知道问题出在什么地方了吗?且看这两句:

if(Node->StateIndex == cCheckAll)
Node->StateIndex == cCheckNone;//怎么用==呢,笨
else
Node->StateIndex == cCheckAll;//都应该用=,笨笨!

大骂自己是多笨之后,不禁有想:BCB编译器怎么没给出敬告提示呢.:(
G66606495 2006-01-06
  • 打赏
  • 举报
回复
:)))))))))
wf2091139 2006-01-06
  • 打赏
  • 举报
回复
学习一下,拷点代码,呵呵
土著巫师 2006-01-05
  • 打赏
  • 举报
回复
TO GAOLUN:

谢谢.不过我希望通过改变StateIndex的方式,达到显示三种状态的效果.不知道在你代码的基础上能不能做到。吃饭了,回头再试试。再次表示感谢。
GaoLun 2006-01-05
  • 打赏
  • 举报
回复
按照这段代码,可以直接加上checkbox,主要使用的是 SetWindowLong
GaoLun 2006-01-05
  • 打赏
  • 举报
回复
收藏别人的加checkbox的代码

void __fastcall TForm1::FormCreate(TObject *Sender)
{
SetWindowLong(TreeView1->Handle,GWL_STYLE,
GetWindowLong(TreeView1->Handle,GWL_STYLE) | TVS_CHECKBOXES);

}
//判断一个节点是否处于Checked状态
bool GetNodeChecked(TTreeNode *ANode)
{
TVITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
tvItem.hItem = ANode->ItemId;
tvItem.stateMask = TVIS_STATEIMAGEMASK;
TreeView_GetItem(ANode->TreeView->Handle, &tvItem);
return ((BOOL)(tvItem.state >> 12) -1);
}
//设置一个节点为Checked状态或者Unchecked状态,由参数IsSetToChecked来确定
void SetNodeChecked(TTreeNode *ANode,bool IsSetToChecked)
{
TVITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
tvItem.hItem = ANode->ItemId;
tvItem.stateMask = TVIS_STATEIMAGEMASK;
tvItem.state = INDEXTOSTATEIMAGEMASK(IsSetToChecked?2:1);
TreeView_SetItem(ANode->TreeView->Handle, &tvItem);
}
void SetChildChecked(TTreeNode *ANode,bool yn)
{ // 把它的子孙都置成一样
int count=ANode->Count;
SetNodeChecked(ANode,yn);
if (count!=0)
for (int i=0;i<count;i++)
SetChildChecked(ANode->Item[i],yn);
}
TTreeNode *ClickNode; // 保存点中的节点
bool NodeChecked; // 保存点中的节点checked
void __fastcall TForm1::TreeView1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
ClickNode=TreeView1->GetNodeAt(X,Y);
if (ClickNode!=NULL) // 保存原节点的Checked值
NodeChecked=GetNodeChecked(ClickNode);
}
void __fastcall TForm1::TreeView1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (ClickNode!=NULL)
if (GetNodeChecked(ClickNode)!=NodeChecked)
{ // 把它的子孙都置成一样
NodeChecked=!NodeChecked; // 更新它
SetChildChecked(ClickNode,NodeChecked);
}
}
你先建手工一个TreeView1的若干节点,用上面的程序一看,
象不象,

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧