【问题标题】:Populate a Virtual ListView with std::vector<std::string>使用 std::vector<std::string> 填充虚拟 ListView
【发布时间】:2017-07-26 05:43:12
【问题描述】:

我有一个包含数千个字符串的向量:

std::vector<std::wstring> a;

充满了一些算法。

按照here 描述的方法,下面是我如何将ListView 创建为“虚拟列表”:

hList = CreateWindowEx(0, WC_LISTVIEW, L"", WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_OWNERDATA, 0, 0, 800, 400, hWnd, (HMENU)ID_LISTVIEW, hInst, NULL);

LV_COLUMN lvcol;
...
ListView_InsertColumn(hList, 0, &lvcol);

ListView_SetItemCountEx(hList, 100000, LVSICF_NOSCROLL);

...

// in the message loop
case WM_NOTIFY:
    pdi = (NMLVDISPINFO*) lParam;
    pi = pdi->item;
    switch (pdi->hdr.code)
    {
        case LVN_GETDISPINFO:
        {
            pi.mask = LVIF_TEXT;
            pi.pszText = a[pi.iItem];    // the nth item should be the nth string in the vector
        }
    }

我尝试了很多变化:

pi.pszText = a[pi.iItem];

但他们都因此类错误而失败:

错误 C2440:“=”:无法从“std::basic_string,std::allocator>”转换为“LPWSTR”

什么可以帮助做到这一点?


注意:实际上我想在ListView 的行n 上显示:向量a 的第n 字符串与数字n 连接,就像这样@ 987654332@ 在第 217 行。

注意 2:即使在 Igor 的建议之后(即演员 pi.pszText = LPWSTR(a[pi.iItem].c_str());),ListView 仍然是空的,而不是显示元素。

【问题讨论】:

  • 你正在构建一个 Unicode。控件需要 Unicode 字符串。你能用std::vector&lt;std::wstring&gt; 代替吗?然后你会写pi.pszText = a[pi.iItem].c_str();
  • 啊。刚投:pi.pszText = LPWSTR(a[pi.iItem].c_str());
  • 什么是圆周率?看起来像一个局部变量。您需要返回通知消息中传递给您的结构中的字符串。
  • @Basj:根据documentation:“如果LVITEM 结构接收项目文本,则pszTextcchTextMax 成员指定缓冲区的地址和大小。您可以将文本复制到缓冲区,也可以将字符串的地址分配给pszText 成员。在后一种情况下,您不能更改或删除字符串,直到相应的项目文本被删除或已发送另外两条LVN_GETDISPINFO 消息。"

标签: c++ listview winapi vector


【解决方案1】:

我不确定您面临的问题,但可以肯定的是,您在请求宽字符字符串时传递了多字节字符串(std::string,使用char) (std::wstring,使用WCHAR)。

这是一个方便的代码,可以将std::string 转换为std::wstring

inline std::wstring WideFromMulti(
    std::string const & multi,
    UINT codepage)
{
    int cchWide = MultiByteToWideChar(codepage, 0, multi.c_str(), -1, nullptr, 0);
    LPWSTR szWide = new wchar_t[cchWide];
    MultiByteToWideChar(codepage, 0, multi.c_str(), -1, szWide, cchWide);
    std::wstring wide(szWide);
    delete[] szWide;
    return wide;
}

inline std::wstring WideFromUtf8(
    std::string const & utf8)
{
    return WideFromMulti(utf8, CP_UTF8);
}

那么你就可以通过c_str()得到LPCWSTR

std::string test_str;
std::wstring test_wstr = WideFromUtf8(test_str);
LPCWSTR wszTest = test_wstr.c_str();

LPWSTR 呢?好吧,如果您确定字符串不会被修改,您可以通过const_cast&lt;LPWSTR&gt;(wszTest) 进行转换。如果您强烈反对const_cast,您可以像这样创建LPWSTR 的临时副本:

std::wstring test(L"Hello world");
LPCWSTR szTestConst = test.c_str();
int cchMax = ::lstrlenW(szTestConst) + 1;
std::vector<WCHAR> v(cchMax);
::lstrcpynW(&v[0], szTestConst, cchMax);
LPWSTR szTest = &v[0];

【讨论】:

    【解决方案2】:

    我真的不知道为什么,但这解决了它:

    case WM_NOTIFY:
        pdi = (NMLVDISPINFO*) lParam;
        //pi = pdi->item;
        switch (pdi->hdr.code)
        {
            case LVN_GETDISPINFO:
            {
                //pi.mask = LVIF_TEXT;
                pdi->item.mask = LVIF_TEXT;;
                //pi.pszText = a[pi.iItem];   
                pdi->item.pszText = a[pi.iItem];   
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 2016-03-15
      • 1970-01-01
      相关资源
      最近更新 更多