MFC表格控件CListCtrl的改造及用法

news2024/12/26 23:46:39

1、目的

  简单描述MFC的表格控件使用方法。Qt适用习惯了以后MFC用的比较别扭,因此记录一下以备后续复制代码使用。由于MFC原生的CListCtrl比较局限,比如无法改变表格的背景色、文字颜色等设定,因此先对CListCtrl类进行重写,以便满足要求。

2、CListCtrl类改造

#pragma once

class CustomListCtrl : public CListCtrl
{
    DECLARE_DYNAMIC(CustomListCtrl)

public:
    CustomListCtrl();
    virtual ~CustomListCtrl();

protected:
    DECLARE_MESSAGE_MAP()
    virtual void PreSubclassWindow();
public:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

public:
    afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
    void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

public:
    CPtrList m_ptrListCol;  //保存列颜色
    CPtrList m_ptrListItem; //保存Item颜色表
    CPtrList m_colTextColor; //保存列字体颜色
    CPtrList m_ItemTextColor; //保存单元格字体颜色

    bool FindColColor(int col, COLORREF& color); //查找列颜色
    bool FindItemColor(int col, int row, COLORREF& color);
    void SetColColor(int col, COLORREF color);  //设置列颜色
    void SetItemColor(int col, int row, COLORREF color); //设置Item颜色
    void SetColTextColor(int col, COLORREF color);   //设置列文本颜色
    void SetItemTextColor(int col, int row, COLORREF color);

    COLORREF m_color;
    BOOL SetTextColor(COLORREF cr);
public:
    // 字体高度
    int m_fontHeight;
    // 字体宽度
    int m_fontWith;
};


#include "pch.h"
#include "CustomListCtrl.h"

// CustomListCtrl.cpp : 实现文件
//
struct stColor
{
    int nRow;
    int nCol;
    COLORREF rgb;
};
// CustomListCtrl

IMPLEMENT_DYNAMIC(CustomListCtrl, CListCtrl)

CustomListCtrl::CustomListCtrl()
    :m_fontHeight(12)
    ,m_fontWith(0)
{
    m_color = RGB(0, 0, 0);
}

CustomListCtrl::~CustomListCtrl()
{
}


BEGIN_MESSAGE_MAP(CustomListCtrl, CListCtrl)
    ON_WM_MEASUREITEM()
    ON_WM_MEASUREITEM_REFLECT()
END_MESSAGE_MAP()

// CustomListCtrl 消息处理程序

void CustomListCtrl::PreSubclassWindow()
{
    // TODO: 在此添加专用代码和/或调用基类
    ModifyStyle(0, LVS_OWNERDRAWFIXED);
    CListCtrl::PreSubclassWindow();
}

void CustomListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    // TODO: 添加您的代码以绘制指定项
    TCHAR lpBuffer[256];
    LV_ITEM lvi;

    lvi.mask = LVIF_TEXT | LVIF_PARAM;
    lvi.iItem = lpDrawItemStruct->itemID;
    lvi.iSubItem = 0;
    lvi.pszText = lpBuffer;
    lvi.cchTextMax = sizeof(lpBuffer);
    VERIFY(GetItem(&lvi));

    LV_COLUMN lvc, lvcprev;
    ::ZeroMemory(&lvc, sizeof(lvc));
    ::ZeroMemory(&lvcprev, sizeof(lvcprev));
    lvc.mask = LVCF_WIDTH | LVCF_FMT;
    lvcprev.mask = LVCF_WIDTH | LVCF_FMT;

    CDC* pDC;
    pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rtClient;
    GetClientRect(&rtClient);
    for (int nCol = 0; GetColumn(nCol, &lvc); nCol++)
    {
        if (nCol > 0)
        {
            // Get Previous Column Width in order to move the next display item
            GetColumn(nCol - 1, &lvcprev);
            lpDrawItemStruct->rcItem.left += lvcprev.cx;
            lpDrawItemStruct->rcItem.right += lpDrawItemStruct->rcItem.left;
        }

        CRect rcItem;
        if (!GetSubItemRect(lpDrawItemStruct->itemID, nCol, LVIR_LABEL, rcItem))
            continue;

        ::ZeroMemory(&lvi, sizeof(lvi));
        lvi.iItem = lpDrawItemStruct->itemID;
        lvi.mask = LVIF_TEXT | LVIF_PARAM;
        lvi.iSubItem = nCol;
        lvi.pszText = lpBuffer;
        lvi.cchTextMax = sizeof(lpBuffer);
        VERIFY(GetItem(&lvi));
        CRect rcTemp;
        rcTemp = rcItem;

        if (nCol == 0)
        {
            rcTemp.left -= 2;
        }

        if (lpDrawItemStruct->itemState & ODS_SELECTED)
        {
            pDC->FillSolidRect(&rcTemp, GetSysColor(COLOR_HIGHLIGHT));
            pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
        }
        else
        {
            COLORREF color;
            color = GetBkColor();
            pDC->FillSolidRect(rcTemp, color);

            if (FindColColor(nCol, color))
            {
                pDC->FillSolidRect(rcTemp, color);
            }

            if (FindItemColor(nCol, lpDrawItemStruct->itemID, color))
            {
                pDC->FillSolidRect(rcTemp, color);
            }
        }
        pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
        UINT uFormat = DT_CENTER;
        TEXTMETRIC metric;
        pDC->GetTextMetrics(&metric);
        int ofst;
        ofst = rcItem.Height() - metric.tmHeight;
        rcItem.OffsetRect(0, ofst / 2);
        pDC->SetTextColor(m_color);

        CFont nFont, * nOldFont;
        nFont.CreateFont(m_fontHeight, m_fontWith, 0, 0, 0, FALSE, FALSE, 0, 0, 0, 0, 0, 0, _TEXT("宋体"));//创建字体 
        nOldFont = pDC->SelectObject(&nFont);
        DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer), &rcItem, uFormat);
        pDC->SelectStockObject(SYSTEM_FONT);
    }
}

void CustomListCtrl::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值

    CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
void CustomListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{

}

bool CustomListCtrl::FindColColor(int col, COLORREF& color) //查找列颜色
{
    int flag = 0;
    for (POSITION pos = m_ptrListCol.GetHeadPosition(); pos != NULL;)
    {
        stColor* pColor = (stColor*)m_ptrListCol.GetNext(pos);
        if (pColor->nCol == col)
        {
            flag = 1;
            color = pColor->rgb;
            break;
        }
    }
    if (1 == flag)
    {
        return true;
    }
    return false;
}

bool CustomListCtrl::FindItemColor(int col, int row, COLORREF& color) //查找颜色
{
    int flag = 0;
    for (POSITION pos = m_ptrListItem.GetHeadPosition(); pos != NULL;)
    {
        stColor* pColor = (stColor*)m_ptrListItem.GetNext(pos);
        if (pColor->nCol == col && pColor->nRow == row)
        {
            flag = 1;
            color = pColor->rgb;
            break;
        }
    }
    if (1 == flag)
    {
        return true;
    }
    return false;
}

void CustomListCtrl::SetColColor(int col, COLORREF color) //设置列颜色
{
    stColor* pColor = new stColor;
    pColor->nCol = col;
    pColor->rgb = color;
    m_ptrListCol.AddTail(pColor);
}

void CustomListCtrl::SetItemColor(int col, int row, COLORREF color) //设置格子颜色
{
    stColor* pColor = new stColor;
    pColor->nCol = col;
    pColor->nRow = row;
    pColor->rgb = color;
    m_ptrListItem.AddTail(pColor);
}

BOOL CustomListCtrl::SetTextColor(COLORREF cr)  //设置字体颜色
{
    m_color = cr;
    return TRUE;
}

void CustomListCtrl::SetColTextColor(int col, COLORREF color)
{
    stColor* pColor = new stColor;
    pColor->nCol = col;
    pColor->rgb = color;
    m_colTextColor.AddTail(pColor);
}


void CustomListCtrl::SetItemTextColor(int col, int row, COLORREF color)
{
    stColor* pColor = new stColor;
    pColor->nCol = col;
    pColor->nRow = row;
    pColor->rgb = color;
    m_ItemTextColor.AddTail(pColor);
}

3、表格初始化

  初始化表格界面效果
在这里插入图片描述

// 初始化表格界面
CustomListCtrl m_listInput;
void CTestDlg::OnInitInputCtrl()
{
	CRect rect;
	m_listInput.GetClientRect(&rect);

	int nWidth = rect.Width() - 15;

	m_listInput.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_SUBITEMIMAGES | LVS_EX_FULLROWSELECT);
	m_listInput.InsertColumn(0, _T("分支号"), LVCFMT_CENTER, nWidth * 0.08);
	m_listInput.InsertColumn(1, _T("名称"), LVCFMT_CENTER, nWidth * 0.1);
	m_listInput.InsertColumn(2, _T("始节点"), LVCFMT_CENTER, nWidth * 0.08);
	m_listInput.InsertColumn(3, _T("终节点"), LVCFMT_CENTER, nWidth * 0.08);
	m_listInput.InsertColumn(4, _T("需风类型"), LVCFMT_CENTER, nWidth * 0.1);
	m_listInput.InsertColumn(5, _T("风阻R"), LVCFMT_CENTER, nWidth * 0.1);
	m_listInput.InsertColumn(6, _T("风阻△R"), LVCFMT_CENTER, nWidth * 0.1);
	m_listInput.InsertColumn(7, _T("需风量Q(m3/s)"), LVCFMT_CENTER, nWidth * 0.15);
	m_listInput.InsertColumn(8, _T("风量△Q"), LVCFMT_CENTER, nWidth * 0.14);
	m_listInput.InsertColumn(9, _T("调节性"), LVCFMT_CENTER, nWidth * 0.1);
}

4、表格插入内容

在这里插入图片描述

// 表格插入内容
void CTestDlg::setInputData()
{
	m_listInput.DeleteAllItems();
	std::sort(m_vecInit.begin(), m_vecInit.end());

	for (int i = 0; i < m_vecInit.size(); ++i)
	{
		stu_GraphParams& windResult = m_vecInit[i];

		CString sTmp;
		// 分支号
		sTmp.Format("%d", windResult.nNumber);
		m_listInput.InsertItem(i, sTmp);

		// 名称
		m_listInput.SetItemText(i, 1, windResult.sName);

		// 始节点
		sTmp.Format("%d", windResult.nStartJunction);
		m_listInput.SetItemText(i, 2, sTmp);

		// 终节点
		sTmp.Format("%d", windResult.nEndJunction);
		m_listInput.SetItemText(i, 3, sTmp);

		// 需风类型
		m_listInput.SetItemText(i, 4, _T("自然"));
		// 风阻
		CString strResistance;
		strResistance.Format("%.6f", windResult.dResistance);
		m_listInput.SetItemText(i, 5, strResistance);
		
		// △风阻
		CString strResistanceEx;
		strResistanceEx.Format("%.6f", windResult.dResistanceEx);
		m_listInput.SetItemText(i, 6, strResistanceEx);
		
		// 数值改变的话修改单元格颜色
		bool bChange = (strResistanceEx.CompareNoCase(strResistance) != 0) ? true : false;
		if(windResult.dResistanceEx > 0.000001f && bChange)
		{
			COLORREF cf = RGB(255, 0, 0);
			m_listInput.SetItemColor(6,i,cf);
		}

		// 需风量
		sTmp.Format("%.3f", windResult.dFlowRate);
		m_listInput.SetItemText(i, 7, sTmp);

		// 风量
		sTmp.Format("%.3f", windResult.dFlowRateEx);
		m_listInput.SetItemText(i, 8, sTmp);

		// 调节性
		bool bAdjust = windResult.bAdjust;
		if (bAdjust)
		{
			m_listInput.SetItemText(i, 9, _T("是"));
		}
		else
		{
			m_listInput.SetItemText(i, 9, _T("否"));
		}
	}
}

5、双击获取表格选中行的内容

// 双击事件
void CTestDlg::OnNMDblclkInputList(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	*pResult = 0;
	// TODO: 在此添加控件通知处理程序代码
	int nIndex = m_listInput.GetNextItem(-1, LVIS_SELECTED);

	POSITION ps = m_listInput.GetFirstSelectedItemPosition();

	if (NULL == ps)
	{
		return;
	}

	int nItem = m_listInput.GetNextSelectedItem(ps);
	stu_WindEdgeInfo windEdgeInfo;
	windEdgeInfo.sEdgeId = m_listInput.GetItemText(nItem, 0);
	windEdgeInfo.sName = m_listInput.GetItemText(nItem, 1);
	windEdgeInfo.sStartIndex = m_listInput.GetItemText(nItem, 2);
}

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

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

相关文章

哪些报表工具更适合中国企业?看完本文就知道了

企业级报表工具是指能够处理大量数据、支持多种数据源连接、具有强大的数据分析和可视化功能的工具。进入大数据时代&#xff0c;企业数据量剧增、分析需求精细化且要求高效率、高灵活自主性&#xff0c;一般都采用BI报表工具来做智能化、可视化数据分析&#xff0c;推动企业的…

Neo4j数据库中导入CSV示例数据

本文简要介绍Neo4j数据库以及如何从CSV文件中导入示例数据&#xff0c;方便我们快速学习测试图数据库。首先介绍简单数据模型以及基本图查询概念&#xff0c;然后通过LOAD CSV命令导入数据&#xff0c;生成节点和关系。 环境准备 读者可以快速安装Neo4j Desktop&#xff0c;启…

Mysql中(@i:=@i+1)的介绍

i:i1 表达式 生成伪列实现自增序列 语法&#xff1a; select (i:i1) as ,t.* from table_name t,(select i:0) as j (i:i1)代表定义一个变量&#xff0c;每次叠加 1&#xff1b; (select i:0) as j 代表建立一个临时表&#xff0c;j是随便取的表名&#xff0c;但别名一定…

python和c++哪个更值得学,python和c++学哪个简单

大家好&#xff0c;本文将围绕python和c哪个更值得学展开说明&#xff0c;python和c学哪个简单是一个很多人都想弄明白的事情&#xff0c;想搞清楚c和python哪个好学需要先了解以下几个事情。 1、想学编程&#xff0c;选择Python 还是Java或者C&#xff1f; 首先&#xff0c;我…

MySQL索引失效原因及解决方案

MySQL索引失效原因及解决方案 在使用MySQL数据库时&#xff0c;索引是一种重要的性能优化工具。然而&#xff0c;有时候我们可能会遇到索引失效的情况。本文将介绍几种常见的MySQL索引失效原因以及相应的解决方案&#xff0c;并提供SQL语句的错误示例和正确示例。 1. 字符串字…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 二)

Prop装饰器&#xff1a;父子单向同步 Prop装饰的变量可以和父组件建立单向的同步关系。Prop装饰的变量是可变的&#xff0c;但是变化不会同步回其父组件。 概述 Prop装饰的变量和父组件建立单向的同步关系&#xff1a; Prop变量允许在本地修改&#xff0c;但修改后的变化不会…

tinkerCAD案例:11.制作齿轮

tinkerCAD案例&#xff1a;11.制作齿轮 制作齿轮 Add a cylinder to be the main part of the gear. 添加一个圆柱体作为齿轮的主要部分。 说明 Click and drag a cylinder onto the Workplane. 单击圆柱体并将其拖动到工作平面上。 Change the cylinder dimensions to 35mm …

四、约束-1.概述

一、概念 约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 二、目的 保证数据库中数据的正确、有效性和完整性。 三、分类

视觉套件专项活动!与飞桨技术专家一起提升技术实力,更多荣誉奖励等你领取

作为中国最早开源的深度学习框架&#xff0c;飞桨深度践行开源理念&#xff0c;开放拥抱社区&#xff0c;重视生态构建&#xff0c;与开发者和生态伙伴共成长&#xff0c;已成为国内综合竞争力第一的产业级深度学习平台。截至目前&#xff0c;飞桨已凝聚750万名开发者。 在飞桨…

i.MX6ULL(十九) linux gpio子系统

一 简介 pinctrl 子系统重点是设置 PIN( 有的 SOC 叫做 PAD) 的复用 和电气属性&#xff0c; 如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话&#xff0c;那么接下来就要用到 gpio 子系 统了。gpio 子系统顾名思义&#xff0c;就是用于初始化 GPIO 并且提供相…

idea,选中同一个变量高亮显示

阅读复杂代码时&#xff0c;我们经常因为找不清变量位置&#xff0c;而浪费精力重新去看变量名。 效果展示&#xff1a; 在设置里直接搜索按照步骤&#xff0c;勾选然后修改选中变量时的变量背景颜色和字体颜色 这里是设置选中变量时&#xff0c;其他变量的背景颜色和字体颜色…

终于搞懂!数字化、信息化、智能化,到底有什么不同?

引言 随着科技的飞速发展&#xff0c;数字化、信息化和智能化这三个术语在各行各业中频繁出现。然而&#xff0c;许多人对它们之间的区别并不十分清楚。本文旨在阐明数字化、信息化和智能化的含义&#xff0c;探讨它们在实践中的应用&#xff0c;并梳理其异同之处。 一、数字化…

你不知道的AI绘画变现方式

&#x1f3c6; 文章目标&#xff1a;学习AI绘画变现方式 &#x1f340; 入门篇&#xff1a;你不知道的AI绘画变现方式 ✅ 创作者&#xff1a;熊猫Jay ✨ 个人公众号: 熊猫Jay字节之旅 (文末有链接) &#x1f341; 展望&#xff1a;若本篇讲解内容帮助到您&#xff0c;请帮忙点个…

【科研必备】生态系统碳循环模型CENTURY建模方法

CENTURY模型&#xff0c;主要基于过程的陆地生态系统生物地球化学循环模型。主要用于模拟不同土壤-植被系统间C、N、P和S的长期动态。根据土壤有机质的分解速率&#xff0c;CENTURY模型将土壤总有机碳&#xff08;TOC&#xff09;分成了三个碳库&#xff0c;即活性、慢性和惰性…

Rest API 开发分享

概述 REST 从资源的角度来观察整个网络&#xff0c;分布在各处的资源由URI确定&#xff0c;而客户端的应用通过URI来获取资源的表示方式。获得这些表徵致使这些应用程序转变了其状态。随着不断获取资源的表示方式&#xff0c;客户端应用不断地在转变着其状态&#xff0c;所谓表…

js获取本js文件名称

使用 script 标签的 src 属性&#xff1a; 如果您的 JavaScript 文件是通过 script 标签引入的&#xff0c;您可以使用以下方法来获取当前脚本的文件名&#xff1a; var scripts document.getElementsByTagName(script); var currentScript scripts[scripts.length - 1]; va…

CMU 15-445 -- Multi-Version Concurrency Control - 16

CMU 15-445 -- Multi-Version Concurrency Control - 16 引言MVCCExample #1Example #2小结 Design DecisionsConcurrency Control ProtocolVersion StorageAppend-Only StorageTime-Travel StorageDelta Storage Garbage CollectionTuple-Level GCTransaction-Level GC Index …

Android编译报错-keystore2

vendor/mediatek/proprietary/trustzone/trustkernel/source/build/k39tv1_64_bsp_k419/array.c vendor/mediatek/proprietary/trustzone/trustkernel/source/build/k39tv1_64_bsp_k419/cert.dat 这个两个文件和厂家名称等配置信息有关。

STM32CubeMX配置STM32G031多通道ADC采集(HAL库开发)

时钟配置HSI主频配置64M 勾选打开8个通道的ADC 使能连续转换模式 配置好串口&#xff0c;选择异步模式配置好需要的开发环境并获取代码 修改main.c 串口重定向 #include "stdio.h" int fputc(int ch, FILE *f) {HAL_UART_Transmit(&huart1, (uint8_t *)&ch…

SOP8,SOP10,SOP16封装的PY32F002A/PY32F003管脚复用

PY32F0系列的封装 在PY32F0系列的封装可以分为两大类, 20PIN及以上的和小于20PIN的. 20PIN, 24PIN 和 32PIN, 带有独立的 NRST 和 BOOT0, PIN脚互相独立不复用;8PIN, 10PIN 和 16PIN, 没有 BOOT0, 存在多个PIN脚共用同一个物理管脚的情况 这篇主要介绍没有BOOT0的情况如何修…