如何将动态字符串转换为 wchar_t 以更改背景
How to convert a dynamic string to wchar_t to change background
我一直在网上寻找一些解决方案,但它们都是从常量字符串转换而来的。 Here's 我使用的一段代码,无需额外的库即可将字符串转换为 wchar_t。我想做的是,我想用我的背景更改 windows 计算机的背景。现在我不能假设我下载的文件夹在 C:\Downloads 中,因为有些人更改了他们的下载文件夹,或者他们可能将整个文件夹移动到另一个位置。所以在第一个代码中,我试图获取 .exe 文件的路径。
string GetExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\/");
return string(buffer).substr(0, pos + 1);//gets the first character in path up to the final backslash
}
接下来我要将我要制作的图片作为我的背景,放在与 .exe 文件相同的文件夹中。
//error on the third parameter
int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, L(string)(GetExePath() + "\picture.png"), SPIF_UPDATEINIFILE);
- 错误(活动)E0040 需要一个标识符
- 错误(活动)E0020 标识符 "L" 未定义
- Error (active) E0254 type name is not allowed
- 错误(活动)E0018 需要 ')'
过了一会儿,我替换了函数的 return 类型,所以它会 return wchar_t*.
const wchar_t* GetExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\/");
string path = string(buffer).substr(0, pos + 1);
path += "\HandleCamWallpaperwithgradient.png";
cout << path << endl;
wstring wide;
for (int i = 0; i < path.length(); ++i){
wide += wchar_t(path[i]);
}
const wchar_t* result = wide.c_str();
return result;
}
但是,第三个参数显示错误
- 错误 E0167 "const wchar_t *" 类型的参数与 "PVOID"
类型的参数不兼容
那我该如何解决呢?
编辑:有人认为这是重复的,但事实并非如此。 How to convert string to wstring in C++ 与此问题无关,因为在该线程上提问的人正在寻求特殊字符的帮助。
首先调用 Unicode 版本 GetModuleFileNameW()
,因此您无需转换。
此外,永远不要 return 指向作为函数局部变量的字符串的指针(除非它是静态的)!否则,您将成为 return 悬空指针。相反,return std::wstring
类似于您的第一个版本。您可以使用 "pointer-to-first-character" 技巧将 std::wstring
直接用作缓冲区。
std::wstring GetExePath() {
std::wstring buffer(MAX_PATH, L'[=10=]'); // reserve buffer
int len = GetModuleFileNameW(NULL, &buffer[0], buffer.size() );
buffer.resize(len); // resize to actual length
string::size_type pos = buffer.find_last_of(L"\/");
return buffer.substr(0, pos + 1);//gets the first character in path up to the final backslash
}
第二个错误可以这样修正:
std::wstring path = GetExePath() + L"picture.png";
int return_value = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, &path[0], SPIF_UPDATEINIFILE);
SystemParametersInfoW
的pvParam
参数是指向非常量数据的指针,所以我们又要在这里使用"pointer-to-first-character"的技巧(避免难看的const_cast
).
对于 C++17,这可以写成一行代码:
int return_value = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (GetExePath() + L"picture.png").data(), SPIF_UPDATEINIFILE);
其他需要改进的地方,留作练习:
- 如
GetModuleFileName()
MSDN reference 的注释中所述检查错误条件 ERROR_INSUFFICIENT_BUFFER
以便您可以支持长于 MAX_PATH
. 的路径
我一直在网上寻找一些解决方案,但它们都是从常量字符串转换而来的。 Here's 我使用的一段代码,无需额外的库即可将字符串转换为 wchar_t。我想做的是,我想用我的背景更改 windows 计算机的背景。现在我不能假设我下载的文件夹在 C:\Downloads 中,因为有些人更改了他们的下载文件夹,或者他们可能将整个文件夹移动到另一个位置。所以在第一个代码中,我试图获取 .exe 文件的路径。
string GetExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\/");
return string(buffer).substr(0, pos + 1);//gets the first character in path up to the final backslash
}
接下来我要将我要制作的图片作为我的背景,放在与 .exe 文件相同的文件夹中。
//error on the third parameter
int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, L(string)(GetExePath() + "\picture.png"), SPIF_UPDATEINIFILE);
- 错误(活动)E0040 需要一个标识符
- 错误(活动)E0020 标识符 "L" 未定义
- Error (active) E0254 type name is not allowed
- 错误(活动)E0018 需要 ')'
过了一会儿,我替换了函数的 return 类型,所以它会 return wchar_t*.
const wchar_t* GetExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\/");
string path = string(buffer).substr(0, pos + 1);
path += "\HandleCamWallpaperwithgradient.png";
cout << path << endl;
wstring wide;
for (int i = 0; i < path.length(); ++i){
wide += wchar_t(path[i]);
}
const wchar_t* result = wide.c_str();
return result;
}
但是,第三个参数显示错误
- 错误 E0167 "const wchar_t *" 类型的参数与 "PVOID" 类型的参数不兼容
那我该如何解决呢?
编辑:有人认为这是重复的,但事实并非如此。 How to convert string to wstring in C++ 与此问题无关,因为在该线程上提问的人正在寻求特殊字符的帮助。
首先调用 Unicode 版本 GetModuleFileNameW()
,因此您无需转换。
此外,永远不要 return 指向作为函数局部变量的字符串的指针(除非它是静态的)!否则,您将成为 return 悬空指针。相反,return std::wstring
类似于您的第一个版本。您可以使用 "pointer-to-first-character" 技巧将 std::wstring
直接用作缓冲区。
std::wstring GetExePath() {
std::wstring buffer(MAX_PATH, L'[=10=]'); // reserve buffer
int len = GetModuleFileNameW(NULL, &buffer[0], buffer.size() );
buffer.resize(len); // resize to actual length
string::size_type pos = buffer.find_last_of(L"\/");
return buffer.substr(0, pos + 1);//gets the first character in path up to the final backslash
}
第二个错误可以这样修正:
std::wstring path = GetExePath() + L"picture.png";
int return_value = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, &path[0], SPIF_UPDATEINIFILE);
SystemParametersInfoW
的pvParam
参数是指向非常量数据的指针,所以我们又要在这里使用"pointer-to-first-character"的技巧(避免难看的const_cast
).
对于 C++17,这可以写成一行代码:
int return_value = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (GetExePath() + L"picture.png").data(), SPIF_UPDATEINIFILE);
其他需要改进的地方,留作练习:
- 如
GetModuleFileName()
MSDN reference 的注释中所述检查错误条件ERROR_INSUFFICIENT_BUFFER
以便您可以支持长于MAX_PATH
. 的路径