1

在这个例子中它编译成工作代码,但是如果我在它周围放置更复杂的东西,程序就会关闭并且无法打开对话窗口。错误信息正是:

test.cpp:10:19:警告:不推荐将字符串常量转换为 'LPWSTR {aka wchar_t*}' [-Wwrite-strings]

#include <windows.h>
int main() {
  OPENFILENAMEW ofn;
  ZeroMemory(&ofn, sizeof(ofn));
  ofn.lStructSize = sizeof(OPENFILENAME);
  ofn.nMaxFile = MAX_PATH;
  ofn.lpstrFile = L"file name";
}
4

4 回答 4

4

您需要为窗口提供一个缓冲区来填充。

用于初始化文件名​​编辑控件的文件名。如果不需要初始化,此缓冲区的第一个字符必须为 NULL。当 GetOpenFileName 或 GetSaveFileName 函数成功返回时,此缓冲区包含所选文件的驱动器指示符、路径、文件名和扩展名。

基本上,Windows 在打开/保存对话框中选择文件后,会使用所选文件的路径和文件名填充缓冲区。所以基本上,你的代码应该是这样的:

#include <windows.h>

int main()
{
    wchar_t fileBuffer[MAX_PATH] = {0};

    OPENFILENAMEW ofn;
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.nMaxFile = MAX_PATH;
    ofn.lpstrFile = fileBuffer;
}

我希望这有帮助。

于 2013-01-18T17:11:31.583 回答
2

lpstrFile成员被定义为非const(类型LPTSTR),但字符串文字是constlpstrFile当与特定的 WINAPI 函数一起使用时,它将被填充、写入的状态的描述。写入字符串文字是未定义的行为。

OPENFILENAME文档:

用于初始化文件名​​编辑控件的文件名。如果不需要初始化,此缓冲区的第一个字符必须为 NULL。当 GetOpenFileName 或 GetSaveFileName 函数成功返回时,此缓冲区包含所选文件的驱动器指示符、路径、文件名和扩展名。

要更正指向 的lpStrFile数组wchar_t

wchar_t file[100] = L"file name";

ofn.plstrFile = file;
于 2013-01-18T15:58:23.797 回答
1

从有关该领域的文档中:lpstrFile

当 GetOpenFileName 或 GetSaveFileName 函数成功返回时,此缓冲区包含所选文件的驱动器指示符、路径、文件名和扩展名。

这应该是指向可以写入的缓冲区的指针,并且它必须足够大以容纳您选择的文件名。将它指向一个常量字符串是一个错误,并且会导致您观察到的未定义行为。

于 2013-01-18T15:58:21.977 回答
1

不推荐使用指向字符串文字的非常量指针,因为写入字符串文字会导致未定义的行为:

const char* s = "abc"; // correct
char* s = "abc"; // deprecated

这同样适用于wchar_t字符串。

ofn.lpstrFile指针是非常量的,旨在指向可写缓冲区。您需要提供一个可写缓冲区并将ofn.plstrFile指针设置为该缓冲区。

wchar_t buf[1024];
ofn.plstrFile = buf;

有关详细信息,请参阅OPENFILENAME 文档

于 2013-01-18T15:59:16.773 回答