使用带有多选标志的GetOpenFileName()时如何获取所选文件的列表?

Roo*_*kie 0 c++ windows winapi visual-c++

我试过谷歌搜索,但人们似乎有同样的问题:我们无法获得所选文件的列表.

这是一段简单的工作代码,类似于我使用的代码:

OPENFILENAME ofn = { sizeof ofn };
wchar_t file[1024];
file[0] = '\0';
ofn.lpstrFile = file;
ofn.nMaxFile = 1024;
ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER;
GetOpenFileName(&ofn);
Run Code Online (Sandbox Code Playgroud)

我如何实际获取我选择的文件名?目前我只能在没有OFN_ALLOWMULTISELECT标志的情况下使用它,因此它会返回一个选定的文件名ofn.lpstrFile.我试图打印出该结构中的所有字符串变量,但什么也没找到.它仅显示所选文件的主文件夹.

Nia*_*all 6

它看起来像ofn.lpstrFile包含所有文件名,用NULL分隔并以另一个NULL结尾(实际上以空字符串结尾).

如果设置了OFN_ALLOWMULTISELECT标志并且用户选择了多个文件,则缓冲区包含当前目录,后跟所选文件的文件名.对于资源管理器样式的对话框,目录和文件名字符串是NULL分隔的,在最后一个文件名后面有一个额外的NULL字符.对于旧式对话框,字符串是空格分隔的,并且该函数使用带有空格的文件名的短文件名.您可以使用FindFirstFile函数在长文件名和短文件名之间进行转换.如果用户只选择一个文件,则lpstrFile字符串在路径和文件名之间没有分隔符.

来自MSDN.

解析内容的可能实现可以是;

wchar_t* str = ofn.lpstrFile;
std::wstring directory = str;
str += ( directory.length() + 1 );
while ( *str ) {
  std::wstring filename = str;
  str += ( filename.length() + 1 );
  // use the filename, e.g. add it to a vector
}
Run Code Online (Sandbox Code Playgroud)

  • 请记住,缓冲区中的第一项是目录:`wchar_t*str = ofn.lpstrFile; std :: wstring dir = str; str + =(dir.length()+ 1); 而(*str){...}` (2认同)
  • 实际上,要使其复杂化,如果只选择了一个文件,缓冲区中的唯一项目就是路径+文件名,因此您也必须考虑到这一点.如果存在一个项目,请按原样使用.如果存在多个项目,则第一个是目录,其余是文件名.结构不告诉你哪个是哪种情况,你必须解析缓冲区来发现它. (2认同)
  • `nFileOffset` 在单文件和多文件场景中都有意义。它指向第一个文件名,因此这确实使事情变得更容易一些。在这两种情况下,“nFileOffset”之前的所有内容都是一个目录,可能会也可能不会以 null 结尾,并且“nFileOffset”之后的所有内容都是 1 个或多个文件名。 (2认同)