c++ - 带有 OFN_ALLOWMULTISELECT 的 CFileDialog 快捷方式的错误结果

标签 c++ winapi mfc cfiledialog

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

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

第二条路径错误!

最佳答案

使用 GetStartPosition()GetNextPathName() 函数是一团糟。一方面,他们使用旧式 API which depends on a correct return buffer size defined via OPENFILENAME struct . 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 );
}

关于c++ - 带有 OFN_ALLOWMULTISELECT 的 CFileDialog 快捷方式的错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54298811/

相关文章:

c++ - "cannot convert ' 单链表<int>::节点* ' to ' int* ' in assignment compilation terminated due to -Wfatal-errors."

windows - 不同DPI、高度计算的CComboBoxEx问题

c++ - 编译程序 linux 32 位 vs 64 位

c++ - std::regex 识别多项式方程的系数

.net - 如何在c#中调用GetGUIThreadInfo

c++ - 我该如何解决这个缓冲区溢出问题?

c# - 重新启动时删除非空文件夹

c++ - 将 FILE * 转换为 CMemFile(或从 FILE * 检索 void*)

c++ - 在 MFC CScrollView 的固定位置显示子窗口

c++ - 多态性的良好实践