像GetItemImage、设置与树项关联图像SetItemImage、取得树项文本GetItemText、设置树项文本SetItemText和取得树项编辑控制句柄GetEditControl等。 3、树控制的操作方法
树控制的操作方法包括插入一个树项InsertItem、删除一个树项DeleteItem、删除所有树项DeleteAllItems、展开或合拢树项的子项Expand、选中特定树项SelectItem、选择一个树项作为第一个可视树项SelectSetFirstVisible、编辑一个可视的树项EditLabel和排序给定父树项的子树项SortChildren等。 (三)树控制的数据结构
在使用树控制时需要了解两个个非常重要的数据结构TV_ITEM和TV_INSERTSTRUCT,前一个数据结构是用来表示树控制的树项信息,后一个数据结构是用来定义将树项增加到数据控制中所需要的数据内容。另外,还需要NM_TREEVIEW、TV_DISPINFO和TV_HITTESTINFO三个数据结构,这几个数据结构的定义方法如下: ①基本数据项结构
typedef struct _TV_ITEM {
UINT mask; //结构成员有效性屏蔽位 HTREEITEM hItem; //数据项控制句柄 UINT state; //数据项状态 UINT stateMask; //状态有效性屏蔽位 LPSTR pszText; //数据项名称字符串 int cchTextMax; //数据项名称的最大长度 int iImage; //数据项图标索引号 int iSelectedImage;//选中数据项图标索引号 int cChildren; //子项标识
LPARAM lParam; //程序定义的32位数据 } TV_ITEM, FAR *LPTV_ITEM; ②插入树项结构
typedef struct _TV_INSER TSTRUCT { HTREEITEM hParent; //父项控制句柄 HTREEITEM hInsertAfter; //插入树项的位置 TV_ITEM item; //数据项的结构 } TV_INSERTSTRUCT, FAR *LPTV_INSERTSTRUCT;
其中插入的位置如果是TVI_FIRST 或TVI_LAST ,则分别插入到树控制的最前面或最后面,如果是TVI_SORT ,则插入的树项自动插入到合适的位置。 ③树控制通知消息结构
typedef struct _NM_TREEVIEW { NMHDR hdr; //通知消息句柄 UINT action; //通知消息标志
TV_ITEM itemOld; //原来的数据结构 TV_ITEM itemNew; //新的数据结构 POINT ptDrag; //拖动指针 } NM_TREEVIEW; ④取得或设置数据结构
typedef struct _TV_DISPINFO { tvdi NMHDR hdr; //通知消息控制句柄 TV_ITEM item; //数据项结构 } TV_DISPINFO; ⑤指针测试数据结构
typedef struct _TVHITTESTINFO { tvhtst POINT pt; //客户区域屏幕坐标指针 UINT flags; //存放测试结果的变量 HTREEITEM hItem; //测试的数据项结构 } TV_HITTESTINFO, FAR *LPTV_HITTESTINFO; 其中flags测试结果可以是如下值: TVHT_ABOVE 在客户区域上面 TVHT_BELOW 在客户区域下面
TVHT_NOWHERE 在客户区域中并在最后一项下面 TVHT_ONITEM 在与树项关联的位图或标签内 TVHT_ONITEMBUTTON 在与树项关联的按钮上 TVHT_ONITEMICON 在与树项关联的位图上 TVHT_ONITEMINDENT 在与树项关联的联线上 TVHT_ONITEMLABEL 在与树项关联的标签上 TVHT_ONITEMRIGHT 在树项的右侧区域中 TVHT_ONITEMSTATEICON 在用户定义的状态图标上 TVHT_TOLEFT 在客户区域的左侧 TVHT_TORIGHT 在客户区域的右侧 (四)树控制的应用技巧示例
这里仍以基于对话框演示实例来具体介绍树控制及其和图像列表相结构的应用技巧: 通过“FILE->NEW->PROJECTS->MFC AppWizard(EXE)”建立名为VCTREE的工程,在建立过程中选择基于对话框(Dialog based)的应用;将对话框中的默认控件删除,并将所有对话框属性中的Language域设置为Chinese(P.R.C.),以使应用程序支持中文;建立两个图标IDI_PM和IDI_CJ,用来表示图标的选中和非选中状态,对于每个图标都应建立32X32和16X16两种大小,以保证程序的需要;在对话框窗口中添加树控制对象(TREE CONTROL),并设置五个按钮“增加|删除|查看|排序|关闭”,其对应标识分别如下:
控制名称 标题名称 标识符号
树控制 IDC_TREECTRL 按钮 增 加 IDC_ADD 删 除 IDC_DEL 查 看 IDC_VIEW 排 序 IDC_SORT 关 闭 IDOK
5、选中树控制控件,选择“VIEW->ClassWizard->Memory Variables。??骺刂艻DC_TREECTRL 引入成员变量,其变量类型为:
变量名 种类 变量类型 m_TreeCtrl Control CTreeCtrl
同时利用“MESSAGES MAP”为各命令按钮增加控制功能函数。 6、然后在代码文件VCTREEDlg.CPP中分别加入如下控制代码: (1)在文件开始处增加图像列表定义 CImageList Cil1,Cil2;//大小图标像列表 (2)在初始化文件开始处增加代码 BOOL CVCTREEDlg::OnInitDialog() { CDialog::OnInitDialog(); ......//原来其它代码
// TODO: Add extra initialization here // 此处开始增加代码
CVCTREEApp *pApp=(CVCTREEApp *)AfxGetApp();//创建图象列表 Cil1.Create(16,16,ILC_COLOR,2,2); Cil1.Add(pApp->LoadIcon(IDI_PM)); Cil1.Add(pApp->LoadIcon(IDI_CJ));
m_TreeCtrl.SetImageList(&Cil1,TVSIL_NORMAL); //设置图象列表
DWORD dwStyles=GetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE);//获取树控制原风格 dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT; SetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE,dwStyles);//设置风格
char * CJ[4]={\玉溪卷烟厂\云南卷烟厂\沈阳卷烟厂\成都卷烟厂\根数据名称 char * PM[4][5]={
{\红梅一\红梅二\红梅三\红梅四\红梅五\产品数据项 {\白梅一\白梅二\白梅三\白梅四\白梅五\{\绿梅一\绿梅二\绿梅三\绿梅四\绿梅五\{\青梅一\青梅二\青梅三\青梅四\青梅五\
int i,j;
HTREEITEM hRoot,hCur;//树控制项目句柄 TV_INSERTSTRUCT TCItem;//插入数据项数据结构
TCItem.hParent=TVI_ROOT;//增加根项
TCItem.hInsertAfter=TVI_LAST;//在最后项之后
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽 TCItem.item.pszText=\数据选择\ TCItem.item.lParam=0;//序号 TCItem.item.iImage=0;//正常图标
TCItem.item.iSelectedImage=1;//选中时图标
hRoot=m_TreeCtrl.InsertItem(&TCItem);//返回根项句柄 for(i=0;i<4;i++){//增加各厂家
TCItem.hParent=hRoot; TCItem.item.pszText=CJ[i];
TCItem.item.lParam=(i+1)*10;//子项序号 hCur=m_TreeCtrl.InsertItem(&TCItem); for(j=0;j<5;j++){//增加各产品 }
TCItem.hParent=hCur;
TCItem.item.pszText=PM[i][j];
TCItem.item.lParam=(i+1)*10+(j+1);//子项序号 m_TreeCtrl.InsertItem(&TCItem);
m_TreeCtrl.Expand(hCur,TVE_EXPAND);//展开树 }
m_TreeCtrl.Expand(hRoot,TVE_EXPAND);//展开上一级树
return TRUE; // return TRUE unless you set the focus to a control }
(3)增加树项功能的实现
在增加树项功能时,除了需要定义和设置插入树项的数据结构之外,还需要注意的是新增树项的名称初始时均为“新增数据”,增加后允许用户给数据项设置自定义名称。在编程时应特别注意m_TreeCtrl.EditLabel(hInsert);后面不能跟任何其它程序命令,否则这条编辑指令无效。 void CVCTREEDlg::OnAdd() { //增加子项功能函数
HTREEITEM hSel=m_TreeCtrl.GetSelectedItem();//取得选择项句柄 if(hSel==NULL) return;//无任何选项则返回 static int nAddNo=100;//编号大于100为新增数据 TV_INSERTSTRUCT TCItem;//定义插入项数据结构 TCItem.hParent=hSel; //设置父项句柄 TCItem.hInsertAfter=TVI_LAST;//在最后增加
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
TCItem.item.pszText=\新增数据\
TCItem.item.lParam=nAddNo++;//索引号增加 TCItem.item.iImage=0;//正常图标
TCItem.item.iSelectedImage=1;//选中时图标
HTREEITEM hInsert=m_TreeCtrl.InsertItem(&TCItem);//增加 m_TreeCtrl.Expand(hSel,TVE_EXPAND);
m_TreeCtrl.EditLabel(hInsert);//修改增加的数据 }
(4)删除树项功能的实现
在实现删除功能时,应对存在子项的树项进行提示,以警告用户是否连同其子项一起删除。 void CVCTREEDlg::OnDel() { //删除子项功能函数
HTREEITEM hSel=m_TreeCtrl.GetSelectedItem();//取得选项句柄; if(hSel==NULL) return;//无任何选项则返回
if(m_TreeCtrl.ItemHasChildren(hSel))//判断是否有子项
if(MessageBox(\厂家下存在品名,一同删除?\警告\ }
(5)排序功能的实现
排序功能是对所选中的树项的所有子项按字符中顺序进行排序,如果想要按照其它规则进行排序,应利用SortChildrenItemBC()函数进行自行开发排序程序,这个自行开发的函数与列表控制中实现的函数基本相同,可兴趣的读可以试验。 void CVCTREEDlg::OnSort() { //排序子项功能函数
HTREEITEM hSel=m_TreeCtrl.GetSelectedItem();//取得选项句柄; if(hSel==NULL) return;//无任何选项则返回 m_TreeCtrl.SortChildren(hSel); }
(6)查看功能的实现
查看功能用来查看选中树项的有关信息,函数中中显示了树项的文本名称和标识号,可以将这两个信息作为查找关键字,来查看其它更详细的信息。 void CVCTREEDlg::OnView() { //查看选中项功能函数
HTREEITEM hSel=m_TreeCtrl.GetSelectedItem();//取得选项句柄; if(hSel==NULL) return;//无任何选项则返回
CString cText=m_TreeCtrl.GetItemText(hSel);//取得数据项名 LONG IDs=m_TreeCtrl.GetItemData(hSel);//取得数据项序号
m_TreeCtrl.DeleteItem(hSel);