How to select specific file using CfileDialog in MFC - c++

I would like to open a file dialog and allow user to select only the file with name "myapplication.ini" and user can only browse folder's to check if the file is existing to select it.
so i came across CFileDialog which would do almost what i want other than limiting it to display only files with name "myapplication.ini"
currently my usage of CFiledialog
CFileDialog FileDialog(TRUE,"features.ini", NULL,OFN_HIDEREADONLY,NULL);
I am not sure what could should be changed to make it work as i expected.

That sounds like a poor UI. Even if you filter out all but that file, the user can override the filter. If you aren't going to allow the user to make a choice of file name, why ask them for their choice?
What you are actually doing, in my view, is asking the user to select a folder. So instead of the file dialog, show them a folder selection dialog, CFolderPickerDialog.

Declare the filter string like this:
static TCHAR BASED_CODE szFilter[] = _T("features.ini (features.ini)|features.ini|");
and then pass it to your CFileDialog ctor:
CFileDialog FileDialog(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter);

Related

IFileDialog Overwrite File and Open Folder/File

I have two issues related to IFileSaveDialog & IFileOpenDialog I did not managed to find a solution for, I hope you can help me.
When the user is saving a file with an existing name, the "Confirm Save As" prompt appears. I need the "Yes" option to be marked as default instead of "No".
The User can open/load a file or a folder from the same dialog.
Can these be done with this API? Or maybe other API?
I tried to google it and go over Microsoft documentation to find a solution, but with no luck.
When the user is saving a file with an existing name, the "Confirm Save As" prompt appears. I need the "Yes" option to be marked as
default instead of "No".
As #Remy Lebeau said that, you can use IFileDialogEvents::OnOverwrite method. And use MessageBox to create a suitable dialog.
Some code:
IFACEMETHODIMP OnOverwrite(IFileDialog* , IShellItem*psi, FDE_OVERWRITE_RESPONSE* response) {
int msgboxID = MessageBox(
NULL,
(LPCWSTR)L"Windows already exists, \n\rDo you want to replace it?",
(LPCWSTR)L"Confirm Save As",
MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1
);
switch (msgboxID)
{
case IDYES:
*response = FDEOR_ACCEPT;
break;
case IDNO:
*response = FDEOR_REFUSE;
break;
}
return S_OK;
}
Debug:
The User can open/load a file or a folder from the same dialog. Can
these be done with this API? Or maybe other API?
There is no such method in the document, you can only select a folder or file.
As a compromise, I suggest that you can create a new MessageBox and set two buttons in it, namely "select folders" and "select files". When the user selects folders, folder dialog with the FOS_PICKFOLDERS style is opened. Otherwise, Files is selected by default.

QFileDialog: add suffix after selecting file

I need to add suffix to selected filename in QFileDialog with QFileDialog::AcceptSave accept mode. For example, after selecting "1.txt" file in QFileDialog edit should be select "1_suffix.txt". It should be added before file accepting, because I need the user to have the ability to change the filename before applying file.
code:
m_dialog.setAcceptMode(QFileDialog::AcceptSave);
m_dialog.setWindowModality(Qt::WindowModal);
m_dialog.setFileMode(QFileDialog::AnyFile);
m_dialog.setDefaultSuffix("_suffix");
if(m_dialog.exec() == QFileDialog::Accept)
{
setPath(m_dialog.selectedFiles()[0]);
}
Usually, a QFileDialog is displaying the platform file dialog. To get the behavior you want, you'd need to use platform-specific mechanisms; Qt doesn't implement such functionality.
If you're using the non-native file dialog, you could inspect its structure to find the widget(s) you're after, filter relevant events on them, and inject the behavior you need.
Try extending QFileDialog and subscribe to QFileDialog signals
void fileSelected(QString file)
void currentChanged(QString path)
It can be a start.

C++ MFC CFileDialog won't save

I created a MFC programm with a menu option to Save a file. When I click it it shows the CFileDialog and I can choose the location where I want to save my file. When I Click save in the Dialog, it closes the dialog, but after that it does nothing. AND it didn't save my file. What am I doing wrong?
Here is the code
CFileDialog *dlg = new CFileDialog(FALSE, L"dr", NULL, NULL,
L"Drawings (*.dr)|*.dr|"
L"All Files||");
bool result = dlg->DoModal();
if(result)
{
MessageBox(0, dlg->GetPathName(), L"Draw", 0);
}
The bool result, is purely there to check if there is no problem/error.
The file save dialog is called "file save dialog" because its caption says "Save File" and it allows you to only select a single file. That does not mean that it actually does any saving of files. It just returns to you the filename selected by the user. You are still responsible for writing the code which will save your file using this filename.
The CFileDialog does not save the file for you, it only provides you with a dialog for the user to determine where (and if!) the file should be saved. The return value of DoModal() should be compared to IDOK before proceeding to save. From the dialog's member functions you can get the path and filename the user selected. With that, you can create/open a file and save your data.

Issues with CFileDialog for multiple file selection

I'm using the following code to retrieve multiple file selection via UI:
CFileDialog fd(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,
NULL, hParentWnd ? CWnd::FromHandle(hParentWnd) : NULL);
fd.m_pOFN->Flags |= OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_NODEREFERENCELINKS;
int nLnBuff = 32767;
TCHAR* pBuffFileSelect = new TCHAR[nLnBuff];
memset(pBuffFileSelect, 0, nLnBuff * sizeof(TCHAR));
fd.m_ofn.lpstrFile = pBuffFileSelect;
fd.m_ofn.nMaxFile = nLnBuff;
if(fd.DoModal() == IDOK)
{
POSITION fileNamesPosition = fd.GetStartPosition();
while(fileNamesPosition != NULL)
{
CString strSelPath = fd.GetNextPathName(fileNamesPosition);
TRACE("path: %s\n", CStringA(strSelPath));
}
}
delete[] pBuffFileSelect;
So when I try it on my PC, I run the method above and when the "Open File" dialog open up, just as a test, I navigated to my desktop and selected all files using Ctrl+A shortcut and then clicked Open. As a result I started getting the following paths:
The first path is a link, which is correct (it exists on my Public desktop):
"C:\Users\Public\Desktop\avp.lnk"
But then the second path is wrong. It gives me:
"C:\Users\Public\Desktop\1.txt"
when it's supposed to be (for the desktop that I picked):
"C:\Users\UserName\Desktop\1.txt"
and then every consecutive path has "Public" instead of "UserName".
I should point out that I have several user accounts set up on this PC and the one that I'm testing this method from is a Standard user account. The app that I'm running this method from is not running elevated (or with regular user privileges) so it should not have access to other user accounts anyway.
So what am I doing wrong here?
Checked the sources, and GetOpenFileName assumes that all the items are in fact in the same file path. This isn't true for the Desktop (there are items in different paths merged into one shell view), and so you'll see the bad behavior.
The solution is to use the Common Item dialogs, which use the shell namespace rather than file system paths. All the desktop items are in a common shell path, and then you can use IShellItem::GetDisplayName to convert to a file system path.
Unfortunately, MFC doesn't have a wrapper for the common item dialog, so you'll have to manage that yourself.

Allowing IFileOpenDialog to pick a folder that doesn't exist yet

I'm trying to create a dialog to select a new folder to save files into. The IFileOpenDialog class works great except that it won't allow a new folder to be picked.
I.e. "Folder: C:\existings\new-folder" in the bottom of the dialog pops up the following message:
new-folder
Path does not exist.
Check the path and try again.
Here's the code I've got:
IFileDialog* fileDialog
CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&fileDialog));
DWORD options;
fileDialog->GetOptions(&options);
options &= ~FOS_FILEMUSTEXIST;
options &= ~FOS_PATHMUSTEXIST;
fileDialog->SetOptions(options | FOS_PICKFOLDERS);
fileDialog->Show(parentWindow);
Any pointers or hacks would be appreciated! Thanks!
To quote Michael from this other question:
[To head off some comments, the SHBrowseForFolder API still exists, but is still not an acceptable solution for our UI deciders.]
The same applies here...
I think you want to use CLSID_FileSaveDialog instead of CLSID_FileOpenDialog. And possibly make use of IFileSaveDialog in addition to the base class IFileDialog.
As you're selecting a folder, you could use the folder picker dialog.
This, with the right flags, has a "create" button at the bottom and a text entry allowing you to specifiy a non existant path.