【发布时间】:2020-12-31 23:56:47
【问题描述】:
=============================== 更新================ ===============
我尝试过使用 Barrnet Chou 的建议。我已经使用评论中提到的实现创建了SelectDialog.h 和SelectDialog.cpp 文件,我已经将SelectDialog.h 包含在主.cpp 文件中,并且我尝试使用我的主.cpp 文件中的代码作为如下:
CSelectDialog ofd(TRUE, _T("*.*"), NULL, OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT,
_T("All files and folders(*.*)|*.*||"));
CString path, nFile, info;
if (ofd.DoModal() != IDOK)
return;
for (int i = 0; i < ofd.m_SelectedItemList.GetCount(); i++) {
nFile = ofd.GetFileName();
path = ofd.GetFolderPath();
info = ofd.m_SelectedItemList[i].GetString();
}
MessageBox(path);
MessageBox(nFile);
MessageBox(info);
我不知道我做错了什么,但我仍然遇到同样的问题,我只能选择文件而不是文件夹。我还尝试添加标志FOS_PICKFOLDERS,正如我在调用ofd varibale 的构造函数时提到的IInspectable,但它也没有帮助。关于我错过了什么的任何想法?
================================================ ==============
我正在用 C++ 在 Visual Studio 2017 上编写一个基于对话框的 MFC 应用程序。我想让用户选择他稍后将写入的文件或文件夹。在用户选择所需的文件或文件夹后,我想将路径保存到pFile 变量中以供以后使用。
我看到了一些关于这个主题的问题,但这些帖子的所有答案都只提供一个功能 - 选择文件或文件夹。
我尝试过的:
方法#1
OPENFILENAME file;
TCHAR szFileName[MAX_PATH] = _T("");
SecureZeroMemory(&file, sizeof(file));
file.lStructSize = sizeof(OPENFILENAME);
file.hwndOwner = NULL;
file.lpstrFilter = NULL;
file.lpstrFile = szFileName;
file.nMaxFile = MAX_PATH;
file.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
file.lpstrDefExt = "txt";
GetSaveFileName(&file);
pFile = file.lpstrFile;
问题:只允许选择如下图所示的文件:
方法#2
CFileDialog dlgFile(TRUE);
CString fileName;
const int c_cMaxFiles = 100;
const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;
dlgFile.GetOFN().lpstrFile = fileName.GetBuffer(c_cbBuffSize);
dlgFile.GetOFN().nMaxFile = c_cbBuffSize;
CString file_name, dir_path;
if (dlgFile.DoModal() == IDOK) {
file_name = dlgFile.GetFileName();
dir_path = dlgFile.GetFolderPath();
pFile = dir_path + "\\" + file_name;
}
fileName.ReleaseBuffer();
问题:仅允许用户选择方法 #1 所附图片中的文件
方法#3
LPCSTR m_strFolderPath = ("C:\\"); // Just for sample
LPCSTR m_strDisplayName;
CFolderDialog dlg(_T("Dialog Title"), m_strFolderPath, this);
if (dlg.DoModal() == IDOK)
{
pFile = dlg.GetFolderPath();
}
问题:只允许用户选择文件夹,如下图所示:
方法#4
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(bi));
TCHAR szDisplayName[MAX_PATH];
szDisplayName[0] = (TCHAR)("");
bi.hwndOwner = NULL;
bi.pidlRoot = NULL;
bi.pszDisplayName = szDisplayName;
bi.lpszTitle = _T("Please select a folder for storing received files :");
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lParam = NULL;
bi.iImage = 0;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
TCHAR szPathName[MAX_PATH];
if (NULL != pidl)
{
BOOL bRet = SHGetPathFromIDList(pidl, szPathName);
if (FALSE == bRet)
return;
AfxMessageBox(szPathName);
}
问题:只允许用户选择方法 #3 所附图片中的文件夹
方法#5
我已经尝试使用IFileDialog 来实现此目的,但我不确定如何使用它来选择文件或文件夹。我认为这就是我需要的解决方案,如果有人可以向我推荐一些如何使用它的示例,我将不胜感激?我从 Microsoft Docs 文档中看到了一些诸如 this 和 git 中的 this 以及堆栈溢出问题中的 this 和 that one 之类的,但我无法应用它们。我尝试使用前面提到的代码构建类似的东西,但我只做到了这一点:
IFileDialog *pfd;
IFileSaveDialog *pfsd;
HRESULT hr = pfd->QueryInterface(&pfsd);
LPWSTR *pszName;
if (SUCCEEDED(hr)) {
hr = pfd->GetFileName(pszName);
if (SUCCEEDED(hr)) {
MessageBox((LPCSTR)pszName);
}
}
如果有人能解释我如何使用 IFileDialog 使用户能够选择文件和文件夹,或者如果有任何其他解决方案可以解决此问题,我将不胜感激。
谢谢。
【问题讨论】:
-
这在link进行了讨论
-
@TomTom 感谢您的回复。我看过这篇文章,但是那里的所有答案都允许我选择文件或文件夹,我想同时选择两者。你知道我该怎么做吗?
-
基于这个讨论和编码,我看到他们使用两种不同的方法或类来实现这一点。他们还表明,即使是 MS 也是如此。
-
FOS_PICKFOLDERS在项目和文件夹选择模式之间切换。这些模式对于IFileDialog也是互斥的。允许用户选择文件或文件夹引入了一个非常混乱的界面。例如,双击文件夹应该做什么并不明显(导航到目录或选择文件夹?)。
标签: c++ visual-studio file mfc dialog