You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MFC CListCtrl转虚拟列表时OnGetdispinfoList调用传参问题如何解决

问题核心原因

OnGetdispinfoList是虚拟列表LVN_GETDISPINFO通知的系统回调函数,不需要你手动调用,该函数的参数是系统自动填充的,包含了当前需要渲染的行号、列号等信息,你手动传入nullptr必然会导致访问空指针崩溃。

正确的虚拟列表配置步骤

你只需要按以下流程配置即可,直接删除手动调用OnGetdispinfoList的代码:

  1. 给CListCtrl控件开启虚拟列表必须的LVS_OWNERDATA风格,建议在对话框OnInitDialog方法中添加:
// 假设你的列表控件关联变量名为m_ListCtrl
m_ListCtrl.ModifyStyle(0, LVS_REPORT | LVS_OWNERDATA);
// 可选:添加网格线、整行选中扩展风格
m_ListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
  1. 给虚拟列表设置总数据行数,你的数据存储在Spiele容器中,直接传入容器大小即可:
// 如果是静态数组就传数组长度,如果是vector就传Spiele.size()
m_ListCtrl.SetItemCount(Spiele.size());
  1. 确保消息映射绑定正确,检查你的对话框消息映射代码中存在如下条目,替换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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 11:24:07