Reputation: 222
When I pick multiple file,Path like c:\users\xxx\1.yhz becomes c:\users\xxx, I have set a break point and see that the next charactor after xxx becomes '\0', it should be '\'. Here is my code:
wchar_t szFile[256 * MAX_PATH];
wchar_t szPath[MAX_PATH];
ZeroMemory(&mOpenFileName, sizeof(mOpenFileName));
mOpenFileName.lStructSize = sizeof(mOpenFileName);
mOpenFileName.hwndOwner = NULL;
mOpenFileName.lpstrFile = szFile;
mOpenFileName.lpstrFile[0] = '\0';
mOpenFileName.nMaxFile = sizeof(szFile);
mOpenFileName.lpstrFilter = lpstrFilter;
mOpenFileName.nFilterIndex = 1;
mOpenFileName.lpstrFileTitle = NULL;
mOpenFileName.nMaxFile = 256;
mOpenFileName.lpstrInitialDir = NULL;
mOpenFileName.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT;
if (GetOpenFileName(&mOpenFileName))
{
}
How do I retrieve the fully qualified pathnames of the selected files?
Upvotes: 0
Views: 1144
Reputation: 51479
This is expected behavior, per the OPENFILENAME
documentation:
lpstrFile
Type: LPTSTRThe file name used to initialize the File Name edit control. The first character of this buffer must be NULL if initialization is not necessary. When the GetOpenFileName or GetSaveFileName function returns successfully, this buffer contains the drive designator, path, file name, and extension of the selected file.
If the OFN_ALLOWMULTISELECT flag is set and the user selects multiple files, the buffer contains the current directory followed by the file names of the selected files. For Explorer-style dialog boxes, the directory and file name strings are NULL separated, with an extra NULL character after the last file name. For old-style dialog boxes, the strings are space separated and the function uses short file names for file names with spaces. You can use the FindFirstFile function to convert between long and short file names. If the user selects only one file, the lpstrFile string does not have a separator between the path and file name.
If the buffer is too small, the function returns FALSE and the CommDlgExtendedError function returns FNERR_BUFFERTOOSMALL. In this case, the first two bytes of the lpstrFile buffer contain the required size, in bytes or characters.
What you describe is the expected behavior. You can picture the layout in memory like this:
+------+----+--------+----+--------+----+-----+--------+----+----+
| path | \0 | file 1 | \0 | file 2 | \0 | ... | file n | \0 | \0 |
+------+----+--------+----+--------+----+-----+--------+----+----+
To reconstruct the fully qualified pathnames, you have to take the path, and iterate over the files, appending one after another:
std::vector<std::wstring> files;
// Get path part
std::wstring path( mOpenFileName.lpstrFile );
path += L"\\";
// Iterate over files
const wchar_t* current = mOpenFileName.lpstrFile + path.size();
while ( *current ) {
std::wstring file( current );
files.push_back( path + file );
current += ( file.size() + 1 ); // account for zero terminator
}
Upvotes: 7