MFC listctrl修改背景颜色

news2025/5/13 10:27:26

在这里插入图片描述
在 MFC 中修改 ListCtrl 控件的行背景颜色,需要通过自绘(Owner-Draw)机制实现。以下是详细的实现方法:

方法一:通过自绘(Owner-Draw)实现

步骤 1:启用自绘属性

在对话框设计器中选择 ListCtrl 控件,右键点击属性 → 样式 → 勾选 “自绘”(Owner Draw Fixed)。

步骤 2:处理 NM_CUSTOMDRAW 消息

在 ListCtrl 所在的对话框类(如 CMyDialog)中添加消息处理函数:

// 在对话框类头文件(.h)中声明
afx_msg void OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult);

// 在对话框类实现文件(.cpp)中添加消息映射
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
    // ... 其他消息映射 ...
    ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, &CMyDialog::OnNMCustomdrawList1)
END_MESSAGE_MAP()

// 实现消息处理函数
void CMyDialog::OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult) {
    LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
    *pResult = CDRF_DODEFAULT;

    // 阶段 1:预处理
    if (CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage) {
        *pResult = CDRF_NOTIFYITEMDRAW;
    }
    // 阶段 2:绘制项目
    else if (CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage) {
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
    }
    // 阶段 3:绘制子项
    else if ((CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage) {
        int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);  // 当前行
        int nSubItem = pLVCD->iSubItem;  // 当前列

        // 根据条件设置背景色和文本色
        if (nItem == 0) {  // 例如:第一行设置为红色背景
            pLVCD->clrTextBk = RGB(255, 200, 200);  // 浅红色背景
            pLVCD->clrText = RGB(0, 0, 0);  // 黑色文本
        }
        else if (nItem == 1) {  // 第二行设置为蓝色背景
            pLVCD->clrTextBk = RGB(200, 200, 255);  // 浅蓝色背景
            pLVCD->clrText = RGB(0, 0, 0);  // 黑色文本
        }
        else {
            // 默认颜色(使用系统默认)
            pLVCD->clrTextBk = ::GetSysColor(COLOR_WINDOW);
            pLVCD->clrText = ::GetSysColor(COLOR_WINDOWTEXT);
        }

        *pResult = CDRF_NEWFONT;  // 使用新设置的颜色
    }
}

方法二:自定义 ListCtrl 类

更优雅的方式是创建一个继承自 CListCtrl 的自定义类,封装自绘逻辑。

步骤 1:创建自定义类
// MyListCtrl.h
#pragma once

class CMyListCtrl : public CListCtrl {
    DECLARE_DYNAMIC(CMyListCtrl)

public:
    CMyListCtrl();
    virtual ~CMyListCtrl();

protected:
    DECLARE_MESSAGE_MAP()
    afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
};

// MyListCtrl.cpp
#include "stdafx.h"
#include "MyListCtrl.h"

IMPLEMENT_DYNAMIC(CMyListCtrl, CListCtrl)

CMyListCtrl::CMyListCtrl() {}
CMyListCtrl::~CMyListCtrl() {}

BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CMyListCtrl::OnNMCustomdraw)
END_MESSAGE_MAP()

void CMyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult) {
    LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
    *pResult = CDRF_DODEFAULT;

    if (CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage) {
        *pResult = CDRF_NOTIFYITEMDRAW;
    }
    else if (CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage) {
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
    }
    else if ((CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage) {
        int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
        
        // 根据条件设置颜色(示例:交替行颜色)
        if (nItem % 2 == 0) {
            pLVCD->clrTextBk = RGB(240, 240, 240);  // 浅灰色背景
        }

        *pResult = CDRF_NEWFONT;
    }
}
步骤 2:在对话框中使用自定义类
  1. 在对话框头文件中添加成员变量:

    class CMyDialog : public CDialogEx {
        // ...
    private:
        CMyListCtrl m_listCtrl;  // 自定义 ListCtrl
    };
    
  2. 在对话框的 DoDataExchange 函数中关联控件:

    void CMyDialog::DoDataExchange(CDataExchange* pDX) {
        CDialogEx::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_LIST1, m_listCtrl);
    }
    
  3. 在对话框初始化时设置 ListCtrl 属性:

    BOOL CMyDialog::OnInitDialog() {
        CDialogEx::OnInitDialog();
        
        // 设置 ListCtrl 样式
        m_listCtrl.SetExtendedStyle(m_listCtrl.GetExtendedStyle() | 
                                   LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
        
        // 添加列和数据...
        
        return TRUE;
    }
    

进阶技巧:动态更新行颜色

如果需要在运行时动态更改某行的颜色,可以在自定义类中添加公共方法:

// 在 CMyListCtrl 类中添加
public:
    void SetItemBackgroundColor(int nItem, COLORREF color) {
        // 使用 CMap 存储每行的颜色
        m_rowColors.SetAt(nItem, color);
        InvalidateRect(NULL);  // 重绘列表
    }

private:
    CMap<int, int, COLORREF, COLORREF> m_rowColors;  // 存储行颜色的映射表

// 修改 OnNMCustomdraw 函数
void CMyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult) {
    // ... 前面的代码不变 ...
    
    else if ((CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage) {
        int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
        
        // 检查是否有自定义颜色
        COLORREF bkColor;
        if (m_rowColors.Lookup(nItem, bkColor)) {
            pLVCD->clrTextBk = bkColor;
        }
        
        *pResult = CDRF_NEWFONT;
    }
}

使用时调用:

m_listCtrl.SetItemBackgroundColor(2, RGB(255, 255, 200));  // 第三行设置为黄色背景

注意事项

  1. 性能考虑:自绘会增加渲染开销,对于大数据量列表,建议使用虚拟列表(LVS_OWNERDATA 样式)。
  2. 选中状态:默认选中状态的颜色可能覆盖自定义颜色,可通过判断 pLVCD->nmcd.uItemState & CDIS_SELECTED 来特殊处理。
  3. 字体设置:若需要自定义字体,需在代码中设置 pLVCD->nmcd.lpFont

通过以上方法,你可以灵活控制 ListCtrl 中任意行的背景颜色,实现个性化的界面效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2374585.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot+Dubbo+Zookeeper实现分布式系统步骤

SpringBootDubboZookeeper实现分布式系统 一、分布式系统通俗解释二、环境准备&#xff08;详细版&#xff09;1. 软件版本2. 安装Zookeeper&#xff08;单机模式&#xff09; 三、完整项目结构&#xff08;带详细注释&#xff09;四、手把手代码实现步骤1&#xff1a;创建父工…

Linux进程10-有名管道概述、创建、读写操作、两个管道进程间通信、读写规律(只读、只写、读写区别)、设置阻塞/非阻塞

目录 1.有名管道 1.1概述 1.2与无名管道的差异 2.有名管道的创建 2.1 直接用shell命令创建有名管道 2.2使用mkfifo函数创建有名管道 3.有名管道读写操作 3.1单次读写 3.2多次读写 4.有名管道进程间通信 4.1回合制通信 4.2父子进程通信 5.有名管道读写规律&#xff…

精品可编辑PPT | 全面风险管理信息系统项目建设风控一体化标准方案

这份文档是一份全面风险管理信息系统项目建设风控一体化标准方案&#xff0c;涵盖了业务架构、功能方案、系统技术架构设计、项目实施及服务等多个方面的详细内容。方案旨在通过信息化手段提升企业全面风险管理工作水平&#xff0c;促进风险管理落地和内部控制规范化&#xff0…

YOLOv8网络结构

YOLOv8的网络结构由输入端(Input)、骨干网络(Backbone)、颈部网络(Neck)和检测头(Head)四部分组成。 YOLOv8的网络结构如下图所示&#xff1a; 在整个系统架构中&#xff0c;图像首先进入输入处理模块&#xff0c;该模块承担着图像预处理与数据增强的双重任务。接着&#xff0c…

笔记本电脑升级实战手册【扩展篇1】:flash id查询硬盘颗粒

文章目录 前言&#xff1a;一、硬盘颗粒介绍1、MLC&#xff08;Multi-Level Cell&#xff09;2、TLC&#xff08;Triple-Level Cell&#xff09;3、QLC&#xff08;Quad-Level Cell&#xff09; 二、硬盘与主控1、主控介绍2、主流主控厂家 三 、硬盘颗粒查询使用flash id工具查…

AutoDL租用服务器教程

在跑ai模型的时候&#xff0c;容易遇到算力不够的情况。此时便需要租用服务器。autodl是个较为便宜的服务器租用平台&#xff0c;h20仅需七点几元每小时。下面是简单的介绍。 打开网站AutoDL算力云 | 弹性、好用、省钱。租GPU就上AutoDL&#xff0c;并登录账号 登录后&#xff…

goner/otel 在Gone框架接入OpenTelemetry

文章目录 背景与意义快速上手&#xff1a;五步集成 OpenTelemetry运行效果展示代码详解与实践目录结构说明组件加载&#xff08;module.load.go&#xff09;业务组件示例&#xff08;your_component.go&#xff09;程序入口&#xff08;main.go&#xff09; 进阶用法与最佳实践…

杨校老师项目之基于SSM与JSP的鲜花销售系统-【成品设计含文档】

基于SSMJSP鲜花商城系统 随着电子商务的快速发展&#xff0c;鲜花在线销售已成为一种重要的消费模式。本文设计并实现了一个基于JSP技术的鲜花销售管理系统&#xff0c;采用B/S架构&#xff0c;使用SSM框架进行开发&#xff0c;并结合Maven进行项目依赖管理。系统分为前台用户模…

springboot集成langchain4j实现票务助手实战

前言 看此篇的前置知识为langchain4j整合springboot&#xff0c;以及springboot集成langchain4j记忆对话。 Function-Calls介绍 langchain4j 中的 Function Calls&#xff08;函数调用&#xff09;是一种让大语言模型&#xff08;LLM&#xff09;与外部工具&#xff08;如 A…

Feed流推送之订阅推送

分类 feed流分为TimeLine和智能排序&#xff0c;前者不对内容进行过滤&#xff0c;一般根据发布的时间来进行排序&#xff0c;一般用于好友动态或者推送关注的人的消息&#xff0c;而后者一般有着复杂的算法&#xff0c;可以根据算法智能地向目标用户推送内容&#xff0c;例如…

wordpress自学笔记 第四节 商城菜单的添加和修改美化

wordpress自学笔记 摘自 超详细WordPress搭建独立站商城教程-第四节 商城菜单的添加和修改美化&#xff0c;2025 WordPress搭建独立站商城#WordPress建站教程https://www.bilibili.com/video/BV1UwwgeuEkK?spm_id_from333.788.videopod.sections&vd_sourcea0af3bbc6b6d…

GPU L2 Cache一致性协议对科学计算的影响研究

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 一、GPU缓存层级革命&#xff1a;从Volta到Hopper的演进图谱 1.1 架构级缓存策略对比 ‌Vo…

【速写】KV-cache与解码的再探讨(以束搜索实现为例)

文章目录 1 Beam Search 解码算法实现2 实现带KV Cache的Beam Search解码3 关于在带kv-cache的情况下的use_cache参数 1 Beam Search 解码算法实现 下面是一个使用PyTorch实现的beam search解码算法&#xff1a; 几个小细节&#xff1a; 束搜索可以加入length_penalty&#…

(网络)应用层协议-HTTPS

1.HTTPS是什么&#xff1f; HTTPS是应用层的一种协议&#xff0c;是在HTTP的基础上进行了加密层的处理。 HTTP协议的内容都是按照文本的形式进行传输的&#xff0c;所以呢就很容易被别人知道传输的是什么。 我们在了解了TCP/IP之后是知道我们的数据在传输的过程中是通过路由器进…

vue3: pdf.js 3.4.120 using javascript

npm install pdfjs-dist3.4.120 项目结构&#xff1a; pdfjsViewer.vue <template><div><div v-if"loading" class"flex justify-center items-center py-8"><div class"animate-spin rounded-full h-12 w-12 border-b-2 borde…

想实现一个基于MCP的pptx生成系统架构图【初版实现】

技术栈:Python + MCP协议 + python-pptx + FastMCP 核心创新点:通过MCP协议实现PPTX元素的动态化生成与标准化模板管理 当前还是个半成品,后续持续更新。 主要先介绍一下思路。 一、MCP协议与系统设计原理 1.1 为什么选择MCP? 标准化工具调用:通过MCP将PPTX元素生成逻辑封…

PyTorch Lightning实战 - 训练 MNIST 数据集

MNIST with PyTorch Lightning 利用 PyTorch Lightning 训练 MNIST 数据。验证梯度范数、学习率、优化器对训练的影响。 pip show lightning Version: 2.5.1.post0Fast dev run DATASET_DIR"/repos/datasets" python mnist_pl.py --output_grad_norm --fast_dev_run…

力扣2094题解

记录&#xff1a; 2025.5.12 题目&#xff1a; 思路&#xff1a; 暴力遍历。 解题步骤&#xff1a; 1.统计数字出现次数&#xff1a;使用数组cnt来记录输入数组中每个数字的出现次数。 2.生成三位偶数&#xff1a;通过循环从100开始&#xff0c;每次递增2&#xff0c;生成…

DHCP自动分配IP

DHCP自动分配IP 练习1 路由器 Router>en Router#conf t Router(config)#ip dhcp pool ip10 //创建DHCP地址池 Router(dhcp-config)#network 192.168.20.0 255.255.255.0 // 配置网络地址和子网掩码 Router(dhcp-config)#default-router 192.168.20.254 //配置默认网关 Rou…

【CF】Day57——Codeforces Round 955 (Div. 2, with prizes from NEAR!) BCD

B. Collatz Conjecture 题目&#xff1a; 思路&#xff1a; 简单模拟 很简单的模拟&#xff0c;我们只需要快速的找到下一个离 x 最近的 y 的倍数即可&#xff08;要大于 x&#xff09; 这里我们可以这样写 add y - (x % y)&#xff0c;这样就知道如果 x 要变成 y 的倍数还要…