关于MFC的使用总结之七——复现CGridListCtrlEx绘制表格

MFC的使用总结之七——复现CGridListCtrlEx绘制表格

写在前面

MFC是一种用c++设计交互界面的的开发工具,在二三十年前比较流行,但目前比较少用了。所以现在使用MFC进行开发,相关资料的查找也比较困难。最近做了一个与MFC有关的项目,其中用到的相关知识总结于此。在使用工具时,最好的资料其实就是那个库本身,查看库内的代码总会有意想不到的收获。本人用的是VS2017专业版里面的MFC。本章主要是复现老外使用CGridListCtrlEx绘制表格。老外的链接如下:
CGridListCtrlEx,文末附老外和个人代码地址。

示例展示

上面网址上有两个下载地址,里面的例子都是可以用的,这里只展示一个例子,运行界面,有图表,日期,checkbox还有超链接。
在这里插入图片描述
如果能够连接维基百科,点击超链接是可以打开的
在这里插入图片描述
表格还可以进行排序,拖动等操作。
在这里插入图片描述

复现CGridListCtrlEx

文件导入

新建项目的过程请参照总结一,现在项目已经创建好了
在这里插入图片描述
首先将cgridlistctrlex_demo里面的CGridListCtrlEx文件夹全体复制到创建的.sln目录中
在这里插入图片描述
将CListCtrl_DataModel.h复制到.h和.cpp的那个目录下。
在项目的属性页中将CGridListCtrlEx文件里面的文件和CListCtrl_DataModel.h部添加到项目中
在这里插入图片描述
将原文夹res中的国旗图标复制到现在的res中
在这里插入图片描述
在资源视图的Icon添加这些资源,选中Icon,选择导入,可以更具需求更不更改名称都行
在这里插入图片描述

新建控件

从工具箱中拖入List Control
在这里插入图片描述
查看器属性页,一定要将View选项选成Report,个人因为这个原因复现好久都一直报错。
在这里插入图片描述
之后得到的界面就变成下面这个样子了
在这里插入图片描述

添加代码

在GridlistDlg.h中添加头文件

#include "afxcmn.h"

#include "..\CGridListCtrlEx\CGridListCtrlGroups.h"
#include "CListCtrl_DataModel.h"

添加定义

private:
	CGridListCtrlGroups m_ListCtrl;
	CListCtrl_DataModel m_DataModel;
	CImageList m_ImageList;

	CGridlistDlg(const CGridlistDlg&);
	CGridlistDlg& operator=(const CGridlistDlg&);

在GridlistDlg.cpp中添加头文件

#include "..\CGridListCtrlEx\CGridColumnTraitDateTime.h"
#include "..\CGridListCtrlEx\CGridColumnTraitEdit.h"
#include "..\CGridListCtrlEx\CGridColumnTraitCombo.h"
#include "..\CGridListCtrlEx\CGridColumnTraitHyperLink.h"
#include "..\CGridListCtrlEx\CGridRowTraitXP.h"
#include "..\CGridListCtrlEx\ViewConfigSection.h"

在void CGridlistDlg::DoDataExchange(CDataExchange* pDX)添加绑定

void CGridlistDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_ListCtrl);
}

在BOOL CGridlistDlg::OnInitDialog()添加代码区添加片段

	// Create and attach image list
	m_ImageList.Create(16, 16, ILC_COLOR16 | ILC_MASK, 1, 0);
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));
	int nStateImageIdx = CGridColumnTraitDateTime::AppendStateImages(m_ListCtrl, m_ImageList);	// Add checkboxes

	m_ListCtrl.SetImageList(&m_ImageList, LVSIL_SMALL);

	// Give better margin to editors
	m_ListCtrl.SetCellMargin(1.2);
	CGridRowTraitXP* pRowTrait = new CGridRowTraitXP;
	m_ListCtrl.SetDefaultRowTrait(pRowTrait);
	m_ListCtrl.EnableVisualStyles(true);

	// Create Columns
	m_ListCtrl.InsertHiddenLabelColumn();	// Requires one never uses column 0

	for (int col = 0; col < m_DataModel.GetColCount(); ++col)
	{
		const CString& title = m_DataModel.GetColTitle(col);
		CGridColumnTrait* pTrait = NULL;
		if (col == 0)	// Country
		{
			CGridColumnTraitCombo* pComboTrait = new CGridColumnTraitCombo;
			const vector<CString>& countries = m_DataModel.GetCountries();
			for (size_t i = 0; i < countries.size(); ++i)
				pComboTrait->AddItem((DWORD_PTR)i, countries[i]);
			pTrait = pComboTrait;
		}
		if (col == 1)	// City
		{
			pTrait = new CGridColumnTraitEdit;
		}
		if (col == 2)	// Year won
		{
			CGridColumnTraitDateTime* pDateTimeTrait = new CGridColumnTraitDateTime;
			pDateTimeTrait->AddImageIndex(nStateImageIdx, _T(""), false);		// Unchecked (and not editable)
			pDateTimeTrait->AddImageIndex(nStateImageIdx + 1, COleDateTime(1970, 1, 1, 0, 0, 0).Format(), true);	// Checked (and editable)
			pDateTimeTrait->SetToggleSelection(true);
			pTrait = pDateTimeTrait;
		}
		if (col == 3)	// Year won
		{
			CGridColumnTraitHyperLink* pHyperLinkTrait = new CGridColumnTraitHyperLink;
			pHyperLinkTrait->SetShellFilePrefix(_T("http://en.wikipedia.org/wiki/UEFA_Euro_"));
			pTrait = pHyperLinkTrait;
		}

		m_ListCtrl.InsertColumnTrait(col + 1, title, LVCFMT_LEFT, 100, col, pTrait);
	}

	// Insert data into list-control by copying from datamodel
	int nItem = 0;
	for (size_t rowId = 0; rowId < m_DataModel.GetRowIds(); ++rowId)
	{
		nItem = m_ListCtrl.InsertItem(++nItem, m_DataModel.GetCellText(rowId, 0));
		m_ListCtrl.SetItemData(nItem, rowId);
		for (int col = 0; col < m_DataModel.GetColCount(); ++col)
		{
			int nCellCol = col + 1;	// +1 because of hidden column
			const CString& strCellText = m_DataModel.GetCellText(rowId, col);
			m_ListCtrl.SetItemText(nItem, nCellCol, strCellText);
			if (nCellCol == 3)
			{
				if (strCellText == _T(""))
					m_ListCtrl.SetCellImage(nItem, nCellCol, nStateImageIdx);	// unchecked
				else
					m_ListCtrl.SetCellImage(nItem, nCellCol, nStateImageIdx + 1);	// checked
			}
		}
		m_ListCtrl.SetCellImage(nItem, 1, nItem); // Assign flag-images
	}

	CViewConfigSectionWinApp* pColumnProfile = new CViewConfigSectionWinApp(_T("Sample List"));
	pColumnProfile->AddProfile(_T("Default"));
	pColumnProfile->AddProfile(_T("Special"));
	m_ListCtrl.SetupColumnConfig(pColumnProfile);

之前要是有比较认真的小伙伴把那个ICON的名字该成和原代码一样的,请用如下代码替换对应部分

	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_FLGDEN));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_FLGGERM));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_FLGFRAN));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_FLGGREEC));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_FLGSWED));
	m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_FLGSPAIN));

至此,整个项目好像都复制过来了,试着运行一下应该没问题,结果发现好多错。
在这里插入图片描述
还有最后一个很重要的地方就是预编译器(stdafx.h)里面还需要引入头文件。这种使用预编译器的项目,这个也是一个大坑,至于要在其中加入下面几行代码就没错了

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

运行结果

各种功能基本都实现了,但还是有一个小遗憾,表格中上下之间不能拖动交换顺序,而原代码中是可以的,个人找了好久,未果,但没有寻病终(哈哈哈!),在此,寻好心人求解。
在这里插入图片描述
老外代码链接.
个人代码链接.

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值