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

猜你喜欢

转载自blog.csdn.net/m0_37251750/article/details/131953414