MFC List Control虚拟列表

一:拖动添加list control控件, 资源IDC_MY_LIST,在.rc文件添加属性LVS_OWNERDATA

 CONTROL         "",IDC_MY_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDATA | LVS_ALIGNLEFT | WS_TABSTOP,7,74,443,292,WS_EX_CLIENTEDGE

二:将控件IDC_MY_LIST绑定成员变量

//XXXDlg.cpp DoDataExchange(CDataExchange* pDX)函数内添加
DDX_Control(pDX, IDC_MY_LIST, m_myList);
//XXXDlg.h 添加成员变量m_myList
CListCtrl m_myList;

三:创建行列数据成员变量

//XXXDlg.h 添加成员变量m_dateList
std::vector<std::vector<CString>> m_dataList;

四:添加LVN_GETDISPINFO的消息响应函数

//XXXDlg.h
afx_msg void OnMyListInfo(NMHDR *pNMHDR, LRESULT *pResult);
//------------------------------------------------------------------------------------

//XXXDlg.cpp
BEGIN_MESSAGE_MAP(XXXDlg, CDialogEx)
    .......
	ON_NOTIFY(LVN_GETDISPINFO, IDC_MY_LIST, OnMyListInfo)
END_MESSAGE_MAP()

void XXXDlg::OnMyListInfo(NMHDR *pNMHDR, LRESULT *pResult)
{
	NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
	// TODO: 刷新结果虚拟列表的显示
	LV_ITEM* pItem = &(pDispInfo)->item;
	int nItem = pItem->iItem;
	if (nItem < 0 || nItem >= m_dateList.size())
	{
		return;
	}
	if (pItem->mask & LVIF_TEXT)
	{
		int nSubItem = pItem->iSubItem;
		_tcscpy(pItem->pszText, m_dataList[nItem][nSubItem]);
	}
	*pResult = 0;
}

五:初始化列表插入表头

void XXXDlg::Init()
{
	//初始化日志list
	LONG lStyle;
	lStyle = GetWindowLong(m_myList.m_hWnd, GWL_STYLE);         //获取当前窗口style
	lStyle &= ~LVS_TYPEMASK;                                     //清除显示方式位
	lStyle |= LVS_REPORT;                                        //设置style
	SetWindowLong(m_myList.m_hWnd, GWL_STYLE, lStyle);          //设置style
	DWORD dwStyle = m_myList.GetExtendedStyle();
	dwStyle |= LVS_EX_FULLROWSELECT;                             //选中某行使整行高亮(只适用与report风格的listctrl)
	dwStyle |= LVS_EX_GRIDLINES;                                 //网格线(只适用与report风格的listctrl)
	m_myList.SetExtendedStyle(dwStyle);                         //设置扩展风格
	m_myList.InsertColumn(0, _T("序号"), LVCFMT_LEFT, 100);
	m_myList.InsertColumn(1, _T("姓名"), LVCFMT_LEFT, 140);
	m_myList.InsertColumn(2, _T("年龄"), LVCFMT_LEFT, 140);
	m_myList.InsertColumn(3, _T("地址"), LVCFMT_LEFT, 300);
}

六:插入数据,触发显示

//插入数据
std::vector<CString>  vecTempDatda;
size_t nCount = m_dateList.size();
vecTempDatda.(std::to_string(++nCount).c_str());
vecTempDatda.push_back(_T("张三"));
vecTempDatda.push_back(std::to_string(21).c_str());
vecTempDatda.push_back(_T("北京"));
m_dataList.push_back(vecTempDatda);

//在m_dateList中push_back数据后
m_myList.SetItemCountEx(m_dataList.size(), LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
m_myList.Invalidate();

七:实现点击“姓名”表头按姓名排序,姓名相同再按年龄排序

//XXXDlg.h
afx_msg void OnColumnClickOrder(NMHDR* pNMHDR, LRESULT* pResult);

//XXXDlg.cpp
BEGIN_MESSAGE_MAP(XXXDlg, CDialogEx)
	ON_NOTIFY(LVN_COLUMNCLICK, IDC_MY_LIST, OnColumnClickOrder)          // 委托列表单击表头排序
END_MESSAGE_MAP()

void XXXDlg::OnColumnClickOrder(NMHDR* pNMHDR, LRESULT* pResult)
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	switch (pNMListView->iSubItem)
	{
	case 1: //姓名
	{
		std::sort(m_dataList.begin(), m_dataList.end(), [](std::vector<CString> &first, std::vector<CString> &seconde) 
		{
			return first[1] == seconde[1]? std::atoi(first[2]) > std::atoi(seconde[2]):first[1]<seconde[1];
		});
		m_myList.SetItemCountEx(m_dataList.size(), LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
		m_myList.Invalidate();
	}
	break;
	default:
		break;
	}
	if (pResult != NULL)
	{
		*pResult = 0;
	}
}

八:调整列表高度

	// 设置行高(关联空白图片)
	CImageList imageList;  
	imageList.Create(1, GetDPIValue(22), ILC_COLOR32, 1, 0);  
	SetImageList(&imageList, LVSIL_SMALL);

九:如何设置定时器时,会出现闪烁

在初始化m_myList属性时,增加LVS_EX_DOUBLEBUFFER属性

十:自绘单元的颜色字体等

//XXXDlg.h
afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
//------------------------------------------------------------------------------------

//XXXDlg.cpp
BEGIN_MESSAGE_MAP(XXXDlg, CDialogEx)
    .......
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_MY_LIST, OnNMCustomdraw)
END_MESSAGE_MAP()

void XXXDlg::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
{
    *pResult               = CDRF_DODEFAULT;
    NMLVCUSTOMDRAW* lplvdr = (NMLVCUSTOMDRAW*)pNMHDR;
    switch (lplvdr->nmcd.dwDrawStage)
    {
    case CDDS_PREPAINT: {
        //设置自定义绘制
        *pResult = CDRF_NOTIFYITEMDRAW;
    }
    break;
    case CDDS_ITEMPREPAINT:
    {
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
        break;
    } 
    case CDDS_ITEMPREPAINT | CDDS_SUBITEM: {
        //绘制item
        DrawSubItem(lplvdr, pResult);
        *pResult = CDRF_DODEFAULT;
    }
    break;
    default:
        break;
    }
}
void XXXDlg::DrawSubItem(NMHDR* pNMHDR, LRESULT* pResult)
{
	/*
	long     iRow         = lplvcd->nmcd.dwItemSpec;
    long     iCol         = lplvcd->iSubItem;
    CDC*     pDC          = CDC::FromHandle(lplvcd->nmcd.hdc);
    CRect    rect;
    rect            = lplvcd->nmcd.rc;

	COLORREF cBlack    = RGB(0, 0, 0);
    COLORREF cwhite    = RGB(255, 255, 255);
    COLORREF COLOR_SEL = RGB(0, 0, 255); // 背景色(选中行)

    lplvcd->clrText = cBlack;
    lplvcd->clrTextBk = cwhite;
    if (GetItemState(iRow, CDIS_SELECTED))
    {
        lplvcd->nmcd.uItemState ^= CDIS_SELECTED;
        lplvcd->clrTextBk = COLOR_SEL;
    }
    if (iCol == 0)
    {
        rect.left = 0;
        pDC->FillSolidRect(rect, lplvcd->clrTextBk);
    }
    */
}

你可能感兴趣的:(c++,MFC,list,mfc,数据结构)