MFC CListCtrl转虚拟列表时OnGetdispinfoList调用传参问题如何解决
问题核心原因
OnGetdispinfoList是虚拟列表LVN_GETDISPINFO通知的系统回调函数,不需要你手动调用,该函数的参数是系统自动填充的,包含了当前需要渲染的行号、列号等信息,你手动传入nullptr必然会导致访问空指针崩溃。
正确的虚拟列表配置步骤
你只需要按以下流程配置即可,直接删除手动调用OnGetdispinfoList的代码:
- 给CListCtrl控件开启虚拟列表必须的
LVS_OWNERDATA风格,建议在对话框OnInitDialog方法中添加:
// 假设你的列表控件关联变量名为m_ListCtrl m_ListCtrl.ModifyStyle(0, LVS_REPORT | LVS_OWNERDATA); // 可选:添加网格线、整行选中扩展风格 m_ListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
- 给虚拟列表设置总数据行数,你的数据存储在
Spiele容器中,直接传入容器大小即可:
// 如果是静态数组就传数组长度,如果是vector就传Spiele.size() m_ListCtrl.SetItemCount(Spiele.size());
- 确保消息映射绑定正确,检查你的对话框消息映射代码中存在如下条目,替换
IDC_YOUR_LIST_ID为你实际的列表控件ID:
ON_NOTIFY(LVN_GETDISPINFO, IDC_YOUR_LIST_ID, &CSpielebibliothekGUIDlg::OnGetdispinfoList)
现有代码优化建议
你现有OnGetdispinfoList函数中存在一行无用代码,可以直接删除,避免潜在的类型转换问题:
// 无用代码,可删除 LPNMITEMACTIVATE pNMIA = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
手动刷新列表的方法
如果你修改了Spiele中的数据需要刷新列表显示,不要调用OnGetdispinfoList,而是调用列表控件的刷新方法:
- 刷新全部列表:
m_ListCtrl.Invalidate(); - 刷新指定行范围:
m_ListCtrl.RedrawItems(起始行号, 结束行号);
调用后系统会自动触发LVN_GETDISPINFO通知,自动调用你的回调函数获取最新数据渲染。
内容的提问来源于stack exchange,提问作者Miyutic
相关产品推荐
相关产品推荐

