第 32 章
D 返回具有输入焦点的表项
LVNI_SELECTED 返回被选择的表项
要对表项进行排列、排序和搜索,可分别调用Arrange、SortItems 和FindItems 函数来完
成。
有时需要在列表视图创建后动态地改变其显示格式,例如,资源管理器中的列表视图就
可以在4 种显示格式之间切换。改变显示格式其实就是改变列表视图的风格,要改变控件的
风格,应先调用::GetWindowLong 获取控件原来的风格,并对其进行修改,然后调
用::SetWindowLong 设置新的风格。这两个函数不是成员函数,而是Windows API 函数,用
来查询和设置窗口的风格。
列表视图控件还会发送自己特有的通知消息,常用的有下面这几个。
? LVN_ITEMCHANGING 和LVN_ITEMCHANGED。当列表视图的状态发生变化时,
会发送这两个通知消息。例如,当用户选择了新的表项时,程序就会收到这两个消息。
消息会附带一个指向NM_LISTVIEW 结构的指针,消息处理函数可从该结构中获得状
态信息。两个消息的不同之处在于,前者的消息处理函数如果返回TRUE,那么就阻
止选择的改变,如果返回FALSE,则允许改变。
? LVN_KEYDOWN。该消息表明了一个键盘事件。消息会附带一个指向LV_KEYDOWN
结构的指针,通过该结构程序可以获得按键的信息。
? LVN_BEGINLABELEDIT 和LVN_ENDLABELEDIT。分别在用户开始编辑和结束编
辑标题时发送。消息会附带一个指向LV_DISPINFO 结构的指针。在前者的消息处理
函数中,可以调用GetEditControl 成员函数返回一个指向用于编辑标题的编辑框的指
针,如果处理函数返回FALSE,则允许编辑,如果返回TRUE,则禁止编辑。在后者
的消息处理函数中,LV_DISPINFO 结构中的item.pszText 指向编辑后的新标题,如果
pszText 为NULL,那么说明用户放弃了编辑,否则,程序应负责更新表项的标题,这
可以由SetItem 或SetItemText 函数来完成。
5.9 树型(Tree Ctrl)控件
5.9.1 树型控件的使用
树型控件是一种特殊的列表,它能以树型分层结构显示数据。在Windows 95 的资源管
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·136·
理器的左侧窗口中就有一个用于显示目录的典型的树形视图,如图5-8 所示。在树形视图中,
每个表项显示一个标题(Label),有时还会显示一幅图像,图像和标题分别提供了对数据的
形象和抽象描述。通过图5-8 可以看出,树形视图可以很清楚地显示出数据的分支和层次关
系。由此可见,树形视图非常适合显示目录、网络结构等这样的复杂数据。传统的列表框不
能分层显示数据,因此树形视图可以看作是对列表框的一种重要改进。
树形视图是一种复杂的控件,它的复杂xìng体现在数据项之间具有分支和层次关系。例如,
如果要向树形视图中加入新的项,则必需描述出该项与树形视图中已有项的相互关系,而不
可能像往列表框中加入新项那样,调用AddString 即可。另外,树形视图可以在每一项标题
的左边显示一幅图像,这使控件显得更加形象生动,但同时也增加了控件的复杂程度。在介
绍如何使用树形视图控件之前,有必要先介绍一下与该控件有关的一些数据类型。
图5-8 CTreeCtrl 控件样例
1.HTREEITEM 型句柄
在Windows 中用HTREEITEM 型句柄来代表树形视图的一项,通过HTREEITEM 句柄
来区分和访问树形视图的各个项。
2.TV_ITEM 结构
该结构用来描述一个表项,它包含了表项的各种属xìng,其定义如下:
typedef struct _TV_ITEM
{
UINT mask;
//包含一些屏蔽位(下面的括号中列出)的组合,用来表明结构的哪些成员是有效的
HTREEITEM hItem;
//表项的句柄(TVIF_HANDLE)
UINT state;
//表项的状态(TVIF_STATE)
UINT stateMask;
枫叶文学网www.fywxw.com
第5 章 常用控件
·137·
//状态的屏蔽组合(TVIF_STATE)
LPSTR pszText;
//表项的标题正文(TVIF_TEXT)
int cchTextMax;
//正文缓冲区的大小(TVIF_TEXT)
int iImage;
//表项的图像索引(TVIF_IMAGE)
int iSelectedImage;
//选中的项的图像索引(TVIF_SELECTEDIMAGE)
int cChildren;
//表明项是否有子项(TVIF_CHILDREN),为1 则有,为0 则没有
LPARAM lParam;
//一个32 位的附加数据(TVIF_PARAM)
}TV_ITEM,FAR *LPTV_ITEM;
下面对上述参数进行解释。如果要使树形视图的表项显示图像,需要为树形视图建立一
个位图序列,这时,iImage 说明表项显示的图像在位图序列中的索引,iSelectedImage 则说明
了选中的表项应显示的图像,在绘制图标时,树形视图可以根据这两个参数提供的索引在位
图序列中找到对应的位图。lParam 可用来放置与表项相关的数据,这常常是很有用的。state
和stateMask 的常用值在表5-22 中列出,其中stateMask 用来说明要获取或设置哪些状态。
表5-22 列表视图的状态
状态 对应的状态屏蔽 含义
TVIS_SELECTED 同左 项被选中
TVIS_EXPANDED 同左 项的子项被展开
TVIS_EXPANDEDONCE 同左 项的子项曾经被展开过
TVIS_CUT 同左 项被选择用来进行剪切和粘贴cāo作
TVIS_FOCUSED 同左 项具有输入焦点
TVIS_DROPHILITED 同左 项成为拖动cāo作的目标
3.TV_INSERTSTRUCT 结构
TV_INSERTSTRUCT 结构。在向树形视图中chā入新项时要用到该结构,其定义如下:
typedef struct _TV_INSERTSTRUCT{
HTREEITEM hParent;
//父项的句柄
HTREEITEM hInsertAfter;
//说明应chā入到同层中哪一项的后面
TV_ITEM item;
}TV_INSERTSTRUCT;
如果hParent 的值为TVI_ROOT 或NULL,那么新项将被chā入到树形视图的最高层(根
位置)。hInsertAfter 的值可以是TVI_FIRST、TVI_LAST 或TVI_SORT,其含义分别是将新
项chā入到同一层中的开头、最后或排序chā入。
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·138·
4.NM_TREEVIEW 结构
树形视图的大部分通知消息都会附带指向该结构的指针以提供一些必要的信息。该结构
的定义如下:
typedef struct _NM_TREEVIEW {
NMHDR hdr;
//标准的NMHDR 结构
UINT action;
//表明是用户的什么行为触发了该通知消息
TV_ITEM itemOld;
//旧项的信息
TV_ITEM itemNew;
//新项的信息
POINT ptDrag;
//事件发生时鼠标的客户区坐标
}NM_TREEVIEW;
5.TV_KEYDOWN 结构
提供与键盘事件有关的信息。该结构的定义如下:
typedef struct _TV_KEYDOWN {
NMHDR hdr;
//标准的NMHDR 结构
WORD wVKey;
//虚拟键盘码
UINT flags;
//为0
}TV_KEYDOWN;
6.TV_DISPINFO 结构
提供与表项的显示有关的信息。该结构的定义如下:
typedef struct _TV_DISPINFO {
NMHDR hdr;
TV_ITEM item;
}TV_DISPINFO;
MFC 的CTreeCtrl 类封装了树形视图。该类的Create 成员函数负责控件的创建,该函数
的声明如下:
BOOL Create(DWORD dwStyle, const RECT& rect,CWnd* pParentWnd,UINT nID);
其中参数dwStyle 是如表5-23 所示的控件风格的组合。
枫叶文学网www.fywxw.com
第5 章 常用控件
·139·
表5-23 树型控件风格
控件风格 含义
TVS_HASLINES 在父项与子项间连线以清楚地显示结构
TVS_LINESATROOT 只在根部画线
TVS_HASBUTTONS 显示带有"+"或"-"的小方框来表示某项能否被展开或已展开
TVS_EDITLABELS 用户可以编辑表项的标题
TVS_SHOWSELALWAYS 即使控件失去输入焦点,仍显示出项的选择状态
TVS_DISABLEDRAGDROP 不支持拖动cāo作
除上表的风格外,一般还要指定WS_CHILD 和WS_VISIBLE 窗口风格。对于用对话框
模板创建的树形视图控件,可以在控件的属xìng对话框中指定上表中列出的控件风格。例如,
在属xìng对话框中选择Has buttons,相当于指定了TVS_HASBUTTONS 风格。
5.9.2 CtreeCtrl 类的主要成员函数
CTreeCtrl 类提供了大量的成员函数。对于常用的函数,下面结合实际应用进行介绍。
1.SetImageList()函数
向树形视图中chā入新的表项。首先应提供一个TV_INSERTSTRUCT 结构并在该结构中
对chā入项进行描述。如果要在树形视图中显示图像,则应该先创建一个CImageList 对象并使
该对象包含一个位图序列,然后调用SetImageList 为树形视图设置位图序列。最后调用
InsertItem 函数把新项chā入到树形视图中。该函数的声明如下:
CImageList* SetImageList(CImageList * pImageList,int nImageListType);
参数pImageList指向一个CImageList对象,参数nImageListType一般应为TVSIL_NORMAL。
2.InsertItem()函数
该成员函数声明如下:
HTREEITEM InsertItem( LPTV_INSERTSTRUCT lpInsertStruct );
参数lpInsertStruct 指向一个TV_INSERTSTRUCT 结构。函数返回新chā入项的句柄。
3.DeleteItem()和DeleteAllItems()函数
用DeleteItem()函数来删除指定项,用DeleteAllItems()函数删除所有项。函数的声明如下:
BOOL DeleteItem(HTREEITEM hItem);
BOOL DeleteAllItems();
cāo作成功则函数返回TRUE,否则返回FALSE。
4.Expand()函数
树形视图控件会根据用户的输入自动展开或折叠子项。但有时需要在程序中展开或折叠
指定项,则应该调用Expand,该函数的声明为
BOOL Expand(HTREEITEM hItem,UINT nCode);
参数hItem 指定了要展开或折叠的项。参数nCode 是一个标志,指定了函数应执行的cāo
作,它可以是TVE_COLLAPSE(折叠)、TVE_COLLAPSERESET(折叠并移走所有的子项)、
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·140·
TVE_EXPAND(展开)或TVE_TOGGLE(在展开和折叠状态之间翻转)。
5.GetSelectedItem()和SelectItem()函数
要查
松语文学免费小说阅读_www.16sy.com
LVNI_SELECTED 返回被选择的表项
要对表项进行排列、排序和搜索,可分别调用Arrange、SortItems 和FindItems 函数来完
成。
有时需要在列表视图创建后动态地改变其显示格式,例如,资源管理器中的列表视图就
可以在4 种显示格式之间切换。改变显示格式其实就是改变列表视图的风格,要改变控件的
风格,应先调用::GetWindowLong 获取控件原来的风格,并对其进行修改,然后调
用::SetWindowLong 设置新的风格。这两个函数不是成员函数,而是Windows API 函数,用
来查询和设置窗口的风格。
列表视图控件还会发送自己特有的通知消息,常用的有下面这几个。
? LVN_ITEMCHANGING 和LVN_ITEMCHANGED。当列表视图的状态发生变化时,
会发送这两个通知消息。例如,当用户选择了新的表项时,程序就会收到这两个消息。
消息会附带一个指向NM_LISTVIEW 结构的指针,消息处理函数可从该结构中获得状
态信息。两个消息的不同之处在于,前者的消息处理函数如果返回TRUE,那么就阻
止选择的改变,如果返回FALSE,则允许改变。
? LVN_KEYDOWN。该消息表明了一个键盘事件。消息会附带一个指向LV_KEYDOWN
结构的指针,通过该结构程序可以获得按键的信息。
? LVN_BEGINLABELEDIT 和LVN_ENDLABELEDIT。分别在用户开始编辑和结束编
辑标题时发送。消息会附带一个指向LV_DISPINFO 结构的指针。在前者的消息处理
函数中,可以调用GetEditControl 成员函数返回一个指向用于编辑标题的编辑框的指
针,如果处理函数返回FALSE,则允许编辑,如果返回TRUE,则禁止编辑。在后者
的消息处理函数中,LV_DISPINFO 结构中的item.pszText 指向编辑后的新标题,如果
pszText 为NULL,那么说明用户放弃了编辑,否则,程序应负责更新表项的标题,这
可以由SetItem 或SetItemText 函数来完成。
5.9 树型(Tree Ctrl)控件
5.9.1 树型控件的使用
树型控件是一种特殊的列表,它能以树型分层结构显示数据。在Windows 95 的资源管
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·136·
理器的左侧窗口中就有一个用于显示目录的典型的树形视图,如图5-8 所示。在树形视图中,
每个表项显示一个标题(Label),有时还会显示一幅图像,图像和标题分别提供了对数据的
形象和抽象描述。通过图5-8 可以看出,树形视图可以很清楚地显示出数据的分支和层次关
系。由此可见,树形视图非常适合显示目录、网络结构等这样的复杂数据。传统的列表框不
能分层显示数据,因此树形视图可以看作是对列表框的一种重要改进。
树形视图是一种复杂的控件,它的复杂xìng体现在数据项之间具有分支和层次关系。例如,
如果要向树形视图中加入新的项,则必需描述出该项与树形视图中已有项的相互关系,而不
可能像往列表框中加入新项那样,调用AddString 即可。另外,树形视图可以在每一项标题
的左边显示一幅图像,这使控件显得更加形象生动,但同时也增加了控件的复杂程度。在介
绍如何使用树形视图控件之前,有必要先介绍一下与该控件有关的一些数据类型。
图5-8 CTreeCtrl 控件样例
1.HTREEITEM 型句柄
在Windows 中用HTREEITEM 型句柄来代表树形视图的一项,通过HTREEITEM 句柄
来区分和访问树形视图的各个项。
2.TV_ITEM 结构
该结构用来描述一个表项,它包含了表项的各种属xìng,其定义如下:
typedef struct _TV_ITEM
{
UINT mask;
//包含一些屏蔽位(下面的括号中列出)的组合,用来表明结构的哪些成员是有效的
HTREEITEM hItem;
//表项的句柄(TVIF_HANDLE)
UINT state;
//表项的状态(TVIF_STATE)
UINT stateMask;
枫叶文学网www.fywxw.com
第5 章 常用控件
·137·
//状态的屏蔽组合(TVIF_STATE)
LPSTR pszText;
//表项的标题正文(TVIF_TEXT)
int cchTextMax;
//正文缓冲区的大小(TVIF_TEXT)
int iImage;
//表项的图像索引(TVIF_IMAGE)
int iSelectedImage;
//选中的项的图像索引(TVIF_SELECTEDIMAGE)
int cChildren;
//表明项是否有子项(TVIF_CHILDREN),为1 则有,为0 则没有
LPARAM lParam;
//一个32 位的附加数据(TVIF_PARAM)
}TV_ITEM,FAR *LPTV_ITEM;
下面对上述参数进行解释。如果要使树形视图的表项显示图像,需要为树形视图建立一
个位图序列,这时,iImage 说明表项显示的图像在位图序列中的索引,iSelectedImage 则说明
了选中的表项应显示的图像,在绘制图标时,树形视图可以根据这两个参数提供的索引在位
图序列中找到对应的位图。lParam 可用来放置与表项相关的数据,这常常是很有用的。state
和stateMask 的常用值在表5-22 中列出,其中stateMask 用来说明要获取或设置哪些状态。
表5-22 列表视图的状态
状态 对应的状态屏蔽 含义
TVIS_SELECTED 同左 项被选中
TVIS_EXPANDED 同左 项的子项被展开
TVIS_EXPANDEDONCE 同左 项的子项曾经被展开过
TVIS_CUT 同左 项被选择用来进行剪切和粘贴cāo作
TVIS_FOCUSED 同左 项具有输入焦点
TVIS_DROPHILITED 同左 项成为拖动cāo作的目标
3.TV_INSERTSTRUCT 结构
TV_INSERTSTRUCT 结构。在向树形视图中chā入新项时要用到该结构,其定义如下:
typedef struct _TV_INSERTSTRUCT{
HTREEITEM hParent;
//父项的句柄
HTREEITEM hInsertAfter;
//说明应chā入到同层中哪一项的后面
TV_ITEM item;
}TV_INSERTSTRUCT;
如果hParent 的值为TVI_ROOT 或NULL,那么新项将被chā入到树形视图的最高层(根
位置)。hInsertAfter 的值可以是TVI_FIRST、TVI_LAST 或TVI_SORT,其含义分别是将新
项chā入到同一层中的开头、最后或排序chā入。
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·138·
4.NM_TREEVIEW 结构
树形视图的大部分通知消息都会附带指向该结构的指针以提供一些必要的信息。该结构
的定义如下:
typedef struct _NM_TREEVIEW {
NMHDR hdr;
//标准的NMHDR 结构
UINT action;
//表明是用户的什么行为触发了该通知消息
TV_ITEM itemOld;
//旧项的信息
TV_ITEM itemNew;
//新项的信息
POINT ptDrag;
//事件发生时鼠标的客户区坐标
}NM_TREEVIEW;
5.TV_KEYDOWN 结构
提供与键盘事件有关的信息。该结构的定义如下:
typedef struct _TV_KEYDOWN {
NMHDR hdr;
//标准的NMHDR 结构
WORD wVKey;
//虚拟键盘码
UINT flags;
//为0
}TV_KEYDOWN;
6.TV_DISPINFO 结构
提供与表项的显示有关的信息。该结构的定义如下:
typedef struct _TV_DISPINFO {
NMHDR hdr;
TV_ITEM item;
}TV_DISPINFO;
MFC 的CTreeCtrl 类封装了树形视图。该类的Create 成员函数负责控件的创建,该函数
的声明如下:
BOOL Create(DWORD dwStyle, const RECT& rect,CWnd* pParentWnd,UINT nID);
其中参数dwStyle 是如表5-23 所示的控件风格的组合。
枫叶文学网www.fywxw.com
第5 章 常用控件
·139·
表5-23 树型控件风格
控件风格 含义
TVS_HASLINES 在父项与子项间连线以清楚地显示结构
TVS_LINESATROOT 只在根部画线
TVS_HASBUTTONS 显示带有"+"或"-"的小方框来表示某项能否被展开或已展开
TVS_EDITLABELS 用户可以编辑表项的标题
TVS_SHOWSELALWAYS 即使控件失去输入焦点,仍显示出项的选择状态
TVS_DISABLEDRAGDROP 不支持拖动cāo作
除上表的风格外,一般还要指定WS_CHILD 和WS_VISIBLE 窗口风格。对于用对话框
模板创建的树形视图控件,可以在控件的属xìng对话框中指定上表中列出的控件风格。例如,
在属xìng对话框中选择Has buttons,相当于指定了TVS_HASBUTTONS 风格。
5.9.2 CtreeCtrl 类的主要成员函数
CTreeCtrl 类提供了大量的成员函数。对于常用的函数,下面结合实际应用进行介绍。
1.SetImageList()函数
向树形视图中chā入新的表项。首先应提供一个TV_INSERTSTRUCT 结构并在该结构中
对chā入项进行描述。如果要在树形视图中显示图像,则应该先创建一个CImageList 对象并使
该对象包含一个位图序列,然后调用SetImageList 为树形视图设置位图序列。最后调用
InsertItem 函数把新项chā入到树形视图中。该函数的声明如下:
CImageList* SetImageList(CImageList * pImageList,int nImageListType);
参数pImageList指向一个CImageList对象,参数nImageListType一般应为TVSIL_NORMAL。
2.InsertItem()函数
该成员函数声明如下:
HTREEITEM InsertItem( LPTV_INSERTSTRUCT lpInsertStruct );
参数lpInsertStruct 指向一个TV_INSERTSTRUCT 结构。函数返回新chā入项的句柄。
3.DeleteItem()和DeleteAllItems()函数
用DeleteItem()函数来删除指定项,用DeleteAllItems()函数删除所有项。函数的声明如下:
BOOL DeleteItem(HTREEITEM hItem);
BOOL DeleteAllItems();
cāo作成功则函数返回TRUE,否则返回FALSE。
4.Expand()函数
树形视图控件会根据用户的输入自动展开或折叠子项。但有时需要在程序中展开或折叠
指定项,则应该调用Expand,该函数的声明为
BOOL Expand(HTREEITEM hItem,UINT nCode);
参数hItem 指定了要展开或折叠的项。参数nCode 是一个标志,指定了函数应执行的cāo
作,它可以是TVE_COLLAPSE(折叠)、TVE_COLLAPSERESET(折叠并移走所有的子项)、
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·140·
TVE_EXPAND(展开)或TVE_TOGGLE(在展开和折叠状态之间翻转)。
5.GetSelectedItem()和SelectItem()函数
要查
松语文学免费小说阅读_www.16sy.com