虚拟CMFCListCtrl滚动条闪烁问题技术求助
嘿,针对你用MFC虚拟列表控件(LVS_OWNERDATA)需要每秒刷新数据的需求,结合你给出的初始化代码,我给你一套实用的解决方案:
实现虚拟列表每秒自动刷新的核心方案
首先得明确:虚拟列表不会缓存所有数据,它只在需要显示时通过LVN_GETDISPINFO消息向你请求当前可见行的内容。所以咱们的刷新逻辑不是硬更每一行,而是通知控件数据源已更新,让它重新请求数据,同时尽量避免全屏闪烁。
1. 加个定时器触发每秒刷新
首先在你的CMyListCtrl类里加个1秒的定时器,用来定时更新数据源并通知列表:
- 在
Init函数末尾补上定时器初始化(记得修正你代码里的InsertColum笔误,应该是InsertColumn):
bool CMyListCtrl::Init(CWnd* pParent) { CRect rectDummy; if(!Create(WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_OWNERDATA, rectDummy, pParent, IDC_LIST1)) return false; #define LVS_EX_DOUBLEBUFFER 0x00010000 SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_DOUBLEBUFFER); InsertColumn(0,_T("#"),LVCFMT_LEFT, 20,1); // 这里继续添加你的其他列... // 设置1秒(1000毫秒)定时器,ID用1001就行,自定义也可以 SetTimer(1001, 1000, nullptr); return true; }
- 然后给类加上定时器消息处理(别忘了在消息映射里加
ON_WM_TIMER()):
void CMyListCtrl::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == 1001) { // 第一步:更新你的数据源(比如从接口拉取新数据、本地计算更新) UpdateMyDataSource(); // 这个函数需要你自己实现,更新背后的数据集合 // 第二步:如果总行数变了,先通知控件更新总行数 int newItemCount = GetUpdatedTotalItemCount(); // 替换成你实际的总行数 SetItemCount(newItemCount); // 第三步:只刷新可见区域,避免全屏闪烁 int topIndex = GetTopIndex(); int visibleCount = GetCountPerPage(); RedrawItems(topIndex, topIndex + visibleCount - 1); } CListCtrl::OnTimer(nIDEvent); }
2. 优化LVN_GETDISPINFO确保取最新数据
虚拟列表显示内容全靠这个消息,一定要确保它能拿到最新的数据源:
void CMyListCtrl::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult) { NMLVDISPINFO* pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR); LVITEM* pItem = &pDispInfo->item; if (pItem->mask & LVIF_TEXT) { // 从你刚更新的数据源里,取对应行和列的文本 CString cellText = GetCellDataFromSource(pItem->iItem, pItem->iSubItem); // 你的数据源读取逻辑 _tcscpy_s(pItem->pszText, pItem->cchTextMax, cellText); } *pResult = 0; }
3. 别忘了清理定时器
窗口销毁时记得关掉定时器,避免内存泄漏:
void CMyListCtrl::OnDestroy() { KillTimer(1001); CListCtrl::OnDestroy(); }
额外的闪烁优化
你已经设置了LVS_EX_DOUBLEBUFFER,这很好,再加上只刷新可见行的操作,基本就能避免明显闪烁了。如果还是有问题,可以试试在刷新前禁用控件重绘,刷新后再启用:
// 在RedrawItems前后加: SetRedraw(FALSE); RedrawItems(topIndex, topIndex + visibleCount - 1); SetRedraw(TRUE);
这样一套操作下来,你的虚拟列表就能每秒自动拉取/更新数据,同时保持流畅不卡顿~
内容的提问来源于stack exchange,提问作者user9444860
相关产品推荐
相关产品推荐

