C++ MFC CFileDialog won't save - c++

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.

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.

QFile: directory not found

I need to write a console application that takes a file, it opens it, and then it calls another procedure based on the information inside the text file.
The only problem is that QFile::errorString() returns:
No such file or directory.
I have been using this implementation in all the programs I had to, and yes, the file exists at that directory.
The code is:
QFile fileName("D:/file.txt");
QString read_from_file;
if(fileName.open(QIODevice::ReadOnly)){
QTextStream in(&fileName);
while(!in.atEnd())
{
read_from_file = in.readLine();
qDebug()<<read_from_file;
}
fileName.close();
}
qDebug()<<fileName.errorString();
Make sure that the file really exists.
QFile::exists("D:/file.txt") – This will return true if the file exists.
QDir("D:/").entryList() – This will return the list of the files and directories located at the specified path; the needed file should be in the list.
As you pointed out in the comments, the problem was the hidden file extensions on Windows.
Open Folder Options by clicking the Start button, clicking Control Panel, clicking Appearance and
Personalization, and then clicking Folder Options.
Click the View tab, and then Advanced settings <...>
To show file name extensions, clear the Hide extensions for known file
types check box, and then click OK.

How to select specific file using CfileDialog in MFC

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);

How can I add text to the file I create using IFileOperation?

I looked at the MSDN samples for IFileOperation, and they show how to create a file, but I don't want to create a blank file, I want to add some text in it. Here's what I have from the sample:
IFileOperation *pfo;
HRESULT hr = CreateAndInitializeFileOperation(IID_PPV_ARGS(&pfo));
if (SUCCEEDED(hr))
{
hr = pfo->NewItem(psiFolder, FILE_ATTRIBUTE_NORMAL, c_szFileName, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = pfo->PerformOperations();
}
pfo->Release();
}
In the pfo->NewItem call, the fourth parameter is for the template, but I don't want to define a template.I want to create a .Url file with the content:
[InternetShortcut]
URL=www.google.com
I can't even seem to control the format of the file, let alone the content. Please help!
IFileOperation::NewItem lets you access the functionality of the 'ShellNew' menu (the menu you get if you right-click in a folder, and select New from the context menu). It's designed to let you make a folder or an empty file, or create a new file from a pre-existing template. It doesn't let you make a file containing arbitrary data.
Once you've created a new empty file you could open it using CreateFile() and write your data to it using WriteFile(). But note that CreateFile() could create the file for you as well - there's really no need to use IFileOperation simply to create an empty file (unless you need its support for UAC to create the file in a protected location, but in that case you'll have trouble writing to it afterwards).

How can I set the default file type for a CFileDialog?

I am using CFileDialog for displaying the open file dialog. I have set the filter as follows:
static TCHAR BASED_CODE szFilter[] = _T("Chart Files (*.xlc)|*.xlc|")
_T("Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|")
_T("*.xlc; *.xls|All Files (*.*)|*.*||");
I need to set the default file type to be "Worksheet Files" whenever I DoModal the dialog box. I am unable to figure out how to do it. MS Paint is doing, it selects the "All Picture files" when we open the open file dialog.
Please let me know how to do it.
You're looking for the SetDefExt function. This allows you to specify the default file extension for an open/save file dialog box. Remember that the string you specify should not contain a period (.).
Of course, you could also just specify this in the constructor. The second parameter is the default extension (lpszDefExt).
You should read and write
This code will do the job during the run time of your program. To be able to display the last used selection next time you run your program, you can store the value of LastIndex in the Registry.
// A dialog box with several filters for various media file types
static int LastIndex = -1; // Holds the last used filter. You can store it in the Registry to use it during next run.
const TCHAR szFilter[] = _T("Video Files (*.mpg, *.mov, *.mp4)|*.mpg;*.mov;*.mp4|Audio Files (*.wav, *.mp3, *.m4a, *.flac)|*.wav;*.mp3;*.m4a;*.flac|MXF Files (*.mxf)|*.mxf|All Files (*.*)|*.*||");
CFileDialog dlg(TRUE, _T("Select Media File"), NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, szFilter, this);
if(LastIndex != -1) dlg.m_ofn.nFilterIndex = LastIndex; // restore last used index
// from last time
if (dlg.DoModal() == IDOK)
{
LastIndex = dlg.m_ofn.nFilterIndex; // Store last used index for next time
CString sFilePath = dlg.GetPathName();
}