在 VC++6.0 下构建可直接编辑的列表控件类
刘 娅
摘要 MFC 中的 CListCtrl 类用于封装列表控件的各种操作,但 CListCtrl 类不支持直接编辑。本文介绍在
VC++6.0 中以 CListCtrl 类为基类构建可直接编辑的列表控件类的方法,并提供一个可运行的实例。
关键词 CListCtrl,列表控件,直接编辑,VC++6.0
一、引言
列 表控件主 要用 来以 各种 方式 显示 一组 数据 记录 供用 户进 行各 种操 作, 是最 常见 的控 件之 一 。
WindowsXP 资源管理器中的“查看”菜单下的 “图标|平铺|列表|详细信息”就是一个非常典型的应用 。
MFC 中的 CListCtrl 类提供了对列表控件操作的基本方法,包括插入一个新的项目 InsertItem、删除一个项
目 DeleteItem、排序项目 SortItems 等,但 CListCtrl 类不支持对项目的直接编辑,只能用 SetItem 或者
SetItemText 来输入数据,使用起来非常不方便。下面介绍在 VC++6.0 中以 CListCtrl 类为基类构建可直接编
辑的列表控件类的方法,并提供一个可运行的实例。
二、实现方法
以在列表控件中实现 CEditBox 的直接编辑为例,介绍构建可直接编辑的列表控件类 CEditListCtrl 的方法:
在 CEditListCtrl 类中设置一个指向编辑框控件的指针 m_edit,当列表控件中的一个子项目被两次不连续的
单击后,使用 m_edit 在该子项目处创建一个编辑框,编辑框的大小与子项目的大小一致。当向编辑框中输
入数据后,单击列表控件,便可将编辑框中的数据写回对应的子项目,同时释放 m_edit 所占用的空间。
当列表控件中的项目通过滚动条滚动时,某一子项目恰好处于编辑状态,则此时该子项目所对应的编辑
框也要跟着滚动。为此,在 CEditListCtrl 类中添加 WM_HSCROLL 和 WM_VSCROLL 消息处理函数,实
现编辑框控件和其所对应的子项目的同步滚动。
在使用列表控件显示数据时,往往只需要编辑部分列中的数据,有些列的数据则不需要进行编辑。为此 ,
在 CEditListCtrl 类中添加一个数据成员 BOOL *m_isedit,m_isedit 是一个数组,用于标志某一列是否可以
进行直接编辑,若 m_isedit[i]为 TRUE,则第 i 列可以进行直接编辑,否则,反之。CEditListCtrl 类中新增
的成员函数 SetEditColomn 用于设置 m_isedit 的值。
以上方法也可用于在列表控件中实现 ComboBox、DropdownList、CheckBox、PushButton 等的直接编辑。
三、CEditListCtrl 类的定义和实现
在 VC++6.0 中创建一个基于对话框的工程,点击菜单“插入 ->类”,在弹出的对话框中设置基类为
CLlistCtrl,派生类为 CEditListCtrl。在 CEditListCtrl 类中定义四个数据成员:
CEdit * m_edit;//指向编辑框,初值为 NULL
BOOL * m_isedit;//允许进行编辑的列,初值为 NULL
int m_item;//当前编辑的行号,初值为-1
int m_subitem;//当前编辑的列号,初值为-1
定义一个常量 ID_LISTEDIT 作为 m_edit 所指向的编辑框的 ID 号。在 CEditListCtrl 中添加 NM_CLICK 的
消息处理函数,实现代码如下:
void CEditListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
if(!m_isedit) return;
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if(!m_edit)
{
m_subitem=pNMListView->iSubItem;
if(pNMListView->iItem!=m_item)
{
m_item=pNMListView->iItem;//标志被单击的项目