Визуальное программирование и MFC

       

Сохранение и восстановление документов


Чтобы приложение имело возможность сохранения документов в файле, нужно изменить метод Serialize класса документа. Метод Serialize вызывается всякий раз, когда надо сохранить документ в файле на диске или загрузить его из существующего файла. В методе Serialize необходимо определить, как он должен сохранять и восстанавливать документы приложения.

Использование стандартных диалогов выбора файлов

Для того, чтобы иметь возможность при открытии и сохранения документа на диске использовать стандартные диалоговые панели выбора файла с определенными программистом настройками, необходимо в приложении обработать командные сообщения с идентификаторами ID_FILE_OPEN, ID_FILE_SAVE, ID_FILE_SAVE_AS (следует отметить, что обработка этих сообщений должна происходить в разных классах приложения – см. ниже).

В класс документа необходимо добавить элемент BOOL status_new, принимающий значение TRUE, если пользователь работает с новым документом, и значение FALSE, если пользователь открыл документ, содержащийся в файле на диске. В методе OnNewDocument класса документа необходимо присвоить элементу status_new значение TRUE.

При помощи средства ClassWizard добавить в главный класс приложения (наследованный от класса CWinApp) обработчик командного сообщения с идентификатором ID_FILE_OPEN. Используемый ранее по умолчанию обработчик CWinApp::OnFileOpen этого сообщения убрать из списка обрабатываемых сообщений:

BEGIN_MESSAGE_MAP(CApp, CWinApp) …… ON_COMMAND(ID_FILE_OPEN, OnFileOpen) …… END_MESSAGE_MAP()

Изменить заготовку метода OnFileOpen главного класса приложения следующим образом:

void CApp::OnFileOpen() { // Создание стандартной панели выбора файла "Open" CFileDialog DlgOpen(TRUE,(LPCTSTR)"txt",NULL, OFN_HIDEREADONLY,(LPCSTR)" Text Files (*.txt) |*.txt");

// Отображение стандартной панели выбора файла "Open" if(DlgOpen.DoModal()==IDOK) { // Создание объекта класса документа, связанного с // файлом, и его окна просмотра. // OpenDocumentFile - метод класса CWinApp CDocument *pDoc =OpenDocumentFile(DlgOpen.GetPathName());


// Чтение данных из файла и запись их // в элементы класса документа. pDoc->OnOpenDocument(DlgOpen.GetPathName()); } }

В классе документа переопределить метод OnOpenDocument базового класса CDocument. Для этого в определении класса документа необходимо объявить виртуальный метод OnOpenDocument, а в реализации класса документа необходимо его определить:

BOOL CDoc::OnOpenDocument( const char* pszPathName) { // Вызов метода базового класса. // Он сначала вызывает метод DeleteContents для очистки документа, // а затем метод Serialize для чтения данных из файла if(!CDocument::OnOpenDocument(pszPathName)) return FALSE;

// Инициализация необходимых данных класса, выделение // памяти аналогично методу OnNewDocument . . . . . . .

status_new=FALSE; // документ не новый return TRUE; }

При помощи средства ClassWizard добавить в класс документа обработчики командных сообщений с идентификаторами ID_FILE_SAVE и ID_FILE_SAVE_AS. Изменить заготовки методов-обработчиков следующим образом:

void CDoc::OnFileSave() { if(status_new==TRUE) // если документ новый, то выбор имени файла { // Создание стандартной панели выбора файла "SaveAs" CFileDialog DlgSave(FALSE,(LPCSTR)"txt",GetTitle(), OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, (LPCSTR)" Text Files (*.txt) |*.txt");

// Отображение стандартной панели выбора файла "SaveAs" if(DlgSave.DoModal()==IDOK) { SetPathName(DlgSave.GetPathName());



// Вызов метода базового класса. // Он вызывает метод Serialize для записи данных CDocument::OnSaveDocument(DlgSave.GetPathName());

status_new=FALSE; // документ уже не новый } } else // Вызов метода базового класса. CDocument::OnSaveDocument(GetPathName()); } void CDoc::OnFileSaveAs() { // Создание стандартной панели выбора файла "SaveAs" CFileDialog DlgSaveAs(FALSE,(LPCSTR)"txt",GetTitle(), OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, (LPCSTR)" Text Files (*.txt) |*.txt");

// Отображение стандартной панели выбора файла "SaveAs" if(DlgSaveAs.DoModal()==IDOK) { SetPathName(DlgSaveAs.GetPathName());



// Вызов метода базового класса. // Он вызывает метод Serialize для записи данных CDocument::OnSaveDocument(DlgSaveAs.GetPathName());

status_new=FALSE; // документ уже не новый } }



Запись и восстановление данных без помощи фрхивных файлов



Если программист не желает производить запись и восстановление документов при помощи архивных файлов и с использованием метода Serialize, то вместо использования в приложении методов CDocument::OnSaveDocument и CDocument::OnOpenDocument базового класса документов он может использовать переопределения этих методов OnSaveDocument и OnOpenDocument в своем классе документа.

В переопределенном уже ранее методе OnOpenDocument класса документа (см. выше) вместо вызова по умолчанию метода базового класса CDocument::OnOpenDocument(pszPathName)) следует:

  • вызвать метод DeleteContents;


  • объявить объект file класса CFile или производного от него;


  • открыть для объекта file файл с именем pszPathName (передается в метод в качестве параметра) в режиме "для чтения";


  • считать данные из файла file и разместить их в элементах класса документа.


  • Изменить в методах OnFileSaveAs и OnFileSaveAs (см. выше) вызовы метода CDocument::OnSaveDocument на вызовы OnSaveDocument. Затем переопределить метод OnSaveDocument в классе документа приложения, для чего в определении класса документа необходимо объявить виртуальный метод OnSaveDocument, а в реализации класса документа необходимо его определить. Причем в переопределенном методе OnSaveDocument выполнить следующие действия:

  • объявить объект file класса CFile или производного от него;


  • открыть для объекта file файл с именем pszPathName в режиме для "записи";


  • записать данные из элементов класса документа в файл file.



  • Содержание раздела