如何将动态字符串转换为wchar_t以更改背景

时间:2017-07-17 05:20:30

标签: c++ winapi wchar-t

我一直在互联网上寻找一些解决方案但是它们都是从一个常量字符串转换而来的。 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);
  1. 错误(有效)E0040需要标识符
  2. 错误(活动)E0020标识符“L”未定义
  3. 错误(有效)不允许使用E0254类型名称
  4. 错误(有效)E0018预期')'
  5. 过了一会儿,我替换了函数的返回类型,所以它会返回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;
    }
    

    但是,第三个参数显示错误

    1. 错误E0167类型“const wchar_t *”的参数与“PVOID”类型的参数不兼容
    2. 那我该怎么办呢?

      编辑:有人认为这是重复的,事实并非如此。 How to convert string to wstring in C++与此问题无关,因为询问该主题的人正在寻求特殊字符的帮助。

1 个答案:

答案 0 :(得分:2)

首先调用Unicode版本GetModuleFileNameW(),这样您就不必转换。

另外,永远不要返回指向函数局部变量的字符串的指针(除非它是静态的)!否则你将返回一个悬空指针。而是返回与您的第一个版本类似的std::wstring。您可以使用“指向第一个字符的”技巧直接使用std::wstring作为缓冲区。

std::wstring GetExePath() {
    std::wstring buffer(MAX_PATH, L'\0');  // 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); 

pvParam的{​​{1}}参数是指向非常量数据的指针,所以我们必须再次使用“指向第一个字符的指针”技巧(以避免丑陋{{1} }})。

使用C ++ 17,这可以写成一行代码:

SystemParametersInfoW

其他需要改进的事项,留作练习:

  • const_cast MSDN reference的评论中所述检查错误情况int return_value = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (GetExePath() + L"picture.png").data(), SPIF_UPDATEINIFILE); ,以便您可以支持超过ERROR_INSUFFICIENT_BUFFER的修补程序。