我正在尝试创建一个Windows控制台应用程序,该应用程序仅打开一个文件夹选择器对话框,供用户选择文件夹。然后,应用程序会将命令提示符的当前工作目录更改为所选文件夹的路径。
这是应用程序的整体,它的唯一目的是使我可以通过简单地键入可执行文件的名称并选择所需的文件夹(前提是该可执行文件所在的目录)来轻松更改命令提示符的当前工作目录。存储在PATH
环境变量中。)
我知道MFC中存在FolderBrowserDialog
类和CFolderPickerDialog
类,但是我希望它的外观和功能尽可能接近OpenFileDialog
类(而MFC似乎不是一个不错的选择,因为它是一个控制台应用程序。)
不要介意应用程序只能更改其自己的当前文件夹这一事实,这是它本身的另一个问题,与该问题无关。 here描述了此问题的解决方法。
实现这种行为的最简单方法是什么?
答案 0 :(得分:2)
使用外壳程序类IFileOpenDialog
并通过调用FOS_PICKFOLDERS
来设置IFileOpenDialog::SetOptions()
选项,以创建标准的文件夹选择器对话框。
这是一个最小的示例。它使用COM智能指针CComPtr
和CComHeapPtr
来简化代码。这些使我们摆脱了手动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.
}