Can someone let me know what am I doing wrong here?
MFC project, I'm using CFileDialog
to let user pick multiple files, as such:
CFileDialog fd(TRUE, NULL, NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ALLOWMULTISELECT,
NULL, this);
if(fd.DoModal() == IDOK)
{
//Multi-selection
CString strPaths;
POSITION fileNamesPosition = fd.GetStartPosition();
while(fileNamesPosition != NULL)
{
if(!strPaths.IsEmpty())
strPaths += L"\n";
strPaths += fd.GetNextPathName(fileNamesPosition);
}
AfxMessageBox(strPaths);
}
So if say, there're two shortcut files:
shortcut_1.lnk
file that refers to: "D:\Folder\Project_B\Release\Name of Project B.exe"
and shortcut_2.lnk
that refers to "D:\Folder\Project_A\Release\Name of Project A.exe"
If I pick both of them from the "File Open" dialog generated by the code above, my resulting strPaths
becomes the following, which is incorrect:
D:\Folder\Project_A\Release\Name of Project A.exe
D:\Folder\Project_A\Release\Name of Project B.exe
The second path is wrong!
Using the GetStartPosition()
and GetNextPathName()
functions is a mess. For one, they use the old-style API which depends on a correct return buffer size defined via OPENFILENAME
struct. MFC does not take care of this! As your question shows, it also has problems with links, even if the buffer size is big enough.
Save yourself a headache and use the Vista+ API, which is available through CFileDialog::GetIFileOpenDialog()
.
Here is a working code sample:
CFileDialog fd( TRUE, NULL, NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ALLOWMULTISELECT,
NULL, nullptr );
if (fd.DoModal() == IDOK)
{
//Multi-selection
CString strPaths;
CComPtr<IFileOpenDialog> piod = fd.GetIFileOpenDialog();
ASSERT( piod );
CComPtr<IShellItemArray> pResults;
if( SUCCEEDED( piod->GetResults( &pResults ) ) )
{
DWORD count = 0; pResults->GetCount( &count );
for( DWORD i = 0; i < count; ++i )
{
CComPtr<IShellItem> pItem;
if( SUCCEEDED( pResults->GetItemAt( i, &pItem ) ) )
{
CComHeapPtr<wchar_t> pPath;
if( SUCCEEDED( pItem->GetDisplayName( SIGDN_FILESYSPATH, &pPath ) ) )
{
if( !strPaths.IsEmpty() )
strPaths += L"\n";
strPaths += pPath;
}
}
}
}
AfxMessageBox( strPaths );
}