C++ ( MS V S ) 获取OpenFileName
Posted
技术标签:
【中文标题】C++ ( MS V S ) 获取OpenFileName【英文标题】:C++ ( MS V S ) GetOpenFileName 【发布时间】:2017-09-27 13:12:35 【问题描述】:我的程序旨在让用户打开 2 个文件,然后以特定方式比较它们。我正在使用 Visual Studio 在 C++ 中使用 GUI 创建它(如果这不是最好的方法,请纠正我,我只知道如何在 Linux 上编写 C 代码):
OPENFILENAME open;
ZeroMemory(&open, sizeof(open));
open.lStructSize = sizeof(LPOPENFILENAMEA);
open.lpstrFilter = "Files\0*.csv;*.xls\0\0";
open.nFileOffset = 1;
open.lpstrFile[0] = '\0';
open.nMaxFile = 2048;
open.lpstrTitle = "Title here.";
open.Flags = OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST;
BOOL selected = GetOpenFileName(&open);
我收到以下编译器错误:
E0513“const char *”类型的值不能分配给“LPCWSTR”类型的实体 错误 C2440 '=':无法从 'const char [39]' 转换为 'LPCWSTR' NewTry在filter
和title
行上。
【问题讨论】:
让我猜猜,你是在启用 Unicode 的情况下构建的(即定义了UNICODE
宏)?这意味着几乎所有字符串都需要是宽字符串。这是T
宏的原因之一。修改您的字符串文字,例如T("Title here.")
不,不要使用 TCHAR 宏。使用L
前缀@Someprogrammerdude
@DavidHeffernan 虽然启用 Unicode 应该是默认的 IMO,但通过硬编码宽字符文字,如果代码用于 UNICODE
的构建或项目中,则会遇到与此相反的问题没有定义的。或者对于可能跨平台使用的代码。我和其他人一样不喜欢使用 T 宏,但在旧的非 Unicode 接口被删除之前,不幸的是,我认为这是最好的折衷方案。
这段代码不能跨平台使用,现在支持Windows 95也没意义了。现在是 2017 年。是时候继续前进了。
@Someprogrammerdude 你记得部分正确。 C 运行时使用_TCHAR
、_T()
(和其他下划线前缀的宏/定义)和_UNICODE
。 Win32 API 使用TCHAR
、LP(C)TSTR
、TEXT()
和UNICODE
。
【参考方案1】:
由于 Windows 95/98/ME 已经长期死了,目前的建议是使用 Windows NT 系列操作系统的原生 Unicode 支持。
显然,您已经完成了该设置,因为错误消息告诉我们GetOpenFileName
被定义为GetOpenFileNameW
。在 WIndows 95 上,它被定义为 GetOpenFileNameA
。 A
变体意味着它采用 const char*
参数,W
变体采用 const wchar_t*
。
您使用L
前缀定义wchar_t
宽字符串文字,即L"Files..."
。你也可以使用std::wstring
,它的c_str()
方法返回一个空终止的const wchar_t*
。
【讨论】:
我已经尝试了 L 前缀,它会导致我在上面的 cmets 中提到更多的错误。 @C.Edelweiss:我认为您的意思是在回答 Sean 的帖子时(上面和下面可能会有所不同,因为答案被赞成)。但那些未解析的符号意味着您的代码编译。它稍后在链接中失败。这意味着这里的编译问题已经解决。至于链接器错误,那当然是添加使用的库的问题了。 @C.Edelweiss 你似乎已经放弃了。您只是在尝试从答案中获得建议,当您遇到后续不相关的失败时,请返回此处获取更多信息。试着思考和思考你在做什么,并理解它。你问的问题已经回答了。你现在有一个新问题。不要问新问题,关于您的新问题,已有数千个问题被问到。确实有数千人被问及这个问题中的问题。将来您应该尝试阅读错误消息,并进行一些独立的研究。不要只是放弃! 我现在正在研究它们,似乎有很多可能性,当我在 Linux 上做 C 语言时,要进入这个环境并不容易,谢谢你的信息。 @C.Edelweiss:嗯,链接中的未定义符号在 C for Linux 中几乎相同。实际上可能不会被命名为LNK2019
,但概念是相同的。 LNK2019
很容易在 *** 上搜索。【参考方案2】:
看起来您正在执行 unicode 构建。
如果您查看字符串结构成员上的 one 的定义,例如 lpstrFilter
,您会发现它被定义为 LPTSTR
。第一个 T
表示文本类型是 ASCII 或 Unicode,具体取决于您的构建方式。
要处理这两种情况,请在输入字符串文字时使用 _T
宏:
open.lpstrFilter = _T("Files\0*.csv;*.xls\0\0");
这将为您提供非 Unicode 版本的 ASCII 字符串,以及 Unicode 版本的 Unicode 字符串。
如果您只希望以 Unicode 为目标,那么您可以通过在字符串前面加上 L
来显式获取 Unicode 字符串:
open.lpstrFilter = L"Files\0*.csv;*.xls\0\0";
Microsoft 如何在他们的Unicode Programming Summary 页面上提供详细信息。
【讨论】:
这两种方法都给了我 17 个新错误,指向第 1 行,即 #include以上是关于C++ ( MS V S ) 获取OpenFileName的主要内容,如果未能解决你的问题,请参考以下文章
leetcode680 C++ 124ms 删掉一个字符后能否构成回文
leetcode387 C++ 84ms 字符串中的第一个唯一字符