3

有人可以让我知道我在这里做错了什么吗?

MFC 项目,我CFileDialog用来让用户选择多个文件,例如:

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);
}

因此,如果说,有两个快捷方式文件:

shortcut_1.lnk文件指的是:"D:\Folder\Project_B\Release\Name of Project B.exe"

shortcut_2.lnk那是指_"D:\Folder\Project_A\Release\Name of Project A.exe"

如果我从上面代码生成的“文件打开”对话框中选择它们,我的结果strPaths将变为以下,这是不正确的:

D:\Folder\Project_A\Release\Name of Project A.exe
D:\Folder\Project_A\Release\Name of Project B.exe

第二条路错了!

4

2 回答 2

5

使用GetStartPosition()andGetNextPathName()函数是一团糟。一方面,他们使用旧式 API ,该 API 取决于通过OPENFILENAMEstruct定义的正确返回缓冲区大小。MFC处理这个!正如您的问题所示,即使缓冲区大小足够大,链接也存在问题。

省去头疼的事,使用Vista+ API,可通过CFileDialog::GetIFileOpenDialog().

这是一个工作代码示例:

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 );
}
于 2019-01-21T23:32:06.920 回答
2

听起来像一个错误CFileDialog

通常,返回的路径是当前显示的目录路径和所选文件名的串联。对于lnk文件,可能CFileDialog只是提取目标文件名并将其连接到文件的父文件夹的路径lnk,而不是仅返回lnk文件内的完整目标路径。如果没有看到CFileDialog.

为避免这种行为,您可以OFN_NODEREFERENCELINKS在调用对话框时包含该标志,以便获得实际lnk文件的完整路径,然后您可以IShellLink在对话框关闭后手动解析它们的目标。

于 2019-01-21T23:22:07.930 回答