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

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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins 拉取 GitHub 私有仓库失败问题

添加仓库的时候提示 stderr: fatal: Cannot prompt because user interactivity has been disabled. 把在 GitHub账户设置中生成的个人访问令牌填到地址里

第54步 深度学习图像识别:MLP-Mixer建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;MLP-Mixer MLP-Mixer&#xff08;Multilayer Perceptron Mixer&#xff09;是Google在2021年提出的一种新型的视觉模型结构。它的主要特点是完全使用多层感知机&#xff08;MLP&#xff09;来处理图像&#…

Docker Compose(九)

一、背景&#xff1a; 对于现代应用来说&#xff0c;大多数都是通过很多的微服务互相协同组成一个完整的应用。例如&#xff0c;订单管理、用户管理、品类管理、缓存服务、数据库服务等&#xff0c;他们构成了一个电商平台的应用。而部署和管理大量的服务容器是一件非常繁琐的事…

Sentinel Dashboard集成Nacos

1.前言 当项目上Sentinel Dashboard做流量监控的时候&#xff0c;我们可以通过Sentinel控制台修改限流配置&#xff0c;但当我们使用Nacos作为配置中心动态配置流控规则的时候&#xff0c;问题就来了。 首先我们要明白&#xff0c;Sentinel Dashboard的配置是从机器的内存中加…

【kubernetes系列】flannel之vxlan模式原理

概述 在Kubernetes中要保证容器之间网络互通&#xff0c;网络至关重要。而Kubernetes本身并没有自己实现容器网络&#xff0c;而是而是借助CNI标准&#xff0c;通过插件化的方式自由接入进来。在容器网络接入进来需要满足如下基本原则&#xff1a; Pod无论运行在任何节点都可…

运算放大器--------加减运算电路

反向求和运算电路 电路 公式 同向加法运算电路 电路 公式 加减运算电路 分别求正向输入的输出和反相输入的输出&#xff0c;然后求和就可以得到到最终的输出。 切记&#xff0c;虚短虚断不是真正的断路和短路。

this关键字和同步异步宏认为微任务理解

目录 js面试常见问题&#xff1a;1.this指向 2.闭包定义和作用 3.原型链 4.异步协程 this关键字 this主要有以下几个使用场合。 1&#xff09;全局环境 &#xff08;2&#xff09;构造函数 &#xff08;3&#xff09;对象的方法 避免多层this 避免数组处理方法中的 this 避免回…

C++(14):重载运算与类型转换

当运算符被用于类类型的对象时&#xff0c;允许我们为其指定新的含义&#xff1b;同时&#xff0c;也能自定义类类型之间的转换规则。和内置类型的转换一样&#xff0c;类类型转换隐式地将一种类型的对象转换成另一种我们所需类型的对象。 当运算符作用于类类型的运算对象时&a…

lc154.寻找旋转排序数组中的最小值

最小元素的位置以旋转次数为索引的位置&#xff0c;但是没有告诉旋转次数&#xff0c;换一种思路 当遇到arr[index] > arr[index1]时&#xff0c;index1为最小元素的位置。首位位置独立比较。但是这种方法还是遍历数组 观察两组数的中间值与首尾的值&#xff0c;又由于数组…

【C++】图

目录 图的存储结构邻接矩阵&#xff08;Adjacency Matrix&#xff09;无向(网)图邻接矩阵代码实现&#xff1a; 邻接表(Adjacency Lists) 图的遍历邻接矩阵深度和广度遍历DFS_BFS邻接表深度和广度遍历DFS_BFS 最小生成树普里姆&#xff08;Prim&#xff09;算法克鲁斯卡尔&…

Spring 6【单例设计模式、bean标签的scope属性、Spring 循环注入问题】(八)-全面详解(学习总结---从入门到深化)

目录 十五、单例设计模式 十六、bean标签的scope属性 十七、Spring 循环注入问题 十五、单例设计模式 设计模式&#xff1a;根据面向对象五大设计思想衍生出的23种常见代码写法&#xff0c;每种写法可以专门解决一类问题。 单例设计模式&#xff1a;保证某个类在整个应用程…

PLC的高端版本通常具有以下特点:

高速处理能力&#xff1a;高端PLC通常具有更快的处理速度和更高的运行频率&#xff0c;可以处理更复杂的控制逻辑和更多的输入/输出信号。 大容量存储&#xff1a;高端PLC通常具有更大的存储容量&#xff0c;可以保存更多的程序和数据&#xff0c;以满足更复杂的应用需求。 多种…

uniapp 选择城市定位 根据城市首字母分类排序

获取城市首字母排序&#xff0c;按字母顺序排序 <template><view class"address-wrap" id"address"><!-- 搜索输入框-end --><template v-if"!isSearch"><!-- 城市列表-start --><view class"address-sc…

基于SSM实现个人随笔分享平台:创作心灵,分享自我

项目简介 本文将对项目的功能及部分细节的实现进行介绍。个人随笔分享平台基于 SpringBoot SpringMVC MyBatis 实现。实现了用户的注册与登录、随笔主页、文章查询、个人随笔展示、个人随笔查询、写随笔、草稿箱、随笔修改、随笔删除、访问量及阅读量统计等功能。该项目登录模…

【C语言day08】

int n5; int a[n][n2] 数组定义下角标不能为变量 注&#xff1a;C99标准中支持了使用变量本题考查的是二维数组的元素访问&#xff0c;A选项是 正确的&#xff0c;X[i]就是第i行的数组名&#xff0c;数组名表示首元素的地址&#xff0c;X[i]表示第i行的第一个元素的地址&#…

Qgis二次开发-QgsMapLayer(加载矢量、栅格图层)

1.简介 QgsMapLayer是所有地图层类型的基类&#xff0c;这是所有地图层类型(矢量&#xff0c;栅格)的基类&#xff0c;首先定义一个QgsMapCanvas地图画布&#xff0c;然后画布上添加图层&#xff0c;使用以下方法设置图层集合。 //设置当前图层集合 void setLayers (const QL…

【c语言进阶】字符函数和字符串函数知识总结

字符函数和字符串函数 前期背景求字符串长度函数strlen函数strlen函数三种模拟实现 长度不受限制的字符串函数strcpy函数strcpy函数模拟实现strcat函数strcat函数模拟实现strcmp函数strcmp函数模拟实现 长度受限制的字符串函数strncpy函数strncpy函数模拟实现strncat函数strnca…

【Qt】QML-02:QQuickView用法

1、先看demo QtCreator自动生成的工程是使用QQmlApplicationEngine来加载qml文件&#xff0c;下面的demo将使用QQuickView来加载qml文件 #include <QGuiApplication> #include <QtQuick/QQuickView>int main(int argc, char *argv[]) {QGuiApplication app(argc,…

electron dialog.showMessageBox使用案例

electron 版本&#xff1a;25.3.1 index.html <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>Hello World!</title><meta http-equiv"Content-Security-Policy" content"script-src self unsa…

MySQL绿色安装和配置

1、 从地址http://dev.mysql.com/downloads/mysql/中选择windows的版本下载。 2、 mysql各个版本的简介 &#xff08;1&#xff09; MySQL Community Server 社区版本&#xff0c;开源免费&#xff0c;但不提供官方技术支持。 &#xff08;2&#xff09; MySQL Enterprise Ed…