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

时间:2018-10-02 22:15:02

标签: c++ winapi windows-shell

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

这是应用程序的整体,它的唯一目的是使我可以通过简单地键入可执行文件的名称并选择所需的文件夹(前提是该可执行文件所在的目录)来轻松更改命令提示符的当前工作目录。存储在PATH环境变量中。)

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

不要介意应用程序只能更改其自己的当前文件夹这一事实,这是它本身的另一个问题,与该问题无关。 here描述了此问题的解决方法。

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

1 个答案:

答案 0 :(得分:2)

使用外壳程序类IFileOpenDialog并通过调用FOS_PICKFOLDERS来设置IFileOpenDialog::SetOptions()选项,以创建标准的文件夹选择器对话框。

这是一个最小的示例。它使用COM智能指针CComPtrCComHeapPtr来简化代码。这些使我们摆脱了手动Release()CoTaskMemFree()通话的职责。请注意,您应该检查每个函数调用的HRESULT返回值是否存在错误,为简洁起见,我将其省略。

#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.  
}