CListCtrl是列表控件类,列表控件的每一行叫做一个item,每一列叫做一个subitem。每一行和每一列都有个ID号,可以确定唯一的单元格。

最近使用了这个控件,有心得总结如下:

(Dialog模式)

1. 创建列表控件.

定义一个成员变量:CListCtrl *m_pListCtrl;

在初始化对话框的时候创建列表,也就是在OnInitDialog()中创建(在哪里创建没有规定,只要符合对象和资源创建的规则即可。)

m_pListCtrl=new CListCtrl();

m_pListCtrl->Create();

m_pListCtrl->SetExtendedStyle();

Create函数有四个参数,DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID 。第一个参数可以是一些值的组合,用来定义列表的样式,这些值MSDN有详细说明,我只举一个简单的例子,更多的查看MSDN。例如第一个参数使用LVS_REPORT,则表示列表有标题,或者说有列头,很多其他的样式必须是和这个样式搭配使用才有效。第二个参数是列表的坐标和大小,这个矩形框就表示列表的矩形框。第三个参数表示这个列表的父类,如果列表在对话框上或者是在试图上,这个参数可以是this。第四个参数是列表的资源号。

SetExtendedStyle函数只有一个参数,是一些值的组合,用来设置列表的扩展样式,这些值MSDN有详细的说明,我只介绍两个比较常用的。 LVS_EX_GRIDLINES :列表显示网格,只适用于LVS_REPORT 风格。LVS_EX_FULLROWSELECT:当一个item被选中时,它的所有subitems也处于被选中状态,点击任意一个subitem,则可同时选中整个行. 只适用于LVS_REPORT 风格。

2.构建列表

构建列表也就是两个操作,插入列和插入行,前面说过,一个列就是一个subitem,一行就是一个item。

m_pListCtrl->InsertColumn(0,"第一列");

列索引从0开始,InsertColumn函数将在列表中建立一个列,如果数据有三列,就调用三次此函数,索引分别是0,1,2。

m_pListCtrl->InsertItem(0,"第一行");

行索引也从0开始,InsertItem函数在列表中建立一行,且“第一行”的字样显示在的一列中,其他各列为空,如果要在除第一列以外的列中插入数据,调用SetItemText()函数,这个函数有三个参数,第一个参数表示要在第几行插入,第二个参数表示要在第几列插入,第三个参数表示要插入的内容。

可以设定列宽:

LVCOLUMN lvcolumn;
 m_pListCtrl->GetColumn(0,&lvcolumn);
 lvcolumn.mask=LVCF_WIDTH;
 lvcolumn.cx=335;
 m_pListCtrl->SetColumn(0,&lvcolumn);

表示将列宽设定为335像素。

3.操作列表

这里主要介绍一个比较有用的函数SubItemHitTest()

当鼠标停留在列表框上时,此函数会返回鼠标所在的行号,和鼠标所在的列号。

LVHITTESTINFO linfo;
 DWORD dwPos   =   GetMessagePos();   
 CPoint point(LOWORD(dwPos),HIWORD(dwPos));
 m_pListCtrl->ScreenToClient(&point);
 linfo.pt=point;
 linfo.flags=LVHT_ABOVE;
 int iItem=m_pListCtrl->SubItemHitTest(&linfo);

行号保存在linfo.iItem中,列号保存在linfo.iSubItem中,此时可以调用GetItemText()函数获得这个单元格的内容了。

这个方法常用在列表的NM_CLICK和NM_DBLCLK事件中。

此类消息为:

ON_NOTIFY(NM_CLICK, IDC, OnFun)

函数原型:

void OnFun(NMHDR *pNMHDR, LRESULT *pResult)
{
 *pResult = 0;
}

4.列表中的CheckBox

列表有多中风格,带CheckBox是其中常见的一种,设置这种风格的列表只需要在调用SetExtendedStyle函数的时候设置LVS_EX_CHECKBOXES。对CheckBox最常见的操作就是选中和取消,可能是我的知识贫乏,到目前,我还没有找到专门的消息处理这两个操作。要处理这样的操作,我使用下面的方法。

响应列表的NM_CLICK消息,在这个消息处理函数中,判断鼠标点击的位置是文本还是CheckBox,代码如下:

UINT nFlag; 
 DWORD   dwPos   =   GetMessagePos();   
 CPoint    point(LOWORD(dwPos),HIWORD(dwPos));
 m_pList1->ScreenToClient(&point);
 m_pList1->HitTest ( point , &nFlag ) ;

如果nFlag==LVHT_ONITEMSTATEICON ,说明鼠标点中了CheckBox。本可以调用GetCheck函数来获得CheckBox的状态,但是很可惜,CheckBox的状态似乎是在NM_CLICK消息函数结束以后才会改变。所以,在NM_CLICK的消息处理函数中获得CheckBox的状态是没有改变之前的。

还有一点需要注意,假设现在目前CheckBox的状态是选中,那么,当你点击两下鼠标的时候,CheckBox还是选中状态,而且NM_CLICK消息处理函数被执行了两次,所以,结果是正确的。但是当你点击两下鼠标时速度比较快,那么系统会把两次单击鼠标看作一次双击,这样,NM_CLICK的消息处理函数只会执行一次,但是,注意但是,CheckBox的状态却改变了两次。因此,这个时候你看到的CheckBox的状态和程序的结果就相反了。要解决这个问题,就需要在NM_DBLCLK的消息函数中做相应的工作。

以上若有不足之处,希望各位高手指正。

2009/04/01补充:

禁止列表头调整大小,需要派生一个CListCtrl类,重载一下函数为:

BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
        HD_NOTIFY     *pHDN   =   (HD_NOTIFY*)lParam;

switch   (((NMHDR*)lParam)->code)  
        {  
        case   HDN_BEGINTRACKW:  
        case   HDN_BEGINTRACKA:  
        case   HDN_DIVIDERDBLCLICKA:  
        case   HDN_DIVIDERDBLCLICKW:  
            *pResult   =   TRUE;                                 //   disable   tracking  
            return   TRUE;    
        }

return CListCtrl::OnNotify(wParam, lParam, pResult);
    }

列表CListCtrl类使用的更多相关文章

  1. VC/MFC列表CListCtrl类的LVCOLUMN和LVITEM详解

      列表视图控件(List Control)列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来.与树视图类似,列表 ...

  2. 自绘CListCtrl类,重载虚函数DrawItem

    //自绘CListCtrl类,重载虚函数DrawItem void CNewListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TOD ...

  3. WorldWind源码剖析系列:插件列表视图类PluginListView和插件列表视图项类PluginListItem

    WorldWind中的插件类是个庞大的类,可以说从软件设计层面上统筹可扩展的插件体系的设计思想是WorldWind中的精华,值得学习和借鉴.插件体系中的所用到的类可以分为两大类,一类是插件类Plugi ...

  4. QMUI UI库 控件 弹窗 列表 工具类 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. PHP+jQuery 列表分页类 ( 支持 url 分页 / ajax 分页 )

    /* ******* 环境:Apache2.2.8 ( 2.2.17 ) + PHP5.2.6 ( 5.3.3 ) + MySQL5.0.51b ( 5.5.8 ) + jQuery-1.8.3.mi ...

  6. CIconListBox带图标的列表框类

    有时候,我们需要在列表框ListBox中插入带图标的文字项,这就需要自己派生一个类出来了,网上的一个CIconListBox类还不错,网站http://www.codeguru.com/Cpp/con ...

  7. C#用到windows 消息列表Message类MSG的id代号

    C# Constants:private const UInt32 WM_ACTIVATE = 0x0006;private const UInt32 WM_ACTIVATEAPP = 0x001C; ...

  8. 10.C++-构造函数初始化列表、类const成员、对象构造顺序、析构函数

    首先回忆下,以前学的const 单独使用const修饰变量时,是定义的常量,比如:const int i=1; 使用volatile const修饰变量时,定义的是只读变量 使用const & ...

  9. MFC中CListCtrl类依靠CImageList贴图并显示不同图像

    只介绍主要方法,函数的具体参数可在MSDN上查阅 ------------------------------------------- CListCtrl     m_ListCtrl; CImag ...

随机推荐

  1. 单点登录(十四)-----实战-----cas5.0.x登录mongodb验证方式常规的四种加密的思考和分析

    我们在上一篇文章中已经讲解了cas4.2.X登录启用mongodb验证方式 单点登录(十三)-----实战-----cas4.2.X登录启用mongodb验证方式完整流程 但是密码是明文存储的,也就是 ...

  2. Java之集合Collection

    集合 初次学习集合过程中的学习笔记,学习顶层,使用底层.包括常用的API Collection接口 概述 集合 : 集合是Java中提供的一种容器,可以用来存储多个数据. 与数组的区别: 数组的长度是 ...

  3. java多线程 -- ReadWriteLock 读写锁

    写一条线程,读多条线程能够提升效率. 写写/读写 需要“互斥”;读读 不需要互斥. ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁 ...

  4. 转载OPENCV学习随笔

    转载自 亦轩Dhc http://www.cnblogs.com/daihengchen/p/5492729.html 学习笔记:使用opencv做双目测距(相机标定+立体匹配+测距).   最近在做 ...

  5. 微信开发使用 frp 实现本地测试

    前提条件: 1.有公网服务器(如阿里云) 2.需要独立的 80 端口,也就是说,想要实现这个目标,服务器上不能跑 nginx 之类占用 80 端口的程序 3.有可以测试使用的域名,并解析到上面说的公网 ...

  6. linux命令总结之state命令

    ls 命令及其许多参数提供了一些非常有用的文件信息.另一个不太为人所熟知的命令 stat 提供了一些更为有用的信息. [root@Gin scripts]# man stat STAT() User ...

  7. unity脚本封装成dll

    先申明一下这样做是有需要的.当我们需要把脚本提供给第三方使用,而又不希望对方看到具体的实现过程,这时候就需要将代码封装编译成dll文件,供第三方调用.或是多个项目都要用到同一个模块或同样的功能,则可以 ...

  8. python实现域账号登陆

    需求:公司的网路比较变态,每天到了24点自动断开,为了避免一台测试机断网,用python做了一个自动登录 原理:时间到了24点的时候,每隔10秒检测是否可以ping通www.baidu.com,如果p ...

  9. Java并发编程原理与实战二十二:Condition的使用

    Condition的使用 Condition用于实现条件锁,可以唤醒指定的阻塞线程.下面来实现一个多线程顺序打印a,b,c的例子. 先来看用wait和notify的实现: public class D ...

  10. 100baseT、100baseFX、1000base-SX、100/1000base-T

    100baseT.100baseFX.1000base-SX.100/1000base-T 100baseT.100baseFX都是100Mbps速率基带传输系统,唯一的不同是100baseT用的是双 ...