============================== UPDATE ==============================
I've tried using what Barrnet Chou suggested. I've created SelectDialog.h
and SelectDialog.cpp
files with the implementation mentioned in the comment, I've included SelectDialog.h
in the main .cpp
file and I've tried using the code from my main .cpp
file as follows:
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);
I don't know what did I do wrong, but I'm still having the same problem, I can only choose files and not folders. I've also tried adding the flag FOS_PICKFOLDERS
as IInspectable mentioned when I call the constructor of ofd
varibale, but it didn't help either. any ideas about what I've missed?
============================== ==============================
I'm writing a dialog based MFC application on Visual Studio 2017 in C++. I want to enable the user to choose a file or folder into which he will write later. After the user will choose the desired file or folder I want to save the path into pFile
variable for later use.
I've seen some questions on this subject, but all the answers to those posts provide only one functionality - either to choose a file or a folder.
what I've tried:
Method #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;
Problem: Allows to choose only files as seen in the picture below:
Method #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();
Problem: Allows user to select files only as seen at the picture attached to Method #1
Method #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();
}
Problem: Allows the user to choose folders only as seen in the picture below:
Method #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);
}
Problem: Allows user to select folders only as seen at the picture attached to Method #3
Method #5
I've tried using IFileDialog
for this purpose, but I'm not sure how to use it to choose a file or a folder. I think that's the solution I need, and I'll appreciate it if anyone could refer me to some examples for how to use it? I've seen some such as this from Microsoft Docs documentation and this one from git and also this and that one from stack overflow questions but I wasn't able to apply them. I've tried constructing something similar by using the previously mentioned codes, but I only got this far:
IFileDialog *pfd;
IFileSaveDialog *pfsd;
HRESULT hr = pfd->QueryInterface(&pfsd);
LPWSTR *pszName;
if (SUCCEEDED(hr)) {
hr = pfd->GetFileName(pszName);
if (SUCCEEDED(hr)) {
MessageBox((LPCSTR)pszName);
}
}
I'd really appreciate If anyone could explain me how to use IFileDialog to enable the user to choose files and folders, or if there's any other solution for this problem, I'd like to try it.
Thank you.
If you want to select files and folders at the same time, I suggest that you could refer to the following example: CSelectDialog
.
Instructions:
CSelectDialog ofd(TRUE, _T("*.*"), NULL, OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT, _T("All files and folders(*.*)|*.*||") );
if( ofd.DoModal() != IDOK )
return;
for( int i=0; i<ofd.m_SelectedItemList.GetCount(); i++ ){
//...
}
Detailed implementation: 1.
#pragma once
#include <dlgs.h> // for (MULTI)FILEOPENORD
// CSelectDialog
class CSelectDialog : public CFileDialog
{
DECLARE_DYNAMIC(CSelectDialog)
public:
CSelectDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |
OFN_EXPLORER & (~OFN_SHOWHELP),
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL);
virtual ~CSelectDialog();
protected:
virtual void OnInitDone();
virtual void OnFolderChange();
virtual BOOL OnFileNameOK();
static LRESULT CALLBACK WindowProcNew(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
public:
static CString m_strCurrendDirectory;
static CStringArray m_SelectedItemList; /*this list includes files and folders
are selected by user. */
static WNDPROC m_wndProc;
};
#include "stdafx.h"
#include "SelectDialog.h"
#pragma warning( push )
#pragma warning( disable : 4311 4312 )
// CSelectDialog
CString CSelectDialog::m_strCurrendDirectory;
CStringArray CSelectDialog::m_SelectedItemList;
WNDPROC CSelectDialog::m_wndProc = NULL;
IMPLEMENT_DYNAMIC(CSelectDialog, CFileDialog)
CSelectDialog::CSelectDialog(BOOL bOpenFileDialog,
LPCTSTR lpszDefExt,
LPCTSTR lpszFileName,
DWORD dwFlags,
LPCTSTR lpszFilter,
CWnd* pParentWnd)
:CFileDialog(
bOpenFileDialog,
lpszDefExt,
lpszFileName,
dwFlags | OFN_EXPLORER | OFN_HIDEREADONLY & (~OFN_SHOWHELP),
lpszFilter,
pParentWnd)
{
dwFlags |= (OFN_EXPLORER | OFN_HIDEREADONLY & (~OFN_SHOWHELP));
};
CSelectDialog::~CSelectDialog()
{
};
BEGIN_MESSAGE_MAP(CSelectDialog, CFileDialog)
END_MESSAGE_MAP()
// CSelectDialog message handlers
BOOL CSelectDialog::OnFileNameOK()
{
if (CFileDialog* pDlg = (CFileDialog*)CWnd::FromHandle(GetParent()->m_hWnd))
{
CWnd* pWnd = pDlg->GetDlgItem(lst2); //getting list
if (pWnd == NULL)
return FALSE;
m_SelectedItemList.RemoveAll(); // emptying list
CListCtrl* wndLst1 = (CListCtrl*)(pWnd->GetDlgItem(1));
int nSelected = wndLst1->GetSelectedCount();
if (!nSelected) // nothing selected -- don't retrieve list
return FALSE;
CString strItemText, strDirectory = m_strCurrendDirectory;
if (strDirectory.Right(1) != _T("\\"))
strDirectory += _T("\\");
CString fileslist = _T("");
pDlg->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)fileslist.GetBuffer(MAX_PATH));
fileslist.ReleaseBuffer();
strItemText = strDirectory + fileslist;
if(nSelected == 1 && fileslist != _T(""))
{
m_SelectedItemList.Add(strItemText);
return CFileDialog::OnFileNameOK();
}
}
::MessageBeep( MB_ICONQUESTION );
return 1; //don't let the dialog to close
};
void CSelectDialog::OnFolderChange()
{
m_strCurrendDirectory = GetFolderPath();
CFileDialog::OnFolderChange();
};
void CSelectDialog::OnInitDone()
{
m_strCurrendDirectory = GetFolderPath();
CWnd* pFD = GetParent();
HideControl(edt1);
HideControl(cmb1);
HideControl(stc2);
//HideControl(cmb13);
//HideControl(stc3);
CRect rectCancel; pFD->GetDlgItem(IDCANCEL)->GetWindowRect(&rectCancel);
pFD->ScreenToClient(&rectCancel);
CRect rectOK; pFD->GetDlgItem(IDOK)->GetWindowRect(&rectOK);
pFD->ScreenToClient(&rectOK);
pFD->GetDlgItem(IDOK)->SetWindowPos(0,rectCancel.left - rectOK.Width() - 5, rectCancel.top, 0,0, SWP_NOZORDER | SWP_NOSIZE);
CRect rectList2; pFD->GetDlgItem(lst1)->GetWindowRect(&rectList2);
pFD->ScreenToClient(&rectList2);
pFD->GetDlgItem(lst1)->SetWindowPos(0,0,0,rectList2.Width(), abs(rectList2.top - (rectCancel.top - 5)), SWP_NOMOVE | SWP_NOZORDER);
CRect rectStatic;pFD->GetDlgItem(stc3)->GetWindowRect(&rectStatic);
pFD->ScreenToClient(&rectStatic);
pFD->GetDlgItem(stc3)->SetWindowPos(0,rectCancel.left - 375,rectCancel.top + 5, rectStatic.Width(), rectStatic.Height(), SWP_NOZORDER);
CRect rectEdit1;pFD->GetDlgItem(cmb13)->GetWindowRect(&rectEdit1);
pFD->ScreenToClient(&rectEdit1);
pFD->GetDlgItem(cmb13)->SetWindowPos(0,rectCancel.left - 320,rectCancel.top, rectEdit1.Width() - 15, rectEdit1.Height(), SWP_NOZORDER);
SetControlText(stc3, _T("Item name:"));
SetControlText(IDOK, _T("Select"));
m_wndProc = (WNDPROC)::SetWindowLong(pFD->m_hWnd, GWL_WNDPROC, (long)WindowProcNew);
pFD->CenterWindow();
};
LRESULT CALLBACK CSelectDialog::WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_COMMAND)
{
if (HIWORD(wParam) == BN_CLICKED)
{
if (LOWORD(wParam) == IDOK)
{
if (CFileDialog* pDlg = (CFileDialog*)CWnd::FromHandle(hwnd))
{
m_SelectedItemList.RemoveAll(); // emptying list
CWnd* pWnd = pDlg->GetDlgItem(lst2); //getting list
if (pWnd == NULL)
return FALSE;
CListCtrl* wndLst1 = (CListCtrl*)(pWnd->GetDlgItem(1));
int nSelected = wndLst1->GetSelectedCount();
if (!nSelected) // nothing selected -- don't retrieve list
return FALSE;
CString strItemText, strDirectory = m_strCurrendDirectory;
if (strDirectory.Right(1) != _T("\\"))
strDirectory += _T("\\");
int nItem = wndLst1->GetNextItem(-1,LVNI_SELECTED);
CString fileslist = _T("");
pDlg->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)fileslist.GetBuffer(MAX_PATH));
fileslist.ReleaseBuffer();
// Add directory names to list
while((nSelected--) > 0)
{
strItemText = wndLst1->GetItemText(nItem,0);
strItemText = strDirectory + strItemText;
DWORD attr = GetFileAttributes(strItemText);
if((attr != 0xFFFFFFFF) && (attr & FILE_ATTRIBUTE_DIRECTORY))
m_SelectedItemList.Add(strItemText);
nItem = wndLst1->GetNextItem(nItem, LVNI_SELECTED);
}
// Add FILE names to list
strItemText = _T("");
nSelected = wndLst1->GetSelectedCount();
if(nSelected > m_SelectedItemList.GetCount())
{
int MoreThanOnFile = fileslist.Find(_T("\""));
if(MoreThanOnFile != -1)
{
for(int i=0; i<fileslist.GetLength(); i++)
if(fileslist[i] != '\"')
{
strItemText.AppendFormat(_T("%c"),fileslist[i]);
if(fileslist[i-1] == '\"' && fileslist[i] == ' ')
strItemText.Delete(strItemText.GetLength()-1);
}
else if(!strItemText.IsEmpty())
{
m_SelectedItemList.Add((strDirectory+strItemText));
strItemText.Empty();
}
}
else
m_SelectedItemList.Add(strDirectory+fileslist);
}
pDlg->EndDialog(IDOK);
return NULL;
} // if IDOK
}
} // if BN_CLICKED
}// if WM_COMMAND
return CallWindowProc(m_wndProc, hwnd, message, wParam, lParam);
}
#pragma warning( pop )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.