如何在地图中更正存储LPTSTR

时间:2017-10-11 18:32:46

标签: c++ visual-studio c++11 visual-c++ visual-studio-2013

我需要在地图中存储注册表中的值。我有这样的代码:

    map<int, LPTSTR> mymap;

    for (i = 0, retCode = ERROR_SUCCESS; i<cValues; i++)
    {
        cchValue = MAX_VALUE_NAME;
        achValue[0] = '\0';
        retCode = RegEnumValue(hKey, i,
            achValue,
            &cchValue,
            NULL,
            NULL,
            NULL,
            NULL);

        if (retCode == ERROR_SUCCESS)
        {
            DWORD lpData = cbMaxValueData;
            buffer[0] = '\0';
            LONG dwRes = RegQueryValueEx(hKey, achValue, 0, NULL, buffer, &lpData);

            LPTSTR val = (TCHAR*)buffer;
            MessageBox(NULL, val, L"VALUE", MB_OK);

            auto r = mymap.insert(pair<int, LPTSTR>(i, val));

            for (map<int, LPTSTR>::const_iterator it = mymap.begin(); it != mymap.end(); it++)
            {
                wchar_t szMessage2[1300];
                if (SUCCEEDED(StringCchPrintf(szMessage2, ARRAYSIZE(szMessage2), L"+ %d : %s\n", it->first, it->second)))
                {
                    MessageBox(NULL, szMessage2, L"MAP", MB_OK);
                }
            }
        }
    }

如何更正保存val来映射?现在所有键都具有相同的值(最新)。

1 个答案:

答案 0 :(得分:1)

问题是你有一个在枚举期间重用的缓冲区,而你只是将指向该缓冲区的指针存储到map中。因此,每个条目都将指向相同的物理内存,其中包含写入它的最后一段数据。

您需要将枚举字符串数据的副本存储到map。请使用std::string / std::wstring,例如:

using tstring = basic_string<TCHAR>;

map<int, tstring> mymap;

for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
{
    cchValue = MAX_VALUE_NAME;

    retCode = RegEnumValue(hKey, i,
        achValue,
        &cchValue,
        NULL,
        NULL,
        NULL,
        NULL);

    if (retCode == ERROR_SUCCESS)
    {
        DWORD dwData = cbMaxValueData;
        DWORD dwType = 0;

        LONG dwRes = RegQueryValueEx(hKey, achValue, 0, &dwType, buffer, &dwData);
        if (dwRes == ERROR_SUCCESS)
        {
            switch (dwType)
            {
                case REG_SZ:
                case REG_MULTI_SZ:
                case REG_EXPAND_SZ:
                {
                    tstring val((LPTSTR)buffer, dwData / sizeof(TCHAR));
                    //MessageBox(NULL, val.c_str(), TEXT("VALUE"), MB_OK);
                    mymap.insert(make_pair(i, val));
                    break;
                }
            }
        }
    }
}

for (auto &value: mymap)
{
    TCHAR szMessage2[1300];
    if (SUCCEEDED(StringCchPrintf(szMessage2, ARRAYSIZE(szMessage2), TEXT("+ %d : %s\n"), value.first, value.second.c_str())))
    {
        MessageBox(NULL, szMessage2, TEXT("MAP"), MB_OK);
    }
}

但是,由于您显然已启用UNICODE进行编译,因此您根本不应该使用TCHAR

map<int, wstring> mymap;

for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
{
    cchValue = MAX_VALUE_NAME;

    retCode = RegEnumValueW(hKey, i,
        achValue,
        &cchValue,
        NULL,
        NULL,
        NULL,
        NULL);

    if (retCode == ERROR_SUCCESS)
    {
        DWORD dwData = cbMaxValueData;
        DWORD dwType = 0;

        LONG dwRes = RegQueryValueExW(hKey, achValue, 0, &dwType, buffer, &dwData);
        if (dwRes == ERROR_SUCCESS)
        {
            switch (dwType)
            {
                case REG_SZ:
                case REG_MULTI_SZ:
                case REG_EXPAND_SZ:
                {
                    wstring val((LPWSTR)buffer, dwData / sizeof(WCHAR));
                    //MessageBoxW(NULL, val.c_str(), L"VALUE", MB_OK);
                    mymap.insert(make_pair(i, val));
                    break;
                }
            }
        }
    }
}

for (auto &value: mymap)
{
    WCHAR szMessage2[1300];
    if (SUCCEEDED(StringCchPrintfW(szMessage2, ARRAYSIZE(szMessage2), L"+ %d : %s\n", value.first, value.second.c_str())))
    {
        MessageBoxW(NULL, szMessage2, L"MAP", MB_OK);
    }
}