我正在编写一个 MFC C ++ 应用程序,它有一个“另存为”按钮,用于将.txt
文件保存到光盘。有了它,我试图为文件覆盖添加额外的验证(如果存在具有相同文件名的文件,那么它应该查询用户是否要覆盖旧文件)。我用下面的代码试过这个,但它确实不起作用。当我在MessageBox上单击No时,它应该重新打开另存为文件对话框,但它会给我两个错误:第一个是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;
}
}
应该提到的是,错误发生在第7行,而且只发生在while
的第二个循环上。
答案 0 :(得分:8)
如果文件存在,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
);
只需传递OFN_OVERWRITEPROMPT作为标志。
至于你的问题,在Debugger中运行,当你得到那个断言时,按Retry按钮查看问题的来源(你可能还需要查看调用堆栈)。也许你应该尝试把它放在while循环中:
CFileDialog FileDlg(FALSE, CString(".txt"), NULL, 0, CString(strFilter));
答案 1 :(得分:3)
您应该在构造函数中使用OFN_OVERWRITEPROMPT
标志。该标志通常是默认标志之一,但您已将标志设置为0.因此,如果您执行以下操作:
CFileDialog FileDlg(FALSE, CString(".txt"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(strFilter));
if (FileDlg.DoModal() == IDOK)
{
model->sendToFile(CSToString(FileDlg.GetPathName()));
}
它应该工作。顺便说一句,GetPathName()
获取所选文件的完整路径,因此您无需分两步获取文件夹和文件名。
答案 2 :(得分:1)
尝试在while循环中包含下面的行(作为while循环中的第一行)
CFileDialog FileDlg(FALSE, CString(".txt"), NULL, 0, CString(strFilter));
此行位于代码中的while循环之外