CListCtrl自绘「建议收藏」

CListCtrl自绘「建议收藏」CListCtrl自绘有3种方法:第一种:使用WM_ERASEBKGND消息+NM_CUSTOMDRAW消息配合自绘WM_ERASEBKGND消息中绘制背景色,比如偶数行为灰色,奇数行为白色。NM_CUSTOMDRAW消息中设置字体的背景色和字体颜色。好处:保留了控件大多数的原有属性。不需要自己去输出每一个项目的字体。可以非常方便的设置背景色,以及文字的颜色。缺点:不能设置选中

大家好,又见面了,我是你们的朋友全栈君。

CListCtrl自绘有3种方法:

第一种:使用WM_ERASEBKGND消息 + NM_CUSTOMDRAW消息配合自绘

WM_ERASEBKGND消息中绘制背景色,比如偶数行为灰色,奇数行为白色。

NM_CUSTOMDRAW消息中设置字体的背景色和字体颜色。

好处:保留了控件大多数的原有属性。不需要自己去输出每一个项目的字体。可以非常方便的设置背景色,以及文字的颜色。缺点:不能设置选中行颜色。

使用到2个数据结构:

typedef struct tagNMLVCUSTOMDRAW
{

NMCUSTOMDRAW nmcd; // 包含客户自绘控件信息的结构
COLORREF clrText; // 列表视图显示文字的颜色
COLORREF clrTextBk; // 列表视图显示文字的背景颜色
} NMLVCUSTOMDRAW, *LPNMLVCUSTOMDRAW;
NMCUSTOMDRAW 结构的定义如下:
typedef struct tagNMCUSTOMDRAWI
{

NMHDR hdr; // 含有通知信息的NMHDR结构
DWORD dwDrawStage; // 目前绘制的步骤
HDC hdc; // 设备上下文句柄
RECT rc; // 绘制的区域
DWORD dwItemSpec; // 绘制项的说明
UINT uItemState; // 当前项的状态
LPARAM lItemlParam; // 应用程序定义的数据
} NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW

//先定义2个变量

COLORREF m_colRow1;

COLORREF m_colRow2;

1、添加WM_ERASEBKGND小心

BOOL CColoredListCtrl::OnEraseBkgnd(CDC* pDC)   //重载
{

CRect rect;
CColoredListCtrl::GetClientRect(rect);
POINT mypoint;
CBrush brush0(m_colRow1); // 颜色1的画笔
CBrush brush1(m_colRow2); // 颜色2的画笔
int chunk_height=GetCountPerPage(); // 得到每页的记录数
pDC->FillRect(&rect,&brush1); // 先用颜色1填充整个客户区
for (int i=0;i<=chunk_height;i++)
{

GetItemPosition(i,&mypoint); // 得到第i项的位置
rect.top=mypoint.y ;
GetItemPosition(i+1,&mypoint);
rect.bottom=mypoint.y;
pDC->FillRect(&rect,i %2 ? &brush1 : &brush0);
// 根据索引的奇偶不同用不同的画刷
}
brush0.DeleteObject(); // 删除画笔
brush1.DeleteObject();
return FALSE;
}

2、手动添加消息NM_CUSTOMDRAW响应函数

afx_msg void OnCustomDraw( NMHDR * pNotifyStruct, LRESULT * pResult );

ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)

void CColoredListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{

*pResult=0;
LPNMLVCUSTOMDRAW lplvcd=(LPNMLVCUSTOMDRAW)pNMHDR;
int iRow=lplvcd->nmcd.dwItemSpec; // 需要绘画的列表项的索引
switch(lplvcd->nmcd.dwDrawStage) // 绘画阶段
{

case CDDS_PREPAINT : // 在绘画前阶段
{

*pResult=CDRF_NOTIFYITEMDRAW; // 返回列表项绘画通知
return;
}
case CDDS_ITEMPREPAINT: // 在列表项的绘画前阶段
{

lplvcd->clrText=RGB(0,0,0);
*pResult=CDRF_NOTIFYSUBITEMDRAW; // 返回子列表项绘画通知
return;
}
case CDDS_SUBITEM|CDDS_PREPAINT | CDDS_ITEM:// 绘画列表项或子项
{

if(iRow %2)
{

lplvcd->clrTextBk=m_colRow2; // 奇数项的背景为颜色2
}
else
{

lplvcd->clrTextBk=m_colRow1; // 偶数项的背景为颜色1
}
*pResult=CDRF_DODEFAULT;
// 控件完成自绘画,不再发送NM_CUSTOMDRAW通知
return;
}
}

}

第二种:重载WM_PAINT消息,全部自己绘制。新手不推荐。

 

第三种:重载虚函数virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);将列表的Own Draw Fixel勾上。优点是全部由自己控制,包括字体,字体颜色。背景色,选中色,缺点:有点复杂。

这里面的一个重要的数据结构是:DRAWITEMSTRUCT,参考MSDN

DRAWITEMSTRUCT

This structure provides information that the owner window must have to determine how to paint an owner-drawn control or menu item.

typedef struct tagDRAWITEMSTRUCT { 
UINT CtlType; 
UINT CtlID; 
UINT itemID; 
UINT itemAction; 
UINT itemState; 
HWND hwndItem; 
HDC hDC; 
RECT rcItem; 
ULONG_PTR itemData; 
} DRAWITEMSTRUCT; 

我们需要使用到的是ItemID,就是行号,rcItem就是行矩形。

要想知道列号,建立一个CHeaderCtrl*指针,然后就能知道有多少列了。

要想知道某一项的矩形,比如行1,列2的矩形。直接使用GetSubItem(1,2)就可以了。

比如:

void CListCtrlRack::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

  CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
 CRect rcItem = lpDrawItemStruct->rcItem;
 CString strText = “”;
 
 CFont* pFont = GetFont();
 //
 if ((lpDrawItemStruct->itemState&ODS_FOCUS))    //如果是选中行
 {

  //  int nMode = pDC->SetBkMode(TRANSPARENT);
  rcItem = lpDrawItemStruct->rcItem;
  rcItem.bottom -= 1;
  pDC->FillSolidRect(rcItem,RGB(0,255,255));
 }
 else if(lpDrawItemStruct->itemID % 2)   //如果是偶数行
 {

  rcItem = lpDrawItemStruct->rcItem;
  rcItem.bottom -= 1;
  pDC->FillSolidRect(rcItem,RGB(200,200,200));
 }
 else  //如果是奇数行
 {

  rcItem = lpDrawItemStruct->rcItem;
  rcItem.bottom -= 1; 
  pDC->FillSolidRect(rcItem,RGB(255,255,255));
 }
 
 
 lpDrawItemStruct->itemData = LB_SETITEMDATA ;
 
 pDC->SelectObject(pFont);
 for(int i=0;i<GetHeaderCtrl()->GetItemCount();i++)
 {

  strText = GetItemText(lpDrawItemStruct->itemID,i);
  GetSubItemRect(lpDrawItemStruct->itemID,i,LVIR_BOUNDS,rcItem);
  rcItem.bottom -=1; 
  rcItem.left +=5;
  pDC->DrawText(strText,strText.GetLength(),&rcItem,DT_LEFT|DT_SINGLELINE|DT_VCENTER);
 }

}

采用方法3制作的效果如图:可以自己设置字体,设置字体颜色,让列表更好看。

 

 CListCtrl自绘「建议收藏」

CListCtrl自绘「建议收藏」

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/152494.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • SpringBoot常见的经典面试题

    SpringBoot常见的经典面试题SpringBoot常见的经典面试题最近很多人面试时,简历上都说自己熟悉SpringBoot,或者说正在学习SpringBoot,一被面试官问道,都只停留在简单的使用阶段,很多东西都不清楚,下面我整理了一些springboot比较常见的面试题。1、什么是SpringBoot?SpringBoot是Spring开源组织下的子项目,是Spring组件一站式解决方案,…

  • python淘宝抢购脚本_Python 实现毫秒级淘宝、京东、天猫等秒杀抢购脚本「建议收藏」

    python淘宝抢购脚本_Python 实现毫秒级淘宝、京东、天猫等秒杀抢购脚本「建议收藏」本篇文章主要介绍了Python通过selenium实现毫秒级自动抢购的示例代码,通过扫码登录即可自动完成一系列操作,抢购时间精确至毫秒,可抢加购物车等待时间结算的,也可以抢聚划算的商品。该思路可运用到其他任何网站,京东,天猫,淘宝均可使用,且不属于外挂或者软件之类,只属于一个自动化点击工具。#!/usr/bin/envpython#-*-coding:utf-8-*-#2019/0…

  • Perl正则表达式讲解「建议收藏」

    Perl正则表达式讲解「建议收藏」9.3.1原则1正则表达式有三种形式:匹配、替换和转换。在表 9-1 中列有三种正则表达式运算符。接下来对每一个表达式给出详尽解释。匹配:m//这种形式表明在//内部的正则表达将用于匹配 = ~或 !~左边的标量。为了语法上的简化用//,略去m。替换:s///这种形式表明正则表达式将被文本替换,为了语法的简化用//略去s。·转换:tr///这种形式包含一系列的字符

  • 【Landsat 8】介绍

    【Landsat 8】介绍【Landsat8】介绍简介传感器OLI陆地成像仪TIRS热红外传感器相关阅读简介发射日期2013年2月11日传感器OLI,TIRS海拔高度705公里轨道倾角98.2°轨道类型近极轨,太阳同步轨道赤道穿越时间当地时间上午10:00(±15min)(降交点)轨道周期99分钟重访周期16天传感器Landsat8卫星包含OLI和TIRS两种传感器。OLI陆地成像仪包括9个波段,空间分辨率为30米,其中包括一个15米的全色

  • axure 发布后隐藏顶部菜单 或展开顶部菜单[通俗易懂]

    axure 发布后隐藏顶部菜单 或展开顶部菜单[通俗易懂]这样可以实现菜单栏最小化,而且在你鼠标不移动到左上角时,小箭头会隐藏,效果就可以了。axure9.0版本在发布后HTML页面打开时总是在顶部弹出菜单既不美观也影响效果。本人axure小白,摸索半天后发现也不能完全关闭或者不显示(除非代码修改);解决方案就是在请求地址后面拼接。…

  • ajax示例_ajax22

    ajax示例_ajax22script language=”javascript”>function deleteobject(id)…{    if (window.XMLHttpRequest)…{            xmlhttp = new XMLHttpRequest();        }else…{            xmlhttp = new ActiveXObject(“Micro

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号