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

C++ ListView单条数据重复显示求助:如何循环加载std::vector数据

问题描述

我有6条公司数据需要显示在ListView控件中,手动添加列和子项的代码可正常运行:

添加列的代码:

LvCol.pszText = header1; //wchar_t header
LvCol.cx = 0x80;
LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
SendMessage(ListCompanyInfoTable, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);

添加子项的代码:

item.iSubItem = 0;
SendMessageW(ListCompanyInfoTable, LVM_INSERTITEM, 0, (LPARAM)&item);
item.mask = LVIF_TEXT;
item.pszText = col1;
item.cchTextMax = wcslen(item.pszText);
SendMessageW(ListCompanyInfoTable, LVM_SETITEM, 0, (LPARAM)&item);

现在希望通过循环遍历存储公司数据的std::vector优化代码,但遇到问题:首次编写的循环代码中,第一行数据正常显示,后续行均重复第一行内容;修改后,iSubItem能正确读取所有项,但始终无法将下一家公司数据添加到下一行,重复显示第一家公司的数据。

补充相关代码:

数据定义与填充

std::vector<LPWSTR> Columns;
std::vector<LPWSTR> TableData;
std::vector<Company> companiesInGame;

Company company1(L"American Gas Co", L"1930", L"ACG", 2000000, 500000);
Company company2(L"TruGrocers", L"1940", L"TRG", 1525000, 300000);
Company company3(L"Northern Airlines", L"1929", L"NAR", 1500000, 220000);
Company company4(L"Jackson Estates", L"1938", L"JAE", 1970000, 255000);
Company company5(L"High Point Hotels", L"1920", L"HPH", 970000, 250000);
Company company6(L"Chucker's Truckers", L"1940", L"CHT", 600000, 100000);

companiesInGame.push_back(company1);
companiesInGame.push_back(company2);
companiesInGame.push_back(company3);
companiesInGame.push_back(company4);
companiesInGame.push_back(company5);
companiesInGame.push_back(company6);

for (int i = 0; i < companiesInGame.size(); i++)
{
    TableData.push_back(companiesInGame[i].CompanyNameBuffer);
    TableData.push_back(companiesInGame[i].CompanyCodeBuffer);
    TableData.push_back(companiesInGame[i].YearEstablishedBuffer);
    TableData.push_back(companiesInGame[i].TotalNetWorthBuffer);
    TableData.push_back(companiesInGame[i].TotalSharesBuffer);
    TableData.push_back(companiesInGame[i].PricePerShareBuffer);
}

Company类构造函数

Company::Company(std::wstring CompanyName, std::wstring YearEstablished, std::wstring CompanyCode, double TotalNetWorth, int TotalShares)
{
    this->companyName = CompanyName;
    this->yearEstablished = YearEstablished;

    this->iCompanyNetWorth = TotalNetWorth;
    this->iTotalShares = TotalShares;

    //Format character arrays for Printing
    CompanyName.copy(CompanyNameBuffer, 100);
    YearEstablished.copy(YearEstablishedBuffer, 100);
    CompanyCode.copy(CompanyCodeBuffer, 100);
    SetStockInfo();

    size_t CompanyNameBufferLength = CompanyName.length();
    CompanyNameBuffer[CompanyNameBufferLength] = '\0';

    size_t YearEstablishedBufferLength = YearEstablished.length();
    YearEstablishedBuffer[YearEstablishedBufferLength] = '\0';

    size_t CompanyCodeBufferLength = CompanyCode.length();
    CompanyCodeBuffer[CompanyCodeBufferLength] = '\0';

    //Convert integer values to string for Printing
    swprintf_s(TotalNetWorthBuffer, 20, L"$ %lf", TotalNetWorth);
    swprintf_s(TotalSharesBuffer, 20, L"%d", TotalShares);
    swprintf_s(PricePerShareBuffer, 20, L"$ %.2lf", this->iPricePerShare);
}
修复方案

核心问题分析

  1. LVM_INSERTITEM参数错误:原代码中每次调用SendMessageW插入行时,第二个参数传了0,这会把所有新行都插入到索引0的位置,导致后续行覆盖前一行,最终所有数据都显示在第一行。正确做法是传入当前行索引x,或者传-1让控件自动追加到末尾。
  2. TableData索引计算错误:原循环中直接用y获取TableData[y],只会拿到第一家公司的列数据。需要用x * numColumns + y来定位当前行对应的列数据。
  3. 内层循环范围错误:原代码中内层循环遍历总单元格数numTableCells,这会导致单行道重复设置所有单元格数据,应该只遍历单行道的列数numColumns。

修复后的循环代码

size_t numColumns = Columns.size();
size_t numRows = companiesInGame.size();

LVITEM tableCell = { 0 };
memset(&tableCell, 0, sizeof(tableCell));
tableCell.mask = LVIF_TEXT; // 提前设置mask,避免重复赋值

for (int x = 0; x < numRows; x++)
{
    // 插入新行,第二个参数传x指定行索引,或者传-1自动追加
    tableCell.iItem = x;
    tableCell.iSubItem = 0;
    // 设置第一列的文本(对应CompanyName)
    tableCell.pszText = TableData[x * numColumns + 0];
    tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
    SendMessageW(ListCompanyInfoTable, LVM_INSERTITEM, x, (LPARAM)&tableCell);

    // 设置当前行的剩余列
    for (int y = 1; y < numColumns; y++)
    {
        tableCell.iSubItem = y;
        tableCell.pszText = TableData[x * numColumns + y];
        tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
        // LVM_SETITEM的第二个参数传x指定要修改的行
        SendMessageW(ListCompanyInfoTable, LVM_SETITEM, x, (LPARAM)&tableCell);
    }
}

进一步优化建议

可以跳过TableData这个中间载体,直接遍历companiesInGame取数据,避免索引计算错误,代码更直观:

size_t numColumns = Columns.size();
size_t numRows = companiesInGame.size();

LVITEM tableCell = { 0 };
memset(&tableCell, 0, sizeof(tableCell));
tableCell.mask = LVIF_TEXT;

for (int x = 0; x < numRows; x++)
{
    Company& currCompany = companiesInGame[x];
    tableCell.iItem = x;
    
    // 插入行并设置第一列
    tableCell.iSubItem = 0;
    tableCell.pszText = currCompany.CompanyNameBuffer;
    tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
    SendMessageW(ListCompanyInfoTable, LVM_INSERTITEM, x, (LPARAM)&tableCell);

    // 设置剩余列
    tableCell.iSubItem = 1;
    tableCell.pszText = currCompany.CompanyCodeBuffer;
    tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
    SendMessageW(ListCompanyInfoTable, LVM_SETITEM, x, (LPARAM)&tableCell);

    tableCell.iSubItem = 2;
    tableCell.pszText = currCompany.YearEstablishedBuffer;
    tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
    SendMessageW(ListCompanyInfoTable, LVM_SETITEM, x, (LPARAM)&tableCell);

    tableCell.iSubItem = 3;
    tableCell.pszText = currCompany.TotalNetWorthBuffer;
    tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
    SendMessageW(ListCompanyInfoTable, LVM_SETITEM, x, (LPARAM)&tableCell);

    tableCell.iSubItem = 4;
    tableCell.pszText = currCompany.TotalSharesBuffer;
    tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
    SendMessageW(ListCompanyInfoTable, LVM_SETITEM, x, (LPARAM)&tableCell);

    tableCell.iSubItem = 5;
    tableCell.pszText = currCompany.PricePerShareBuffer;
    tableCell.cchTextMax = (int)wcslen(tableCell.pszText);
    SendMessageW(ListCompanyInfoTable, LVM_SETITEM, x, (LPARAM)&tableCell);
}

内容的提问来源于stack exchange,提问作者DaBigBoy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:32:19