Диалог сохранения файла MFC - PullRequest
5 голосов
/ 12 мая 2011

Я пишу MFC C ++ приложение, которое имеет кнопку Сохранить как для сохранения файла .txt на диск. С его помощью я пытаюсь добавить дополнительную проверку для перезаписи файла (если существует файл с таким же именем файла, он должен запросить пользователя, хочет ли он перезаписать старый файл или нет). Я пробовал это с приведенным ниже кодом, но это на самом деле не работает. Когда я нажимаю «Нет» в MessageBox, он должен снова открыть диалоговое окно «Сохранить как файл», но вместо этого он выдаёт мне две ошибки: первая - 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.

Ответы [ 3 ]

8 голосов
/ 12 мая 2011

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 для флагов.

Что касается вашей проблемы, запустите в отладчике и когдаВы получите это утверждение, нажав кнопку «Повторить», чтобы увидеть, откуда возникла проблема (вам, вероятно, придется также просмотреть стек вызовов).Может быть, вы должны попробовать поместить это в цикл while:

CFileDialog FileDlg(FALSE, CString(".txt"), NULL, 0, CString(strFilter)); 
3 голосов
/ 12 мая 2011

Вы должны использовать флаг 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 голос
/ 12 мая 2011

Попробуйте включить нижнюю строку внутри цикла while (как первую строку в цикле while)

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

Эта строка находится вне цикла while в вашем коде

...