CListCtrl实现合并单元格的效果
目录
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实现合并单元格的效果相关推荐
- 前端导出 excel ,设置字体,列宽,行高,对其方式,合并单元格等效果
一.先看实现后的图 二.技术 这个表格主要采用了 xlsx-style 来实现 https://www.npmjs.com/package/xlsx-style https://github.com/ ...
- el-table合并单元格
el-table合并单元格 原效果: 这样看起来就很难受,用户体验极其不好,所以,我们把相同的单元格进行合并. 直接上代码 <el-table v-loading="loading&q ...
- easyExcel实现动态表头的数据导出,合并单元格,列宽策略
easyExcel导出(非注解) 思路:先拿到表头数据,再去封装表数据. 一.动态表头 List<List<String>> headTitles = Lists.newArr ...
- vxe-table合并单元格后增加选中效果
<vxe-table:data="retrievalList":row-class-name="setRowClass"@cell-click=" ...
- java excel导出 jxl_java使用JXL导出Excel及合并单元格
jxl是一个韩国人写的java操作excel的工具,在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一点.但jExcelAPI对中文支持 ...
- 记一次用iview实现表格合并单元格的具体操作
记一次用iview实现表格"合并"单元格的具体操作 最近做项目使用iview框架做后台管理系统,第一次使用iview遇到过很多问题,有些小坑也都在网上找到解决方案了,可作为一个通用 ...
- 合并单元格两行_28 HTML5标签学习——table单元格的合并
成长是一辈子的事儿!大家好!我是时问新.分享前端.Python等技术,以及个人成长路上的那些事儿. 表格是可以进行单元格的合并的. 比如下图所示: 单元格A跨了两列,单元格E跨了两行.这就是单元格的合 ...
- GridView、Repeater合并单元格
GridView.Repeater合并单元格 对于GridView.Repeater生成的表格一般都比较固定,但是有时候我们为了报表统计方便常把列名一样的单元格合并以达到易观察统计的效果,这样我们就需 ...
- 【EasyUI】DataGrid 合并单元格 - 使用实例
官方文档 - EasyUI 合并单元格 为了合并数据网格(datagrid)单元格,只需简单地调用 'mergeCells' 方法,并传入合并信息参数,告诉数据网格(datagrid)如何合并单元格. ...
最新文章
- R语言导入.dta文件实战
- 写了一个 SSO 单点登录的代码示例给胖友!
- 带通 带阻滤波器 幅频响应_二阶有源带通滤波器设计
- javascript --- 混入
- 800多名各国院士热忱参与 第三届“科学探索奖”名单公布
- 轻量级Ajax解决方案:Anthem.NET初探
- Titon Toolkit – 非常强大的用户界面组件
- el表达式 循环_EL表达式+JSTL+Ajax 047
- 对select into表复制的一点思考
- JMockit学习笔记
- 算法:回溯十二 Word Search字符串匹配二维矩阵
- 图片剪裁在线html,前端图片裁剪实战
- 汇智聚力 平台闪耀 —— CDEC2022中国数字智能生态大会深圳举行
- php表格增加一行数据,Excel表格如何增加一行
- java合并流与文件的分割合并示例
- 18118 勇者斗恶龙
- 小程序系统API调用
- Cisco Firepower 1000 Series FTD Software 7.2.0 ASA Software 9.18.1
- 戳破中台泡沫,软件定义让数字中台脱虚入实
- Ajax跨域请求保证同一个session的问题
热门文章
- 零基础掌握“辛普森悖论及因果关系”通俗易懂
- 二次开发:flowable审批流程实践与创建流程源码分析
- 大数据基础之JAVA生成随机数案例
- 国网376.1协议开发 【1】
- 聚宽mysql,聚宽十万个为什么(常见Bug或者警告)
- java 调度任务_Java Quartz 任务指定时间执行,任务调度框架
- php yii框架路由,yii框架如何配置路由
- codeforces1469E. A Bit Similar
- 【CSDN竞赛第四期】参赛体验(第四期徽章什么时候发呀
- 第366章 六道轮回_神墓_辰东_玄幻小说