目录

1.合并后文本显示的位置不变

1.1界面展示

1.2 AutoScanTable.h

1.3 AutoScanTable.cpp

1.4 创建表格并添加内容

1.5 核心代码说明

2.合并后文本居中显示

2.1 界面展示

2.2 AutoScanTable.cpp


1.合并后文本显示的位置不变

1.1界面展示

下图中第2行是合并后的效果

1.2 AutoScanTable.h

#pragma onceclass AutoScanTable : public CListCtrl
{
public:enum ROWTYPE{AUTOSCAN_ROW_NORMAL = 0,AUTOSCAN_ROW_DTC = 1};private:unsigned int m_uRowHeight;CRect m_listRect;public:AutoScanTable();virtual ~AutoScanTable();    protected:virtual void DoDataExchange(CDataExchange* pDX);DECLARE_MESSAGE_MAP()
public:void SetRowHeigt(int nHeight);virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);        afx_msg void OnSize(UINT nType, int cx, int cy);
};

1.3 AutoScanTable.cpp

#include "stdafx.h"
#include "MainDisplay.h"
#include "AutoScanTable.h"AutoScanTable::AutoScanTable()
{m_uRowHeight = 60;
}AutoScanTable::~AutoScanTable()
{
}void AutoScanTable::DoDataExchange(CDataExchange* pDX)
{CListCtrl::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(AutoScanTable, CListCtrl)ON_WM_MEASUREITEM_REFLECT()ON_WM_MEASUREITEM()ON_WM_DRAWITEM()ON_WM_SIZE()
END_MESSAGE_MAP()void AutoScanTable::SetRowHeigt(int nHeight)
{m_uRowHeight = nHeight;CRect rcWin;GetWindowRect(&rcWin);WINDOWPOS wp;wp.hwnd = m_hWnd;wp.cx = rcWin.Width();wp.cy = rcWin.Height();wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
}void AutoScanTable::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}void AutoScanTable::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{lpMeasureItemStruct->itemHeight = m_uRowHeight;
}void AutoScanTable::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);LVITEM lvi = { 0 };lvi.mask = LVIF_STATE;//|LVIF_IMAGE; lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;lvi.iItem = lpDrawItemStruct->itemID;BOOL bGet = GetItem(&lvi);BOOL bSelect = ((lvi.state & LVIS_DROPHILITED) || ((lvi.state & LVIS_SELECTED)&& ((GetFocus() == this) || (GetStyle() & LVS_SHOWSELALWAYS))));//画文本背景 CRect bgRect = lpDrawItemStruct->rcItem;if (bSelect)//设置选中颜色{pDC->SetTextColor(RGB(255, 255, 255));//白色文本pDC->FillRect(bgRect, &CBrush(RGB(88, 88, 88)));//深灰色背景}else{int iRow = lvi.iItem;if (iRow % 2 == 0)//设置偶数行文字颜色和背景颜色{pDC->SetTextColor(RGB(0, 0, 0));//黑色文本pDC->FillRect(bgRect, &CBrush(RGB(128, 128, 128))); //灰色背景}else//设置奇数行文字颜色和背景颜色{pDC->SetTextColor(RGB(0, 0, 0));//黑色文本pDC->FillRect(bgRect, &CBrush(RGB(227, 227, 227))); //白色背景}}LVITEM itemParam;itemParam.iItem = lpDrawItemStruct->itemID;itemParam.iSubItem = 0;GetItem(&itemParam);//绘制文本if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE){//得到列数//int nCollumn = GetHeaderCtrl()->GetItemCount();//循环处理CString szText;for (int i = 0; i < GetHeaderCtrl()->GetItemCount(); i++){CRect rcItem;if (!GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem)){continue;}if ((0 != i) && (AUTOSCAN_ROW_NORMAL == itemParam.lParam)){CPen pen(PS_SOLID, 1, RGB(255, 255, 255));pDC->SelectObject(&pen);CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));pDC->SelectObject(pBrush);pDC->Rectangle(rcItem);}szText = GetItemText(lpDrawItemStruct->itemID, i);rcItem.left += 5; rcItem.right -= 1;pDC->DrawText(szText, lstrlen(szText), &rcItem,DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);}}
}void AutoScanTable::OnSize(UINT nType, int cx, int cy)
{CListCtrl::OnSize(nType, cx, cy);ShowScrollBar(SB_HORZ, FALSE);//隐藏水平滚动条
}

1.4 创建表格并添加内容

m_listCtrl.Create(WS_BORDER | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS| LVS_NOCOLUMNHEADER | LVS_OWNERDRAWFIXED, rect, this, IDC_LISTCTRL);//m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | WS_VSCROLL);m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | WS_VSCROLL);m_listCtrl.SetBkColor(RGB(227, 227, 227));m_listCtrl.MoveWindow(GetClientRectEx());m_listCtrl.InsertColumn(0, _T(""), LVCFMT_LEFT, 0);//第0列无法居中显示,一般将其隐藏m_listCtrl.InsertColumn(1, _T("No"), LVCFMT_LEFT, 30); // 插入第2列的列名m_listCtrl.InsertColumn(2, _T("Name"), LVCFMT_LEFT, 450); // 插入第3列的列名m_listCtrl.InsertColumn(3, _T("State"), LVCFMT_LEFT, 70); // 插入第4列的列名m_listCtrl.InsertColumn(4, _T("Operation"), LVCFMT_LEFT, 90); // 插入第4列的列名m_listCtrl.SetColumnWidth(4, LVSCW_AUTOSIZE_USEHEADER);CString strNo;CString strName;CString strState;CString strOpt;for (int i = 0; i <= 2; i++) {strNo.Format(_T("%d"), i);strName.Format(_T("Ecu%d"), i);strState.Format(_T("未扫描"), 20 + i);strOpt = _T("进入系统");LVITEM *item = new LVITEM;if (1 == i){item->lParam = AutoScanTable::AUTOSCAN_ROW_DTC;} else{item->lParam = AutoScanTable::AUTOSCAN_ROW_NORMAL;}item->iItem = i;item->iSubItem = 0;item->mask = LVIF_PARAM;m_listCtrl.InsertItem(item);//m_listCtrl.InsertItem(i, _T("")); // 插入行m_listCtrl.SetItemText(i, 1, strNo);m_listCtrl.SetItemText(i, 2, strName);m_listCtrl.SetItemText(i, 3, strState);m_listCtrl.SetItemText(i, 4, strOpt);}

1.5 核心代码说明

创建表格时:

m_scanList.Create(WS_BORDER | WS_VISIBLE | LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_OWNERDRAWFIXED, rect, this, IDC_LISTCTRL);//m_scanList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | WS_VSCROLL);//设置表格扩展样式时,千万不要加LVS_EX_GRIDLINES,此参数会给表格自动加上白色的网格线,不容易去掉
m_scanList.SetExtendedStyle(LVS_EX_FULLROWSELECT | WS_VSCROLL);

往表格中插入行时

LVITEM *item = new LVITEM;
if (1 == i)
{//因为只会合并部分单元格,所以哪些单元格是需要合并的,我们可以在这里指定一个标识来区分item->lParam = AutoScanTable::AUTOSCAN_ROW_DTC;
}
else
{item->lParam = AutoScanTable::AUTOSCAN_ROW_NORMAL;
}item->iItem = i;//行号
item->iSubItem = 0;//列号
item->mask = LVIF_PARAM;//这里必须用LVIF_PARAM,以使得能传递item->lParam的值m_listCtrl.InsertItem(item);//插入一行

绘制单元格时

//获取单元格信息,以读取itemParam.lParam
LVITEM itemParam;
itemParam.iItem = lpDrawItemStruct->itemID;
itemParam.iSubItem = 0;
GetItem(&itemParam);...//在插入表格的行时,设置了itemParam.lParam,这里通过此值来判断是否为待合并的单元格
//不需要合并的单元格不会执行下面的代码
if ((0 != i) && (AUTOSCAN_ROW_NORMAL == itemParam.lParam))
{CPen pen(PS_SOLID, 1, RGB(255, 255, 255));pDC->SelectObject(&pen);CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));pDC->SelectObject(pBrush);pDC->Rectangle(rcItem);//绘制一个白色边框的矩形
}

2.合并后文本居中显示

2.1 界面展示

下图中第2行是合并后的效果

2.2 AutoScanTable.cpp

要实现上面的效果,只需要拷贝本文“1.3章节”的代码,然后修改一下下面这个函数:

void AutoScanTable::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

void AutoScanTable::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);LVITEM lvi = { 0 };lvi.mask = LVIF_STATE;//|LVIF_IMAGE; lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;lvi.iItem = lpDrawItemStruct->itemID;BOOL bGet = GetItem(&lvi);BOOL bSelect = ((lvi.state & LVIS_DROPHILITED) || ((lvi.state & LVIS_SELECTED)&& ((GetFocus() == this) || (GetStyle() & LVS_SHOWSELALWAYS))));//画文本背景 CRect bgRect = lpDrawItemStruct->rcItem;if (bSelect)//设置选中颜色{pDC->SetTextColor(RGB(255, 255, 255));//白色文本pDC->FillRect(bgRect, &CBrush(RGB(88, 88, 88)));//深灰色背景}else{int iRow = lvi.iItem;if (iRow % 2 == 0)//设置偶数行文字颜色和背景颜色{pDC->SetTextColor(RGB(0, 0, 0));//黑色文本pDC->FillRect(bgRect, &CBrush(RGB(128, 128, 128))); //灰色背景}else//设置奇数行文字颜色和背景颜色{pDC->SetTextColor(RGB(0, 0, 0));//黑色文本pDC->FillRect(bgRect, &CBrush(RGB(227, 227, 227))); //白色背景}}LVITEM itemParam;itemParam.iItem = lpDrawItemStruct->itemID;itemParam.iSubItem = 0;GetItem(&itemParam);//绘制文本if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE){//得到列数//int nCollumn = GetHeaderCtrl()->GetItemCount();//循环处理CString szText;CRect totalRect;for (int i = 0; i < GetHeaderCtrl()->GetItemCount(); i++){CRect rcItem;if (!GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem)){continue;}//记录单元格位置if (0 == i){totalRect = rcItem;} else{totalRect.right = rcItem.right;totalRect.bottom = rcItem.bottom;}if ((0 != i) && (AUTOSCAN_ROW_NORMAL == itemParam.lParam)){CPen pen(PS_SOLID, 1, RGB(255, 255, 255));pDC->SelectObject(&pen);CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));pDC->SelectObject(pBrush);pDC->Rectangle(rcItem);szText = GetItemText(lpDrawItemStruct->itemID, i);rcItem.left += 5; rcItem.right -= 1;pDC->DrawText(szText, lstrlen(szText), &rcItem,DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);}//记录每个单元格的文本szText += GetItemText(lpDrawItemStruct->itemID, i);  szText += "--";}//将合并后的文本一次性显示出来totalRect.left += 230; totalRect.right -= 230;pDC->DrawText(szText, lstrlen(szText), &totalRect,DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);}
}

CListCtrl实现合并单元格的效果相关推荐

  1. 前端导出 excel ,设置字体,列宽,行高,对其方式,合并单元格等效果

    一.先看实现后的图 二.技术 这个表格主要采用了 xlsx-style 来实现 https://www.npmjs.com/package/xlsx-style https://github.com/ ...

  2. el-table合并单元格

    el-table合并单元格 原效果: 这样看起来就很难受,用户体验极其不好,所以,我们把相同的单元格进行合并. 直接上代码 <el-table v-loading="loading&q ...

  3. easyExcel实现动态表头的数据导出,合并单元格,列宽策略

    easyExcel导出(非注解) 思路:先拿到表头数据,再去封装表数据. 一.动态表头 List<List<String>> headTitles = Lists.newArr ...

  4. vxe-table合并单元格后增加选中效果

    <vxe-table:data="retrievalList":row-class-name="setRowClass"@cell-click=" ...

  5. java excel导出 jxl_java使用JXL导出Excel及合并单元格

    jxl是一个韩国人写的java操作excel的工具,在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一点.但jExcelAPI对中文支持 ...

  6. 记一次用iview实现表格合并单元格的具体操作

    记一次用iview实现表格"合并"单元格的具体操作 最近做项目使用iview框架做后台管理系统,第一次使用iview遇到过很多问题,有些小坑也都在网上找到解决方案了,可作为一个通用 ...

  7. 合并单元格两行_28 HTML5标签学习——table单元格的合并

    成长是一辈子的事儿!大家好!我是时问新.分享前端.Python等技术,以及个人成长路上的那些事儿. 表格是可以进行单元格的合并的. 比如下图所示: 单元格A跨了两列,单元格E跨了两行.这就是单元格的合 ...

  8. GridView、Repeater合并单元格

    GridView.Repeater合并单元格 对于GridView.Repeater生成的表格一般都比较固定,但是有时候我们为了报表统计方便常把列名一样的单元格合并以达到易观察统计的效果,这样我们就需 ...

  9. 【EasyUI】DataGrid 合并单元格 - 使用实例

    官方文档 - EasyUI 合并单元格 为了合并数据网格(datagrid)单元格,只需简单地调用 'mergeCells' 方法,并传入合并信息参数,告诉数据网格(datagrid)如何合并单元格. ...

最新文章

  1. 2013年F5应用交付高峰论坛北京站落幕
  2. 重绘Winform窗体
  3. (Oracle学习笔记) sql*plus命令
  4. LSMW one tip - 字段定义
  5. 他复读才考上三本,如今让华为开出201万年薪(其实还拒绝了360万offer)
  6. dotnet Blazor 用 C# 控制界面行为
  7. 免费的.NET混淆和反编译工具
  8. java maximumpoolsize,如果maximumPoolSize小于corePoolSize怎么办? Java 6中可能存在的错误?...
  9. 企业网络高级技术-VTP中继协议(2)
  10. MapReduce之Partitioner的理解
  11. 京东:妥善处理个别显卡售后的问题 不存在“金融化”情况
  12. mac m1 php,【php】Macbook m1 Big Sur 安装php7.1 mondodb 折腾记
  13. mven2 + androMDA 初探
  14. 解决路由器中继不能连中文ssid问题
  15. iOS计算器:采用NSDecimalNumber 进行表达式的精准计算(计算字符串数学表达式)【案例:折扣计算器(完整demo源码)】
  16. Thinkpad预装win10硬盘分区
  17. 辛弃疾·青玉案·元夕
  18. 法大大连续两年中国电子签名市场份额第一
  19. 下列叙述中正确的是计算机课,大学计算机课程练习题(期末)
  20. kubeadm reset重新初始化过程

热门文章

  1. 尚硅谷谷粒音乐项目学习笔记及答疑解惑(1-20集)
  2. 基于selenium爬取去哪儿酒店信息
  3. 计算机信息检索公选课作业,学习#网络信息检索 选修课后的感想
  4. 树莓派飞控PID调节之XJB调
  5. 黑盒测试方法实例分析
  6. 程序员的成长故事之 从微软走向开源的5年
  7. Hbase学习笔记(一)
  8. APP发布平台与加固平台
  9. 【淘宝SEO】官方淘宝搜索排序算法浅析(鬼脚七)
  10. java 判定全角空格_JAVA中半角和全角的判定