【MFC】CListCtrl控件(报表样式)—— 内附自制巅峰查询器V1.0源码

01、目录

02、CListCtrl 与 样式介绍

写这篇文章之前,其实我是有写过一篇CListCtrl的介绍文章的,突然发现,自己写的那篇文章介绍得实在太基础,完全就是介绍一下这个控件,导致自己后面做项目时,这个控件费时很久,以至于这次研究了一下,写了这篇文章,这里关于CListCtrl不做重复介绍,感兴趣可以去了解一下这篇文章:https://blog.csdn.net/m0_43458204/article/details/107641264

常规样式与扩展样式:

首先区分LVS_与LVS_EX_,哪些是常规样式,哪些是扩展样式:能在属性对话框里看到的样式都是常规样式,例如LVS_REPORT。

重点介绍一下扩展样式!
常用扩展样式如下表:

样式宏宏描述
LVS_EX_CHECKBOXES您可以获得 ListView_GetCheckState 指定项目的复选框的状态。若要设置检查状态,请使用 ListView_SetCheckState。如果设置了此样式,则当用户单击该复选框,或按空格键在列表视图控件自动切换复选状态
LVS_EX_FLATSB扁平滚动条 列表视图中的启用平面滚动条。如果您需要更多的控制列表视图滚动条的外观,您应该操作平的滚动栏 Api 使用直接的列表视图滚动条。如果更改系统度量,您负责调整与 FlatSB_SetScrollProp 的滚动栏度量。有关进一步的详细信息请参阅平滚动条。
LVS_EX_FULLROWSELECT选择整行/高亮 当选择某个项目时,强调了项目和其所有子项。此样式是仅在 LVS_REPORT 风格结合中可用。
LVS_EX_GRIDLINES绘制表格 显示项及其子项周围的网格线。此样式是仅在 LVS_REPORT 风格结合中可用
LVS_EX_HEADERDRAGDROP报表头可以拖拽 允许拖放的列表视图控件中的列重新排序。此样式是只可用于使用 LVS_REPORT 样式的列表视图控件。
LVS_EX_INFOTIP将提示信息窗口的消息通知父窗口 当列表视图控件使用的 LVS_EX_INFOTIP 样式时,LVN_GETINFOTIP 通知代码发送到父窗口显示工具提示项之前。
LVS_EX_LABELTIP\
LVS_EX_MULTIWORKAREAS多工作区
LVS_EX_ONECLICKACTIVATE单击激活
LVS_EX_REGIONAL\
LVS_EX_SUBITEMIMAGES子项目图标列表
LVS_EX_TRACKSELECT自动换行
LVS_EX_TWOCLICKACTIVATE双击激活
LVS_EX_UNDERLINECOLD\
LVS_EX_UNDERLINEHOT\

因为这里的样式我们是没法更改的,但是有的时候又想显示跟默认不一样的样式,比如选中行不要默认的蓝色。这个时候就需要我们自绘ListCtrl,我试着写了下,但是失败了,遇到点问题没法解决,就没有实现此功能。(后面会补上此类)

03、示例程序——《王者荣耀》玩家信息添加

本程序,不出意外应该是会出很多版,最后成品的效果大概就是,通过QQ或者微信登陆,选择大区,可以查询当前大区的各种榜单排行榜
内含:python爬虫、MFC界面搭建、Json解析、远程连接、等相关知识。

第一版界面图如下所示:(基本信息)

在这里插入图片描述
巅峰查询器V1.0内容包括:基础信息支持手动添加、单选删除、全部删除、选择一项数据、选择多项数据(支持反选、全选)。

关于界面的搭建,这里属于MFC基本功,我这里不多叙述,直接开始我们的码程序教程。

下面将贴上部分核心源码及操作:

  • 初始化:

在这里插入图片描述

在这里插入图片描述
如此,我们就可以去OnInitDialog()中添加初始化程序,代码如下:

m_ListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_INFTIP);

DWORD dwStyle = ::GetWindowLong(m_ListCtrl.m_hWnd, CWL_STYLE);
dwStyle &= ~(LVS_TYPEMASK);  //~ 按位取反,此语句用于去掉TYPEMASK风格

SetWindowLong(m_ListCtrl.m_hWnd,CWL_STYLE, dwStyle | LVS_REPORT | LVS_NOLABELWRAP | LVS_SHOWSELALWAYE | LVS_EDITLABELS);

//设置扩展风格:使选中行高亮(蓝色)、网格线、增加CheckBox
DWORD styles = LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES; 
ListView_SetExtendedListViewStyleEx(m_ListCtrl.m_hWnd, styles, styles);

//加入列头
const TCHAR* ListName[5] = {_T("ID"),_T("所在大区"),_T("当前段位"),_T("最高段位"),_T("巅峰积分")};

//数据列表
LV_COLUMN lvCol;
CRect rect;
m_ListCtrl.GetWindowRect(&rect);
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);

int wt = rect.width(); //列表视图总宽度,可通过增加对话框大小扩大(此程序)
int w[5] = {0}; //各列数据的宽度

w[0] = wt / 5, w[1] = wt / 5, w[2] = wt / 5, w[3] = wt / 5, w[4] = wt / 5;

//将里面的五个列标题插入列表
for(int i = 0; i < 5; i++)
{
	lvCol.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH | LVCF_ORDER;
	lvCol.fmt = LVCFMT_LEFT;
	lvCol.pszText = (LPWSTR)listName[i];
	lvCol.iSubItem = i;
	lvCol.iOrder = i;
	lvCol.cx = w[i];
	m_ListCtrl.InsertColumn(i, &lvCol);
}

m_ListCtrl.SetBKColor(RGB(223,223,223));
m_ListCtrl.SetTextBKColor(RGB(255,255,255)); //红色
m_ListCtrl.SetTextColor(RGB(0,0,0));
  • 添加信息:

    双击添加按钮,添加消息响应函数,然后里面就写上添加逻辑。

UpdateData();

int count = m_ListCtrl.GetItemCount();  //初始计数,防止删除之后,序号错乱,导致信息添加不完整
TCHAR rgtsz[5][256];

_stprintf(rgtsz[0], _T("%s"),m_strID.GetString());
_stprintf(rgtsz[1], _T("%s"),m_strSuperMarket.GetString());
_stprintf(rgtsz[2], _T("%s"),m_strCurPos.GetString());
_stprintf(rgtsz[3], _T("%s"),m_strBestPos.GetString());
_stprintf(rgtsz[4], _T("%d"),m_nPeakScore);

int bRet = MySetItem(rgtsz[0],rgtsz[1],rgtsz[2],rgtsz[3],rgtsz[4],count);
if (bRet == -1)
{
	MessageBox(_T("ID为NULL,请检查!",_T("Tencent"),MB_ICONINFORMATION);
	return;
}
else if (bRet == -2)
{
	MessageBox(_T("所在大区为NULL,请检查!",_T("Tencent"),MB_ICONINFORMATION);
	return;
}
else if (bRet == -3)
{
	MessageBox(_T("当前段位为NULL,请检查!",_T("Tencent"),MB_ICONINFORMATION);
	return;
}
else if (bRet == -4)
{
	MessageBox(_T("最高段位为NULL,请检查!",_T("Tencent"),MB_ICONINFORMATION);
	return;
}
else if (bRet == -5)
{
	MessageBox(_T("巅峰积分为NULL,请检查!",_T("Tencent"),MB_ICONINFORMATION);
	return;
}

count++;  //计数++

UpdateData(FALSE);

插入函数MySetItem如下:

if(*tchar1 == NULL)
{
	return -1;
}
else if(*tchar2 == NULL)
{
	return -2;
}
else if(*tchar3 == NULL)
{
	return -3;
}
else if(*tchar4 == NULL)
{
	return -4;
}
else if(*tchar5 == NULL)
{
	return -5;
}

//Col、tchar1~tchar5均为传递的参数
m_ListCtrl.InsertItem(Col, tchar1);
m_ListCtrl.SetItemText(Col, 1 , tchar2);
m_ListCtrl.SetItemText(Col, 2 , tchar3);
m_ListCtrl.SetItemText(Col, 3 , tchar4);
m_ListCtrl.SetItemText(Col, 4 , tchar5);

return TRUE;
  • 删除一项/删除全部:

按钮都是同样的方法添加消息响应。

UpdateData();
//删除一项,这里提供两种方法
#if 0
	BOOL state = FALSE;

	int len = m_ListCtrl.GetItemCount();
	for(int i = 0; i < len; i++)
	{
		state = m_ListCtrl.GetCheck(i);
		if(state == TRUE)
		{
			m_ListCtrl.DeleteItem(i);
		}
	}
#else
	int nCurSelIndex = GetCurSel();
	m_ListCtrl.DeleteItem(nCurSelIndex);
#endif

UpdateData(FALSE);
//删除全部
UpdateData();
m_ListCtrl.DeleteAllItems();
UpdateData(FALSE)
  • 反选与全选:

在这里插入图片描述
这里两个消息响应函数都是同样的添加方法,代码如下:

//反选
UpdateData();
BOOL state = FALSE;
int len = m_ListCtrl.GetItemCount();

for(int i = 0; i < len; i++)
{
	state = m_ListCtrl.GetCheck(i); //得到选中项的状态
	if(state == FALSE)
	{
		m_ListCtrl.SetItemState(i , LVIS_SELECTED,LVIS_SELECTED);
		m_ListCtrl.SetCheck(i , TRUE);
	}
	else
	{
		m_ListCtrl.SetItemState(i, ~LVIS_SELECTED,LVIS_SELECTED);
		m_ListCtrl.SetCheck(i , FALSE);
	}
}

UpdateData(FALSE);
//全选
UpdateData();
int len = m_ListCtrl.GetItemCount(); //获得当前项数

for(int i = 0; i < len; i++)
{
	m_ListCtrl.SetCheck(i , TRUE);
	m_ListCtrl.SetItemState(i , LVIS_SELECTED, LVIS_SELECTED);
}

UpdateData(FALSE);
  • 选中点与得到点:

在这里插入图片描述
按照图中所示添加双击函数,然后手动添加一个函数,删除中方法二也用到了。

//得到点
POSITION pos = m_ListCtrl.GetFirstSelectedItemPosition();
if(pos == NULL)
{
	return -1;
}
else
{
	int nSelIndex = m_ListCtrl.GetNextSelectedItem(pos);
	return nSelIndex;
}
//选中点
int nCurSelIndex = GetCurSel();
if( -1 == nCurSelIndex)
{
	MessageBox(_T("未选中数据!"),_T("Tencent"),MB_ICONINFORMATION);
	return;
}

MessageBox(_T("编辑功能有待完善,请等待版本更新!")_T("Tencent"),MB_ICONINFORMATION);

04、说明与版权

关于巅峰查询器的版本更新问题,博主这里有时间就继续写,工作之余做一款软件出来,虽然功能不一定很强,但是主要是练手与熟悉各种技术为重,先发布一下V1.0版本源码吧,至于源码下载,等软件做出来之后,我会发布到github上,到时候需要请大家自行下载。

版权声明:转载请注明出处,谢谢!

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cain Xcy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值