热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CListCtrl详解

作为MFC中最常用的控件之一,CListCtrl功能的使用,修改及扩展是一个很深,很广泛的问题。在学习的过程中我尽量留下笔记,
作为MFC中最常用的控件之一,CListCtrl功能的使用,修改及扩展是一个很深,很广泛的问题。在学习的过程中我尽量留下笔记,贴在这里和大家共享,欢迎大家挑错。

CListCtrl应用在作表格上最多,所以一般研究的功能都是Report view。
下面的程序实现了一些ListCtrl的加强功能。如果你遇到这个问题想找一个现成的解决方法,你可以下载下面的小程序包。
效果大概如下图:

这个增强的listctrl控件支持CheckBox和彩色字体。同时可以选择当鼠标选中一个格子的时候是全行显示被选中,还是只有这个格子显示被选中。上图中只有当前的格子被选中。
对程序稍作修改可以调整背景颜色等等。
如果想在表格中显示其它控件,只需要按照下面说的方法加入两三个函数就可以了。

下面讲一下怎么应用这个小程序:

这是一个演示增强控件CListReport的程序,如果你要用CListReport这个控件,需要把在Shared Classes里面的六个文件加到你的project中。6个文件所在目录的深度需要一样,否则在include的语句中你需要修改以下路径。

在你的Dialog或者FormView里加上想要用的List Control。在class wizard里给list control加控制变量,variable type里就会有CListCtrl和CListReport两个选后者,然后把List Control的Proprty中View设成Report,然后选Owner draw fixed。就可以了。(如果由于一些原因你在class wizard中找不到CListReport,可以直接加成CListCtrl类,然后在自己的.h中将其改成CListReport,然后在.h最前面 写 #include "路径/ListReport.h")


CListReport的默认显示方式是全行选中,就是当你选中一个格子的时候全行被hightlight,这个和CListCtrl的默认风格一样。想改成选中格子就只加重这个格子,在你的Dialog或FormView的析构函数中初始话风格变量:
CListDemoDlg::CListDemoDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CListDemoDlg::IDD, pParent)
    , m_listDemo(ListReportDefinition::intCellSelect)

用以下方法在表格中进行添加。
在你的主程序中用下面的方法调用: 假设变量名叫m_listDemo
CReportCtrl m_listDemo
在header中加一列:     m_listDemo.AddColumn("Column 0", 0);   //第一个参数是列的文字,第二个参数是列号。
在header中加一列,并指定其宽度为200:    m_listDemo.AddColumn("Column 0", 0, 200);

在第0行第0列加Text "Row 0, Col 000",红色字体,粗体字    
m_listDemo.AddItem(0, 0, "Row 0, Col 000", CListItemText::GenerateProperty(true, RGB(255,  0,  0)))
字太长的时候item会显示成...(如图)。
在第0行第1列加Text "Row 0, Col 100",绿色字体,非粗体字    
    m_listDemo.AddItem(0, 1, "Row 0, Col 100", CListItemText::GenerateProperty(false, RGB(0, 255,  0)));
在第0行第2列加Check Box,初始状态为选中。  
    m_listDemo.AddItem(0, 2, "1", CListItemCheckBox::GenerateProperty());


基本上直接使用的函数就这些了。如果你想作进一步修改
1。改写DrawItem()函数,可以将颜色背景颜色之类的进行调整。
2。如果除了彩色字体和checkbox你还想加入别的类,例如图片类。你只需要作以下几个步骤:
     生成一个普通的C++ class,从CListItem继承下来(#include "路径/ListItem.h",或者直接写在ListItem.h/.cpp中)。
     CListItem是显示没个小格子的基类。对于你的contructor而言,你可以定义格子的风格参数。例如CListItemText中定义了是否 是粗体字,是什么颜色等等。CListItemCheckBox没有任何附加的功能,contructor就是空的。这里我用CSV格式来将所有的参数一 次性输入,然后在画图的时候再将其展开。每个函数的GenerateProperty()就是实现这个功能的。
    好,假设你已经定义好了所有风格,或者没有风格,下面需要写的就是如何显示它了。实现DrawRect(CDC &dc, CRect rcItem, string sText, bool bSelected)函数。    其中提供了dc,格子的位置,格子的内容以及当前是否被选中,干什么都够了。
    显示已经作完了。如果你想实现点击功能,需要写ClickItem和DbClickItem这两个功能。注意在List中如果点的很快,响应将是 double click,所以像CheckBox,必须重载ClickItem和DbClickItem这两个功能,而不能只重载ClickItem参数中第一个 pParent是这个List。另外两个是行和列。

需要注意的问题是,这个ListReport控件使用了ON_WM_LBUTTONDOWN和ON_WM_LBUTTONDBLCLK两个事件,那么其parent就无法获得这两个事件了。作为补偿,这里增加了两个user message:
#define WM_LISTREPORT_LBUTTONDOWN    WM_USER+1201
#define WM_LISTREPORT_LBUTTONDBLCLK    WM_USER+1202
你的主Dialog可以像处理ON_WM_LBUTTONDOWN和ON_WM_LBUTTONDBLCLK一样处理这两个事件,我没有在 PostMessage里面加任何参数,因为好像没太多必要。找到鼠标的位置然后hittest一下就得到所有信息了。如果有什么其它需要的希望大家提 醒。

尚存问题:目前为止发现的问题是有时候连续选中一行的不同列的时候反应比较慢,能长达半秒钟。主要问题大概是ListCtrl本身把这一行来回draw了好几遍。我的DrawItem里面需要更仔细的判断以提高速度。

功能讲完了。制作的原理大概就是在鼠标左键按下的时候记下鼠标的位置,重载DrawItem函数,根据鼠标位置决定文字的背景颜色。程序应该很好懂,有什么问题欢迎大家指正。

其它ListCtrl的常见问题:
问题1:如何左击list的列的时候如何获得当前的列号?
    ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST, OnLvnColumnclickList)

void CDlgLists::OnLvnColumnclickList(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
    int intSelectedColumn = pNMLV->iSubItem;

这里intSelectedColumn就是当前选中的列好了。

这个事件也可以在list内管理,而不在Dialog中管理。看具体的处理事件是什么了。一般的概念就是谁来处理这个事件就有谁管理。例如我的list上 有30行,我想用ListCtrl自身的sort()来重新排序,那么这个事件应该由list管理。如果希望sort有其Dialog实现,就应该在 Dialog中管理。我个人更加倾向于在Dialog中管理。因为list本身能作的事情太有限了。例如我要求sort()结束后在下面的状态栏里显示 Sort by 哪一列,这个很小的附加功能对于list管理的方法而言就很不舒服了。另外如果list显示的是一个巨大的数据库中的某一页,我想sort()的时候当然 是对整个数据库sort()。list控件的sort()对此无能为力。

转:https://www.cnblogs.com/yelinpalace/archive/2009/09/10/1563775.html



推荐阅读
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • Spring Data JdbcTemplate 入门指南
    本文将介绍如何使用 Spring JdbcTemplate 进行数据库操作,包括查询和插入数据。我们将通过一个学生表的示例来演示具体步骤。 ... [详细]
  • 为什么多数程序员难以成为架构师?
    探讨80%的程序员为何难以晋升为架构师,涉及技术深度、经验积累和综合能力等方面。本文将详细解析Tomcat的配置和服务组件,帮助读者理解其内部机制。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 本文详细介绍了如何使用Python中的smtplib库来发送带有附件的邮件,并提供了完整的代码示例。作者:多测师_王sir,时间:2020年5月20日 17:24,微信:15367499889,公司:上海多测师信息有限公司。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 本指南介绍了 `requests` 库的基本使用方法,详细解释了其七个主要函数。其中,`requests.request()` 是构建请求的基础方法,支持其他高级功能的实现。此外,我们还重点介绍了如何使用 `requests.get()` 方法来获取 HTML 网页内容,这是进行网页数据抓取和解析的重要步骤。通过这些基础方法,读者可以轻松上手并掌握网页数据抓取的核心技巧。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 本文详细介绍了 com.apollographql.apollo.api.internal.Optional 类中的 orNull() 方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 包含phppdoerrorcode的词条 ... [详细]
  • 我有一个从C项目编译的.o文件,该文件引用了名为init_static_pool ... [详细]
  • 本文详细介绍了如何使用 Python 进行主成分分析(PCA),包括数据导入、预处理、模型训练和结果可视化等步骤。通过具体的代码示例,帮助读者理解和应用 PCA 技术。 ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
author-avatar
王怡君3018
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有