C++ MFC 保存文件对话框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5975224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:16:28  来源:igfitidea点击:

MFC Save file dialog

c++filemfcdialog

提问by Adrian Marinica

I am writing an MFC C++application that has a Save As button for saving a .txtfile to the disc. With it I am trying to add an extra verification for file overwriting (if a file with the same filename exists, then it should query the user if he wants to overwrite the old file or not). I have tried this with the below code, but it doesn't really work. When I click No on the MessageBox, it should reopen the Save As file dialog, but instead it gives me two errors: the first one is Debug assertion failed, and the second one is Encountered an improper argument. How should I do this better? This is the code:

我正在编写一个MFC C++应用程序,它有一个用于将.txt文件保存到光盘的另存为按钮。有了它,我试图为文件覆盖添加额外的验证(如果存在具有相同文件名的文件,那么它应该询问用户是否要覆盖旧文件)。我已经用下面的代码尝试过这个,但它并没有真正起作用。当我在 MessageBox 上单击 No 时,它应该重新打开 Save As file 对话框,但它给了我两个错误:第一个是Debug assertion failed,第二个是Encountered an improper argument。我应该如何更好地做到这一点?这是代码:

char strFilter[] = { "Text Files (*.txt)|*.txt|" }; 

    CFileDialog FileDlg(FALSE, CString(".txt"), NULL, 0, CString(strFilter)); 

    while(true)
    {
        if( FileDlg.DoModal() == IDOK ) // this is the line which gives the errors
        {
            agendaName = FileDlg.GetFileName(); //filename
            agendaPath = FileDlg.GetFolderPath(); //filepath (folders)

            if(model->agendaExists(CSToString(agendaPath+TEXT("\")+agendaName))) // there is another file called the same way
            {
                if(MessageBox(TEXT("A file with the specified name already exists. Overwrite?"), TEXT("File exists"), MB_YESNO) != 6) // user clicked NO (do not overwrite file)
                {
                    continue;
                }

            }

            model->sendToFile(CSToString(agendaPath+TEXT("\")+agendaName));  // the file is unique so the agenda named agendaName found at path agendaPath is saved
            return;
        }
    }

It should be mentioned that the errors occur on line 7 and only on the second loop through the while.

应该提到的是,错误发生在第 7 行,并且仅发生在通过while.

回答by Marius Bancila

CFileDialog can detect itself if a file exists and prompt the user for overwriting.

CFileDialog 可以检测自己是否存在文件并提示用户进行覆盖。

explicit CFileDialog(
   BOOL bOpenFileDialog,
   LPCTSTR lpszDefExt = NULL,
   LPCTSTR lpszFileName = NULL,
   DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
   LPCTSTR lpszFilter = NULL,
   CWnd* pParentWnd = NULL,
   DWORD dwSize = 0
);

Just pass OFN_OVERWRITEPROMPT for the flags.

只需为标志传递 OFN_OVERWRITEPROMPT 即可。

As for your problem, run in Debugger and when you get that assertion press the Retry button to see where the problem comes from (you'll probably have to look through the call stack also). Maybe you should try putting this in the while loop:

至于您的问题,请在 Debugger 中运行,当您获得该断言时,请按“重试”按钮查看问题出在哪里(您可能还需要查看调用堆栈)。也许您应该尝试将其放入 while 循环中:

CFileDialog FileDlg(FALSE, CString(".txt"), NULL, 0, CString(strFilter)); 

回答by MikMik

You should use the OFN_OVERWRITEPROMPTflag in the constructor. That flag is usually one of the default flags, but you have set your flags to 0. So, if you do:

您应该OFN_OVERWRITEPROMPT在构造函数中使用该标志。该标志通常是默认标志之一,但您已将标志设置为 0。因此,如果您这样做:

CFileDialog FileDlg(FALSE, CString(".txt"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(strFilter));

if (FileDlg.DoModal() == IDOK)  
{  
    model->sendToFile(CSToString(FileDlg.GetPathName()));
}

It should work. By the way, GetPathName()gets the full path to the selected file, so you don't need to get the folder and the file name in 2 steps.

它应该工作。顺便说一句,GetPathName()获取所选文件的完整路径,因此您无需分两步获取文件夹和文件名。

回答by Ankur

Try including below line inside the while loop (as first line in while loop)

尝试在 while 循环中包含以下行(作为 while 循环中的第一行)

CFileDialog FileDlg(FALSE, CString(".txt"), NULL, 0, CString(strFilter));

This line is outside the while loop in your code

此行在代码中的 while 循环之外