在 C++ 中创建文件夹选取器对话框的最简单方法是什么?

What is the easiest way to create a folder picker dialog box in C++?

我正在尝试创建一个 Windows 控制台应用程序,它只打开一个文件夹选择器对话框,用户可以通过该对话框 select 一个文件夹。然后应用程序会将命令提示符的当前工作目录更改为 selected 文件夹的路径。

这是整个应用程序,它的唯一目的是让我通过简单地键入可执行文件的名称和 selecting 所需的文件夹 (前提是存储可执行文件的目录列在 PATH 环境变量中)。

我知道 MFC 中存在 FolderBrowserDialog class 和 CFolderPickerDialog class,但我只是希望它的外观和功能尽可能接近尽可能 OpenFileDialog class(MFC 似乎不是一个很好的选择,因为它是一个控制台应用程序)。

不要介意应用程序只能更改它自己的当前文件夹这一事实,这是它自己的另一个问题,与此问题无关。 .

描述了解决此问题的方法

实现这种行为的最简单方法是什么?

使用 shell class IFileOpenDialog and set the FOS_PICKFOLDERS option via a call to IFileOpenDialog::SetOptions() 创建标准文件夹选择器对话框。

这是一个最小的例子。它使用 COM 智能指针 CComPtrCComHeapPtr 来简化代码。这些使我们免于手动 Release()CoTaskMemFree() 调用的职责。请注意,您应该检查每个函数调用的 HRESULT return 值是否有错误,为简洁起见,我已将其省略。

#include <iostream>
#include <ShlObj.h>
#include <atlbase.h>  // for CComPtr, CComHeapPtr

struct ComInit
{
    ComInit() { CoInitialize(nullptr); }
    ~ComInit() { CoUninitialize(); }
};

int main()
{
    // Initialize COM to be able to use classes like IFileOpenDialog.
    ComInit com;

    // Create an instance of IFileOpenDialog.
    CComPtr<IFileOpenDialog> pFolderDlg;
    pFolderDlg.CoCreateInstance( CLSID_FileOpenDialog );

    // Set options for a filesystem folder picker dialog.
    FILEOPENDIALOGOPTIONS opt{};
    pFolderDlg->GetOptions( &opt );
    pFolderDlg->SetOptions( opt | FOS_PICKFOLDERS | FOS_PATHMUSTEXIST | FOS_FORCEFILESYSTEM );

    // Show the dialog modally.
    if( SUCCEEDED( pFolderDlg->Show( nullptr ) ) )
    {
        // Get the path of the selected folder and output it to the console.

        CComPtr<IShellItem> pSelectedItem;
        pFolderDlg->GetResult( &pSelectedItem );

        CComHeapPtr<wchar_t> pPath;
        pSelectedItem->GetDisplayName( SIGDN_FILESYSPATH, &pPath );

        std::wcout << L"Selected folder: " << pPath.m_pData << std::endl;
    }
    // Else dialog has been canceled. 

    // The destructor of ComInit calls CoUninitialize() here after all
    // other objects have been destroyed.  
}