2017-10-11 19 views
0

我需要存儲註冊表中的地圖值。我有這樣的代碼:如何更正地圖中的商店LPTSTR

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保存到地圖?現在所有的鍵都有相同的值(最新)。

+4

是'地圖 mymap;'或'map mymap;'取決於是否定義了UNICODE。 –

+0

'LPTSTR'是一個指針。它指向'buffer'的開始。由於您不斷重複使用相同的緩衝區以便將來插入,因此只需重複插入相同的指針,該指針指向包含放置在其中的最後一個值的緩衝區。 –

+2

鑑於您將寬字符串傳遞給'MessageBox',請刪除'TCHAR'並使用寬字符串。 'TCHAR'的兼容性對於新代碼來說並沒有多少用處,而且如果你的代碼用寬字符串編譯,你顯然不需要它。代碼中的所有'TCHAR'內容僅用於混淆它,並且沒有任何好處,因爲未定義'UNICODE'會導致編譯錯誤。 – chris

回答

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); 
    } 
}