我尝试使用Google搜索,但人们似乎遇到了同样的问题:我们无法获取所选文件的列表。
这是一段简单的工作代码,类似于我使用的代码:
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);
如何实际获取我选择的文件名?目前我只能在没有OFN_ALLOWMULTISELECT标志的情况下使用它,因此它将一个选定的文件名返回到ofn.lpstrFile
。我试图打印出该结构中的所有字符串变量,但什么也没找到。它仅显示所选文件的主文件夹。
答案 0 :(得分: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
}
答案 1 :(得分:1)
检查nFileExtension可能不可靠,因为如果用户没有输入文件扩展名(但只是点,如“file。”),它也可能为0。 我认为要区分单文件和多文件选择,必须检查位置nFileOffset - 1是否有空字符(终止符)。
答案 2 :(得分:0)
试试这个:
wchar_t file[1025] = {0}; // room for an extra null terminator, just in case
...
ofn.nMaxFile = 1024;
...
wchar_t* ptr = ofn.lpstrFile;
ptr[ofn.nFileOffset-1] = 0;
std::wcout << L"Directory: " << ptr << std::endl;
ptr += ofn.nFileOffset;
while (*ptr)
{
std::wcout << L"File: " << ptr << std::endl;
ptr += (lstrlenW(ptr)+1);
}
答案 3 :(得分:0)
如果在使用OFN_ALLOWMULTISELECT时选择单个文件,则nFileExtension字段包含扩展的偏移量。如果选择多个文件,则nFileExtension字段包含0.
通过这种方式,您可以确定是否选择了单个文件,并且只读取/复制lpstrFile字段指向的缓冲区(这将是一个包含完整路径和文件名的单个空终止字符串,包括扩展名)
或者如果选择了多个文件,则解析lpstrFile字段指向的缓冲区,使用nFileOffset首先读取/复制文件夹(例如使用lstrcpyn并指定length作为nFileOffset值读取)然后读取/从nFileOffset复制到下一个null,即file1字符串,添加文件字符串长度+1以获取读取/复制下一个文件字符串等的下一个位置,直到找到以null开头的文件字符串 - 这是所有结尾的双重空值文件(作为空终止之前的最后一个字符串)
答案 4 :(得分:0)