昨天老师给了个demo,说是让做一个关于树状控件的应用程序。
基本上原理部分的内容我也不大懂,就整理了关于树状控件的用法部分。一、树形控件的创建。1,树形控件的创建也是有两种方式,一种是在对话框模板中直接拖入TreeControl控件创建,另一种就是通过CTreeCtrl类的Create成员函数创建。
首先介绍一下Create函数:
CTreeCtrl类的Create成员函数的原型如下:
virtualBOOL Create(
DWORD dwStyle,
const RECT& rect,
CWnd*pParentWnd,
UINT nID
);
dwStyle指定树形控件风格的组合,rect指定树形控件窗口的位置和大小,pParentWnd为指向树形控件父窗口的指针,nID指定树形控件的ID。下面还是主要讲讲树形控件的主要风格以及含义。
TVS_DISABLEDRAGDROP:禁止树形控件发送TVN_BEGINDRAG通知消息,即不支持拖动操作
TVS_EDITLABELS:用户可以编辑节点的标签文本
TVS_HASBUTTONS:显示带有"+"或"-"的小方框来表示某项能否被展开或已展开
TVS_HASLINES:在父节点与子节点间连线以更清晰地显示树的结构
TVS_LINESATROOT:在根节点处连线
TVS_SHOWSELALWAYS:即使控件失去输入焦点,仍显示出项的选择状态
简而言之,风格就是树状控件前面的加减符号那种。。
需要树形控件添加CTreeCtrl类型的控件变量m_Tree
从对话框模板中直接拖入TreeControl控件创建基本类似,但是dwStyle需要自己设置。
DWORDdwStyles=GetWindowLong(m_Tree.m_hWnd,GWL_STYLE);//获取树控制原风格dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT;
SetWindowLong(m_Tree.m_hWnd,GWL_STYLE,dwStyles);//设置风格
具体函数参数可以参考MSDN。
二、添加节点。
HTREEITEM 是树状控件的节点类型,
HTREEITEM hRoot;
创建节点需要调用insertTree函数。
示例:
insertitem函数有四个重载函数。
HTREEITEMInsertItem( LPTVINSERTSTRUCT lpInsertStruct);
HTREEITEMInsertItem(
UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINTnState,
UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEMhInsertAfter );
HTREEITEMInsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT,
HTREEITEM hInsertAfter = TVI_LAST);
HTREEITEMInsertItem( LPCTSTR lpszItem,
int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT,
HTREEITEM hInsertAfter = TVI_LAST);
lpszItem为节点名,nImage为节点图标,nSelectedImage是选中之后的节点图标,hParent是父节点,
hInsertAfter是“Specifiesthe handle of the item after which the new item is to beinserted.”(MSDN的说法,反正记住默认为TVI_LAST就行了)
这几个函数基本上差不多,后面实例我有举出应用。
不要忘记给节点编号哦!
BOOL SetItemData( HTREEITEM hItem, DWORDdwData );
hTtem为节点,dwData为节点编号。
三、树状控件的其他函数。
CImageList* SetImageList(CImageList * pImageList,intnImageListType);
如果树节点需要显示图标时,则必须先创建一个CImageList类的对象,并为其添加多个图像组成一个图像序列,然后调用SetImageList函数为树形控件设置图像序列,在用InsertItem插入节点时传入所需图像在图像序列中的索引即可。后面的例子中会演示。参数pImageList为指向图像序列类CImageList的对象的指针,若为NULL则删除树形控件的所有图像。参数nImageListType指定图像序列的类型,可以是TVSIL_NORMAL(普通图像序列)或TVSIL_STATE(状态图像序列,用图像表示节点的状态)。
UINTGetCount( ) const;
获取树形控件中节点的数量。
DWORD_PTRGetItemData(HTREEITEM hItem) const;
获取树形控件中某个指定节点的附加32位数据。参数hItem为指定的树节点的句柄。
BOOLSetItemData(HTREEITEM hItem,DWORD_PTR dwData);
为树形控件中某个指定节点设置附加的32位数据。参数hItem同上,dwData为要设置的32位数据。
CStringGetItemText(HTREEITEM hItem) const;
获取树形控件中某个指定节点的标签文本。参数hItem同上。返回值是包含标签文本的字符串。
BOOLSetItemText(HTREEITEM hItem,LPCTSTR lpszItem);
为树形控件中某个指定节点设置标签文本。参数hItem同上,lpszItem为包含标签文本的字符串的指针。
HTREEITEMGetNextSiblingItem(HTREEITEM hItem) const;
获取树形控件中某个指定节点的下一个兄弟节点。参数hItem同上。返回值是下一个兄弟节点的句柄。
HTREEITEMGetPrevSiblingItem(HTREEITEM hItem) const;
获取树形控件中某个指定节点的上一个兄弟节点。参数hItem同上。返回值是上一个兄弟节点的句柄。
HTREEITEMGetParentItem(HTREEITEM hItem) const;
获取树形控件中某个指定节点的父节点。参数hItem同上。返回值是父节点的句柄。
HTREEITEMGetRootItem( ) const;
获取树形控件根节点的句柄。
HTREEITEMGetSelectedItem( ) const;
获取树形控件当前选中节点的句柄。
BOOLDeleteAllItems( );
删除树形控件中的所有节点。删除成功则返回TRUE,否则返回FALSE。
BOOLDeleteItem(HTREEITEM hItem);
删除树形控件中的某个节点。参数hItem为要删除的节点的句柄。删除成功则返回TRUE,否则返回FALSE。
HTREEITEMInsertItem(LPCTSTR lpszItem,int nImage,int nSelectedImage,HTREEITEMhParent = TVI_ROOT,HTREEITEM hInsertAfter = TVI_LAST);
在树形控件中插入一个新节点。参数lpszItem为新节点的标签文本字符串的指针,参数nImage为新节点的图标在树形控件图像序列中的索引,参数nSelectedImage为新节点被选中时的图标在图像序列中的索引,参数hParent为插入节点的父节点的句柄,参数hInsertAfter为新节点的前一个节点的句柄,即新节点将被插入到hInsertAfter节点之后。
BOOLSelectItem(HTREEITEM hItem);
选中指定的树节点。参数hItem为要选择的节点的句柄。若成功则返回TRUE,否则返回FALSE。
四、多说无益,进入实战吧!
1. 创建一个基于对话框的MFC工程,名称设置为“机器人参数设置”。
2. 在自动生成的对话框模板IDD_MY_DIALOG中,删除“TODO: Place dialog controlshere.”静态文本框、“OK”按钮和“Cancel”按钮。添加一个Tree Control控件。右击控件,点击属性,里面可以设置树状控件的一些属性。
3. 导入需要为树形控件的节点添加的图标。我在这里找了三个32x32的Icon图标,保存到工程的res目录下。然后在ResourceView资源视图中,快捷键Ctrl+R弹出“插入资源”对话框,再从左边“资源类型”列表中选择“Icon”,点击右边的“引入...”按钮,就可以选择三个图标文件进行导入了。导入成功后,分别修改它们ID为IDI_HICON1,IDI_HICON2,IDI_HICON3,(我这里偷懒了,嘻嘻!)。
4,为树形控件IDC_MY_TREE添加CTreeCtrl类型的控件变量m_Tree。
5,新建变量:
HTREEITEMhRoot;
HTREEITEMhCataItem;
HTREEITEMhArtItem;
HICONHicon1;
HICONHicon2;
HICONHicon3;
CImageListm_ImageList;
在CMyDlgOnInitDialog函数里面添加代码
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add"About..." menu item to system menu.
//IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu*pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu!= NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX,strAboutMenu);
}
}
// Set theicon for this dialog. The framework does thisautomatically
// when the application's main window is not adialog
SetIcon(m_hIcon,TRUE); // Set bigicon
SetIcon(m_hIcon,FALSE); // Set smallicon
// TODO: Addextra initialization here
//导入资源图标
Hicon1 =theApp.LoadIcon(IDI_ICON1);
Hicon2 =theApp.LoadIcon(IDI_ICON2);
Hicon3 =theApp.LoadIcon(IDI_ICON3);
// 创建图像序列CImageList对象
m_ImageList.Create(32,32,ILC_COLOR32,2,2);
//将资源图标加载到图像序列
m_ImageList.Add(Hicon1);
m_ImageList.Add(Hicon2);
m_ImageList.Add(Hicon3);
// 为树形控件设置图像序列
m_Tree.SetImageList(&m_ImageList,TVSIL_NORMAL);
//设置节点(具体参照上边创建节点的Create函数)
hRoot =m_Tree.InsertItem(_T("机器人参数设定"),0,0);
/ /为节点设置编号。很重要。
m_Tree.SetItemData(hRoot, 0);
//设置子节点
hCataItem =m_Tree.InsertItem(_T("头部参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,1);
hCataItem =m_Tree.InsertItem(_T("眼睛参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,2);
hCataItem =m_Tree.InsertItem(_T("鼻子参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,3);
hCataItem =m_Tree.InsertItem(_T("嘴巴参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,4);
hCataItem =m_Tree.InsertItem(_T("脖子参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,5);
hCataItem =m_Tree.InsertItem(_T("身体参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,6);
hCataItem =m_Tree.InsertItem(_T("胳膊参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,7);
hCataItem =m_Tree.InsertItem(_T("腿部参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem,8);
hCataItem =m_Tree.InsertItem(_T("脚部参数设定"),1,2,hRoot,TVI_LAST );
m_Tree.SetItemData(hCataItem, 9);
//设置风格,我这里多此一举了,完全可以在上面设置属性界面进行勾选。
DWORDdwStyles=GetWindowLong(m_Tree.m_hWnd,GWL_STYLE);//获取树控制原风格
dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT;
SetWindowLong(m_Tree.m_hWnd,GWL_STYLE,dwStyles);//设置风格
returnTRUE; // return TRUE unless youset the focus to a control
}
这样的话界面就完成了啊!
五、为树状控件添加响应函数。
右击树状控件点击事件添加响应函数。
树状控件有两个响应函数,
void CMyDlg::OnClickTree(NMHDR* pNMHDR, LRESULT* pResult);
void CMyDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult);
下面我就介绍一下这两个函数的区别吧。
树状控件的Create函数不是设置了参数嘛,选中状态下和未选中状态下图标不一样,
当我分别在两个响应函数里面写上以下一段代码,
//获取节点编号,所以说设置节点编号很重要的呀!
DWORD data=m_Tree.GetItemData(hItem);
switch(data)
{
case1:
{
CDialog1dlg;
dlg.DoModal();
}
break;
case2:
{
CDialog2dlg;
dlg.DoModal();
}
break;
case3:
{
CDialog3dlg;
dlg.DoModal();
}
break;
case4:
{
CDialog4dlg;
dlg.DoModal();
}
break;
case5:
{
CDialog5dlg;
dlg.DoModal();
}
break;
case6:
{
CDialog6dlg;
dlg.DoModal();
}
break;
case7:
{