You need to use the std::wstring
type instead. This will give you a wide (Unicode) string, based on the wchar_t
type, which is how Windows stores strings internally.
Then, you can simply use the c_str()
member function to retrieve a pointer to a C-style string, and pass this directly to the RegSetValueEx
function. The size()
member function gives you the length of the string, which you can pass as the cbData
parameter, except for two caveats:
cbData
expects the length of the string to include the terminating NUL character, so you will need to add 1 to the length returned by size()
.
cbData
expects the size of the string in bytes, not the number of characters, so for a wide string, you will need to multiply the value returned by size()
by the length of a wchar_t
.
bool SetStringValue(HKEY hRegistryKey,
const std::wstring& valueName,
const std::wstring& data)
{
assert(hRegistryKey != nullptr);
return (RegSetValueExW(hRegistryKey,
valueName.c_str(),
0,
REG_SZ,
(LPBYTE)(data.c_str()),
(data.size() + 1) * sizeof(wchar_t)) == ERROR_SUCCESS);
}
If you absolutely have to use narrow (ANSI) strings (and you shouldn't, because you're interfacing directly with the operating system here, not working with user data), you can do the same thing but explicitly call the ANSI version of RegSetValueEx
, which has an A
suffix. Here, you still need to add 1 to the length, but the size in bytes is equivalent to the number of characters, so no scaling is necessary.
bool SetStringValue_ANSI(HKEY hRegistryKey,
const std::string& valueName,
const std::string& data)
{
assert(hRegistryKey != nullptr);
return (RegSetValueExA(hRegistryKey,
valueName.c_str(),
0,
REG_SZ,
(LPBYTE)(data.c_str()),
data.size() + 1) == ERROR_SUCCESS);
}
Internally, RegSetValueExA
will convert the string to Unicode and then perform the same task as RegSetValueExW
.