在 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 智能指针 CComPtr
和 CComHeapPtr
来简化代码。这些使我们免于手动 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.
}
我正在尝试创建一个 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 智能指针 CComPtr
和 CComHeapPtr
来简化代码。这些使我们免于手动 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.
}