| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 9766 人关注过本帖, 1 人收藏
标题:[原创]CListCtrl详解
只看楼主 加入收藏
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏(1)
 问题点数:0 回复次数:22 
[原创]CListCtrl详解

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

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

0gjad9M4.rar (48.23 KB) [原创]CListCtrl详解



这个增强的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<LPNMLISTVIEW>(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()对此无能为力。

以后我会不断更新本文,增加其它CListCtrl的功能,并讲解相关问题。


[此贴子已经被作者于2006-7-16 14:38:19编辑过]



qcL7xNUH.rar (32.08 KB) [原创]CListCtrl详解



DpWx0Fp3.jpg (23.64 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册


elprAoWd.rar (44.29 KB) [原创]CListCtrl详解



CYYcxK82.jpg (23.41 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册


gsgtrjfb.rar (41.07 KB) [原创]CListCtrl详解



e6xIVycE.rar (46.84 KB) [原创]CListCtrl详解

搜索更多相关主题的帖子: CListCtrl 详解 鼠标 控件 字体 
2006-07-08 16:53
天地乾坤
Rank: 1
等 级:新手上路
帖 子:85
专家分:0
注 册:2005-11-21
收藏
得分:0 

斑竹辛苦了~~

2006-07-09 08:34
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
得分:0 

新加了CheckBox,同时可以显示彩色字体和粗体。以后加入位图或者按钮应该没什么难度。


http://myajax95./
2006-07-09 14:47
xurundong
Rank: 1
等 级:新手上路
帖 子:19
专家分:0
注 册:2006-4-10
收藏
得分:0 
谢谢
谢谢,我去看看有用不。
2006-07-11 08:12
ljypetrel
Rank: 1
等 级:新手上路
帖 子:31
专家分:0
注 册:2006-4-3
收藏
得分:0 
ListReport.obj : error LNK2001: unresolved external symbol "public: __thiscall CCSVLineParser::~CCSVLineParser(void)" (??1CCSVLineParser@@QAE@XZ)
ListItem.obj : error LNK2001: unresolved external symbol "public: __thiscall CCSVLineParser::~CCSVLineParser(void)" (??1CCSVLineParser@@QAE@XZ)
ListReport.obj : error LNK2001: unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall CCSVLineParser::GetFullString(bool)" (?GetFullString@CCSVLineParser@@QAE?AV?$basic
_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z)
ListItem.obj : error LNK2001: unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall CCSVLineParser::GetFullString(bool)" (?GetFullString@CCSVLineParser@@QAE?AV?$basic_s
tring@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z)
ListReport.obj : error LNK2001: unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall CCSVLineParser::GetAt(int,bool)" (?GetAt@CCSVLineParser@@QAE?AV?$basic_string@DU?$
char_traits@D@std@@V?$allocator@D@2@@std@@H_N@Z)
ListItem.obj : error LNK2001: unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall CCSVLineParser::GetAt(int,bool)" (?GetAt@CCSVLineParser@@QAE?AV?$basic_string@DU?$ch
ar_traits@D@std@@V?$allocator@D@2@@std@@H_N@Z)
ListReport.obj : error LNK2001: unresolved external symbol "public: unsigned int __thiscall CCSVLineParser::size(void)" (?size@CCSVLineParser@@QAEIXZ)
ListItem.obj : error LNK2001: unresolved external symbol "public: unsigned int __thiscall CCSVLineParser::size(void)" (?size@CCSVLineParser@@QAEIXZ)
ListReport.obj : error LNK2001: unresolved external symbol "public: void __thiscall CCSVLineParser::SetFullString(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?SetFullString@CCSVLineParser@@QAEXV?$basic_
string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
ListReport.obj : error LNK2001: unresolved external symbol "public: __thiscall CCSVLineParser::CCSVLineParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0CCSVLineParser@@QAE@V?$basic_string@DU?$char_
traits@D@std@@V?$allocator@D@2@@std@@@Z)
ListItem.obj : error LNK2001: unresolved external symbol "public: __thiscall CCSVLineParser::CCSVLineParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0CCSVLineParser@@QAE@V?$basic_string@DU?$char_tr
aits@D@std@@V?$allocator@D@2@@std@@@Z)
ListItem.obj : error LNK2001: unresolved external symbol "public: void __thiscall CCSVLineParser::SetAt(int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?SetAt@CCSVLineParser@@QAEXHAAV?$basic_string@DU
?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
Debug/autoDial.exe : fatal error LNK1120: 7 unresolved externals
Error executing link.exe.
2006-07-11 16:37
ligt0610
Rank: 1
等 级:新手上路
帖 子:204
专家分:5
注 册:2006-6-29
收藏
得分:0 
作为一个初学者感觉好难
得加油了

通过不断的学习与思考才是提高自己能力的最好途径。。。。。。。
2006-07-11 22:13
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
得分:0 
5楼的,我刚试了一下,没有这个问题,可能是你打开project的方法不对。可以试着重新下载,或者把包里的CSVLineParser.h和.cpp重新加到project中。

http://myajax95./
2006-07-11 22:54
cantyming
Rank: 1
等 级:新手上路
帖 子:28
专家分:0
注 册:2006-7-9
收藏
得分:0 
那是一个什么样个控件
是组合控件吗
2006-07-12 08:30
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
得分:0 
是个CListCtrl,以后会加上位图,没准下拉菜单等功能。

http://myajax95./
2006-07-14 00:16
菜gua
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2006-5-25
收藏
得分:0 
2006-07-15 12:14
快速回复:[原创]CListCtrl详解
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032558 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved