当使用ListCtrl显示大量数据或频繁进行显示时,传统的显示方法不仅显示速度慢,而且会出现闪烁的问题,为了提高数据的时效性,选择使用了虚拟列表。

首先,设置Listctrl控件属性,将OwnerData属性修改为TRUE;然后为控件关联一个变量m_List。

初始化

CRect rect;

int Total_num=4;

m_List.ModifyStyle(WS_VSCROLL,0,0);

m_List.GetClientRect(&rect); // 获取编程语言列表视图控件的位置和大小

// 为列表视图控件添加全行选中和栅格风格

m_List.InsertColumn(0, _T("信号"), LVCFMT_CENTER, 2*rect.Width()/Total_num, 0);

m_List.InsertColumn(1, _T("数值"), LVCFMT_CENTER, 1*rect.Width()/Total_num, 1);

m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT |LVS_EX_DOUBLEBUFFER| LVS_EX_GRIDLINES | LVS_EX_LABELTIP|LVIS_SELECTED|LVIS_FOCUSED);

添加LVN_GETDISPINFO消息,编辑OnLvnGetdispinfoList消息,将要显示的信息(行信息)放置于数组coloum1Text、coloum2Text中。

void CXXXDlg::OnLvnGetdispinfoList(NMHDR *pNMHDR, LRESULT *pResult)

{

// TODO: 在此添加控件通知处理程序代码

*pResult = 0;

LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

LV_ITEM* pItem= &(pDispInfo)->item;

int iItemIndx= pItem->iItem;//获取行号,会自动根据当前显示区的行数,更新所有的行

if (pItem->mask & LVIF_TEXT) //字符串缓冲区有效

{

// then display the appropriate column

switch(pItem->iSubItem)

{

case 0:

lstrcpy(pItem->pszText, coloum1Text[iItemIndx]);//将要显示的行信息放置于数组中

break;

case 1:

lstrcpy(pItem->pszText, coloum2Text[iItemIndx]);

break;

default:

ASSERT(0);

break;

}

}

}

开一个定时器,周期根据自己情况定,100ms以上就可以,太短了人眼反应过不来。在定时器中调用下面的代码

m_List.SetItemCountEx(1000);//需要显示多少行就填多少,如果不是固定值,那需要一个变量进行控制

m_List.Invalidate();

m_List.UpdateWindow();

要显示的信息填充到上面的数组中,就可以正常显示了,而且效率比较高。

当你按照这些做下来,可能会发现一个问题,Listctrl控件刷新时会闪烁,不用尝试网上说的那些设置RedrawItems或其他的,基本都试过,不好用。

解决方法是:在初始化ListCtrl属性时,增加LVS_EX_DOUBLEBUFFER属性。加上之后,数据更新特别平滑,不会跳动。

如果想改变ListCtrl中单元格的颜色,需要增加NM_CUSTOMDRAW消息,如下图所示。

void CXXXDlg::OnNMCustomdrawDbcListShow(NMHDR *pNMHDR, LRESULT *pResult)

{

NMLVCUSTOMDRAW* pLVCD = reinterpret_cast(pNMHDR);

*pResult = 0;

if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )

{

*pResult = CDRF_NOTIFYITEMDRAW;

}

else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )

{

*pResult = CDRF_NOTIFYSUBITEMDRAW;

}

else if ( (CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage )

{

COLORREF m_clrTextBk;

COLORREF m_clrText;

int nItem = static_cast(pLVCD->nmcd.dwItemSpec);

m_clrTextBk = WHITE;

m_clrText = BLACK;

//这里改变颜色,可增加限制条件

pLVCD->clrTextBk = m_clrTextBk;

pLVCD->clrText = m_clrText;

*pResult = CDRF_DODEFAULT;

}

}

别急,还有内容,今天才注意到ListCtrl的第一列是左对齐的,无论如何修改初始化时的属性,都是左对齐,解决方法是在初始化之后增加下面的代码:

LVCOLUMN lvc;

lvc.mask = LVCF_FMT;

m_List.GetColumn(0, &lvc);

lvc.fmt &= ~LVCFMT_JUSTIFYMASK;

lvc.fmt |= LVCFMT_CENTER;

m_List.SetColumn(0, &lvc);

最后,ListCtrl向下滚动有下面几种方法

1.

m_list_Infor.PostMessage(WM_VSCROLL, SB_BOTTOM, NULL);

2.

m_list_Infor.SendMessage(WM_VSCROLL, SB_BOTTOM, NULL);

3.

m_list_Infor.EnsureVisible(m_list_Infor.GetItemCount()-1,FALSE);

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐