ClistCtrl 自绘 可设置 每一行的 rect 及 这一行如何绘制
来源:互联网 发布:华钦软件拖欠工资 编辑:程序博客网 时间:2024/06/04 23:32
CListCtrl自绘
转帖地址:http://kb.cnblogs.com/a/1556904/
花了一个晚上学习listctrl的自绘,不是很简单,可能比CRichEditCtrl还要复杂些,遇到第一件事情是自适应改变行高,项目需要,当然也可以是固定,最终解决方案如下:
网上修改CListCtrl项高度的方法一般是扩大字体,及用图片将项高度撑大.
这两种方法虽然简单,但是效果却不是很理想.一种比较理想的方法是自画CListCtrl,不过方法相对来说比较复杂.
要修改CListCtrl的列表项高度,我们需要自己添加 MeasureItem 的消息响应函数,对应的消息是 WM_MEASUREITEM+WM_REFLECT_BASE, 而不是 WM_MEASUREITEM.在CListBox里我们可以直接在 ClassWizard 里将此消息响应添加进 class 里,但是 CListCtrl 默认是没有这个消息响应的,我们需要手动添加它(注意,这里不是 WM_MEASUREITEM. CListCtrl 仅有 WM_MEASUREITEM, 对应的函数为 OnMeasureItem).
为了响应这个消息,我们还需要给列表加上 LVS_OWNERDRAWFIXED 风格.可以在 Create 列表的时候添加,也可以在 PreCreateWindow 虚函数中添加.
添加 MeasureItem 消息响应函数,首先我们需要在类的头文件中添加:
afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
来声明此消息响应函数;
然后在cpp的消息响应宏中添加:
ON_WM_MEASUREITEM_REFLECT()
最后自己建立 MeasureItem 的函数定义:
/////////////////////////////////////////////////////////////////////////////
// CListEx message handlers
void CListEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) //实际上是被mfc 中Cwnd 调用的,所谓的消息
{ //反射其实是 消息在Clistctrl的父窗口中处理后调
if( m_nItemHeight > 0 ) //用MeasureItem函数,所以此函数并不是第一手
lpMeasureItemStruct->itemHeight = m_nItemHeight; //接受消息的
}
其中 m_nItemHeight 是我在头文件中声明的一个成员变量,用于从外部修改列表项高度.
然后我们添加一个方法,便于从外部直接修改列表项高度:
//设置行高
void SetItemHeight(UINT nHeight);
然后是该方法的定义:
//设置行高
void CListEx::SetItemHeight(UINT nHeight)
{
m_nItemHeight = nHeight;
CRect rcWin;
GetWindowRect(&rcWin);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rcWin.Width();
wp.cy = rcWin.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
}
这个方法的最后,使用了 SendMessage 发送 WM_WINDOWPOSCHANGED 消息让 CListCtrl 进入 MeasureItem 的消息响应函数,对列表高度进行修改.
因为我们这里使用了列表的自绘风格,因此列表项需要自己绘制.
首先在类的声明中添加 DrawItem 虚函数声明:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
然后自画 CListCtrl:
void CListEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
int nItem = lpDrawItemStruct->itemID;
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
......
CRect rcBound, rcLabel, rcIcon;
//获得列表项图标,标签,及项的区域
GetItemRect ( nItem, rcIcon, LVIR_ICON );
GetItemRect ( nItem, rcLabel, LVIR_LABEL );
GetItemRect ( nItem, rcBound, LVIR_BOUNDS );
......
}
现在这个 CListCtrl 的重载类就支持自定义列表项高度了.
这两种方法虽然简单,但是效果却不是很理想.一种比较理想的方法是自画CListCtrl,不过方法相对来说比较复杂.
要修改CListCtrl的列表项高度,我们需要自己添加 MeasureItem 的消息响应函数,对应的消息是 WM_MEASUREITEM+WM_REFLECT_BASE, 而不是 WM_MEASUREITEM.在CListBox里我们可以直接在 ClassWizard 里将此消息响应添加进 class 里,但是 CListCtrl 默认是没有这个消息响应的,我们需要手动添加它(注意,这里不是 WM_MEASUREITEM. CListCtrl 仅有 WM_MEASUREITEM, 对应的函数为 OnMeasureItem).
为了响应这个消息,我们还需要给列表加上 LVS_OWNERDRAWFIXED 风格.可以在 Create 列表的时候添加,也可以在 PreCreateWindow 虚函数中添加.
添加 MeasureItem 消息响应函数,首先我们需要在类的头文件中添加:
afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
来声明此消息响应函数;
然后在cpp的消息响应宏中添加:
ON_WM_MEASUREITEM_REFLECT()
最后自己建立 MeasureItem 的函数定义:
/////////////////////////////////////////////////////////////////////////////
// CListEx message handlers
void CListEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) //实际上是被mfc 中Cwnd 调用的,所谓的消息
{ //反射其实是 消息在Clistctrl的父窗口中处理后调
if( m_nItemHeight > 0 ) //用MeasureItem函数,所以此函数并不是第一手
lpMeasureItemStruct->itemHeight = m_nItemHeight; //接受消息的
}
其中 m_nItemHeight 是我在头文件中声明的一个成员变量,用于从外部修改列表项高度.
然后我们添加一个方法,便于从外部直接修改列表项高度:
//设置行高
void SetItemHeight(UINT nHeight);
然后是该方法的定义:
//设置行高
void CListEx::SetItemHeight(UINT nHeight)
{
m_nItemHeight = nHeight;
CRect rcWin;
GetWindowRect(&rcWin);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rcWin.Width();
wp.cy = rcWin.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
}
这个方法的最后,使用了 SendMessage 发送 WM_WINDOWPOSCHANGED 消息让 CListCtrl 进入 MeasureItem 的消息响应函数,对列表高度进行修改.
因为我们这里使用了列表的自绘风格,因此列表项需要自己绘制.
首先在类的声明中添加 DrawItem 虚函数声明:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
然后自画 CListCtrl:
void CListEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
int nItem = lpDrawItemStruct->itemID;
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
......
CRect rcBound, rcLabel, rcIcon;
//获得列表项图标,标签,及项的区域
GetItemRect ( nItem, rcIcon, LVIR_ICON );
GetItemRect ( nItem, rcLabel, LVIR_LABEL );
GetItemRect ( nItem, rcBound, LVIR_BOUNDS );
......
}
现在这个 CListCtrl 的重载类就支持自定义列表项高度了.
- ClistCtrl 自绘 可设置 每一行的 rect 及 这一行如何绘制
- 为CListCtrl每一行设置不同的颜色
- 如何设置ListCtrl控件每一行的背景色
- 如何设置Eclipse中的每一行容纳的代码数
- 如何设置Eclipse中的每一行容纳的代码数
- 使用XIB设置UILabel的换行及设置每一行的字体大小
- 如何设置Eclipse中的每一行容纳的代码数 字节数
- 设置Eclipse中的每一行容纳的代码数
- 显示每一行的序号
- 数据库每一行的长度
- 如何使用read命令读取文件的每一行
- 如何使用read命令读取文件的每一行
- 如何在vi中将每一行的^M去掉。
- 如何在DBGrid的每一行前加一个单选框?
- 如何在Datagrid的每一行里面加入虚线
- 如何在DBGrid的每一行前加一个单选框
- 如何取出每一行某一字符串后面的内容
- 如何在table的每一行添加点击事件
- 编写自己的高效分页SqlHelper
- ts的I帧
- 看《Windows Live Spaces官方关于中国区博客迁移的声明》随想
- ts的I帧
- 提取I帧
- ClistCtrl 自绘 可设置 每一行的 rect 及 这一行如何绘制
- Oracle归档模式和非归档模式的区别
- 深入剖析Spring Web源码(十) - 处理器映射,处理器适配器以及处理器的实现 - 基于HTTP请求处理器流程的实现
- 重构
- NNM内置的数据库Solid定期备份配置方法
- 1.1 开始
- FTP报Inode 是远程的错误信息
- 【探索wireshark】 熟悉GTK+
- 在Eclipse中构建Heritrix1.14.4