WTL Application Develop Use CListViewCtrl Control With LVS_OWNERDATA Style (virtual ListCtrl)

本文介绍了在Visual Studio 2005环境下,结合Win CE 6.0和WTL 8.1库,使用CListViewCtrl控件的LVS_OWNERDATA风格开发一个虚拟列表的应用。内容涉及COwnerDraw、CCustomDraw、CImageList等组件的使用,以及如何处理LVN_GETDISPINFO和LVN_ODCACHEHINT消息,实现文件过滤和自定义图标显示。同时,文章讨论了在LVS_ICON样式下显示图片文件的挑战,包括自定义滚动条、动态创建ImageList和绘制图片缩略图的方法。
摘要由CSDN通过智能技术生成

 

Visual Studio2005 + Win CE 6.0 + WTL 8.1

 

WTL Application Develop Use CListViewCtrl Control With LVS_OWNERDATA Style (virtual ListCtrl)

 

For next wentao

 

Include: COwnerDraw, CCustomDraw, CImageList, Base On Dialog, WM_MEASUREITEM

 

Summary:开发一个车载系统的SD卡,USB中文件的查看应用模块,其中对图像,音乐,视频文件进行过滤并在ListViewCtrl控件中显示。

              根据需求,整套系统要与WinCE 6.0系统默认风格区别的统一风格,所以所有文件的图标和显示内容都需要自己来Draw

              其中音乐和视频文件以LVS_REPORT方式显示,利用ImageList根据不同的文件画出不同的ICON,再显示文件名。Item被选中时,Item的背景色与文件名颜色改变。

              图像文件的显示比较复杂,用LVS_ICON方式显式,需要自己画出一定大小的图像缩略图(不同格式的需自行解码为bmp格式)。选择时用一颜色框圈中图片。

              由于风格的问题,还需要自己实现一个ScrollBar,并把系统默认的隐藏。

 

考虑到硬件发展的速度,外存设备的大小成指数上升,所以文件个数成百上千已经不足为奇,

特别是图片文件,为了实现快速查找文件并显示出来,所以用virtual list(也就是在创建

ListViewCtrl的时候添加LVS­_OWNERDATA Style),因为virtual list不保存数据。

Virtual list的用法,建议认真看一遍下面的这篇Article:

http://www.codeproject.com/KB/list/virtuallist.aspx

 

这篇文章包函的知识点非常多,而且非常实用,虽然些没有用到,就像

LVN_ODFINDITEM消息的处理,还有check boxes的使用,等等。

不过作者对LVN_ODCACHEHINT处理讲得比较简单,其实这条消息是非常重要的,只是作者实现的功能不需要对这个消息进行处理而已。

ListViewCtrl控件通常会与ImageList一同使用,用以显示Item的图标,我在开发中以LVS_REPORT Style过滤视频和音乐文件的时候就用到了下面这条图片List来输出。

CImageList来输出一系列固定的图片,只需先判断文件的属性,然后指定一个Index就可以把图标Draw出来。

而我对图片文件就过滤就不这么简单,因为图片是以LVS_ICON Style显示的,每找到一张图片都把它的缩略图显示出来,这就要动态创建一张ImageList

而我在前面讲过,virtual ListCtrl是不保存数据的,当它需要数据的时候才向我们要,我们就把准备好的数据给它,这样,我们就要处理LVN_ODCACHEHINT消息了,在这里我们可以向ListViewCtrl提供从第几条到第几条需要用到的数据。

 

在这次的开发中,CImageList我也是第一次用到,不难,不过用的好的话真的非常方便。我以前试过设置一个定时器,在一系列图片当中,自己计算每次截取的部分显示出来,实现一个动画闪光就效果,虽然也不会很难,但显然使用CImageList来画比较规范。

CImageList的在上面的例子中也有用到,你可以上那个网站,注册一个会员,就可以下载到源码,可以参考一下如何使用,或者看MSDN

http://www.codeproject.com/KB/list/virtuallist.aspx

codeproject这个网站提供非常丰富的源码下载,值得注册一个会员)

 

如果不用CImageList先保存Icon,直接找一个画一个,也可以,不过还是有必要创建一个CImageList与控件关联,并加载一张你将要显示的Icon大小的图,用以CListViewCtrl确定Icon的大小。这一点很重要,花了很多时间在这里,因为就算SetIconSpacing()还是无法取到Icon的大小。

OnCreate()中,初始化CImageList:

   m_ImageList.Create(IDB_FOLDER, ICON_WIDTH, 1, RGB(0, 0, 0));

SetImageList(m_ImageList, LVSIL_NORMAL);

还有一点非常重要,一定不能在OnCreate()中简单地SetMsgHandled(FALSE);一定要在一开始先初始化基类:

DefWindowProc(m_pCurrentMsg->message, m_pCurrentMsg->wParam , m_pCurrentMsg->lParam);

       否则所有在OnCreate()中的对ListViewCtrl的初始化都没有一点作用!!!

       要实现自己对ListViewCtrl中的Item进行绘制,无非三种方法:1.继承COwnerDraw,响应DrawItem消息,有OnDrawItem()中进行绘制。2.继承CCustomDraw,OnPrePaint()中进行绘制。用CustomDraw来处理,要自己控制步骤,对消息的处理要十分小心,特别是返回值。3.就是在OnPaint()中老老实实地一条一条画。

 

       要画出自己风络的Item,要解决三件事,获得当前ItemDCRECTID。最重要还是ID,可以选的话,当然在DrawItem中画,来一条处理一条,在lpDrawItemStruct中,有你需要的所有信息。在CustomDraw中也差不多,而OnPaint中,它的绘图要求就一次性过来的,所以要自己计算ID

 

先看一下COwnerDrawCCustom的用法吧:

http://www.codeproject.com/KB/wtl/wtl4mfc5.aspx

 

 

 

如果是基于对话框的控件开发,还需要掌握DDX的知识:

http://www.codeproject.com/KB/wtl/wtl4mfc4.aspx

 

     准备知识这样就差不多了,可以开始开发了。

     先是用基于对话框的吧,用对话框作为父窗口, 这样有几个好处,首先就是资源可以统一管理,排版的工作全部都可以在OnSize()里面做,当然你也可以在资源中进行排版,不过这对于比较精细的排版有一定的困难,因为在资源中,不是以像素为单位的,而且经常会有一两个像素的误差。如果你在程序中要取客户区与屏幕的大小判断是否相等,这样就不能简单在用==来判断。

 

       首先我们当然要创建两个类,一个是自己的ListViewCtrl,另一个是自己的ScrollBar.

 

class CFSListViewCtrl : public CWindowImpl<CFSListViewCtrl, CListViewCtrl>

 

DECLARE_WND_SUPERCLASS(L"CFSListViewCtrl", CListViewCtrl::GetWndClassName())

 

为什么不是这个继承呢?CFSListViewCtrl : public CListViewCtrl

因为CListViewCtrl只是一个简单的控件,在WTL中,其他控件也是一样,这样继承就没有了消息循环,没有什么作用。

       在上面我们已经讲到,在CFSListViewCtrl的消息循环中我们要处理这两个消息,

REFLECTED_NOTIFY_CODE_HANDLER_EX(LVN_GETDISPINFO, OnGetdispinfo)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值