Сначала при помощи средства AppWizard создается шаблон однооконного или многооконного
приложения. При этом генерируются следующие основные классы :
- главный класс
приложения (производный от базового класса
CWinApp );
- класс главного окна
приложения (производный от базового класса
CFrameWnd или CMDIFrameWnd
в зависимости от типа приложения) ;
- класс документа
приложения (производный от базового
CDocument );
- класс окна просмотра документа
(производный от базового CView );
- класс дочернего
MDI-окна
(производный от базового класса
CMDIChildWnd ) - только для
mdi-приложения.
Редактирование документов (и обликов)
В классе документа следует определить элементы (простые переменные,
переменные структурного типа, объекты различных классов и др.), отвечающие за
хранение данных документа, считываемых и записываемых в файл.
Если в процессе работы с документом выделяется дополнительная память для
хранения информации, то в деструкторе класса документа необходимо освободить всю дополнительную память,
полученную в процессе работы.
В тех методах класса окна просмотра документа, где содержимое
документа изменяется, следует выполнить определенные действия :
- объявить указатель
pDoc на текущий
документ и получить его при помощи метода GetDocument класса окна просмотра ;
- изменить графическое изображение документа;
- изменить содержимое документа, на который указывает
pDoc;
- установить флаг изменения документа, вызвав метод
pDoc.SetModifiedFlag(TRUE);
- для
mdi-приложения вызвать метод
pDoc.UpdateAllViews(this) для перерисовки
всех обликов документа (кроме
текущего ), на который указывает
pDoc.
Для класса окна просмотра переопределить метод OnUpdate для того, чтобы выводить в этом методе только последние
изменения, т.к. метод CView::OnUpdate базового класса просто вызывает метод OnDraw для перерисовки всего изображения.
Для восстановления всего изображения в окне просмотра после перекрытия окна
необходимо изменить метод OnDraw класса
окна просмотра документа, добавив вывод всего изображения .
Инициал изация нового документа
Для инициализации нового документа в методе OnNewDocument
класса документа произвести
- вызов метод CDocument::OnNewDocument базового класса для полной подготовки к работе с новым
документом ;
- инициализацию необходимых данных нового документа
;
- выделение необходимой памяти для работы над документом
.
Для очистки содержимого документа при инициализации нового документа в
классе документа необходимо
переопределить метод DeleteContents базового
класса CDocument (этот метод вызывается
методом CDocument::OnNewDocument -
обработчиком открытия нового документа). Для этого в определении класса документа необходимо объявить
виртуальный метод DeleteContents, а в реализации класса его определить. Работа
метода DeleteContents должна заключаться в следующем :
- необходимо освободить всю память, выделяемую в процессе работы над
предыдущим документом
;
- вызвать метод
CDocument::DeleteContents
базового класса для полной очистки документа
Сохранение и восстановл ение документов
Чтобы приложение имело возможность сохранения документов в файле, нужно
изменить метод 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::On OpenDocument базового класса документов он может использовать
переопределения этих методов OnSaveDocument и On OpenDocument в своем классе документа .
В переопределенном уже ранее методе On OpenDocument класса документа (см. выше) вместо
вызова по умолчанию метода базового класса
CDocument::OnOpenDocument(pszPathName)) следует:
DeleteContents;
объявить объект file класса CFile
или производного от него ;
открыть для объекта file файл с именем
pszPathName (передается в метод в качестве параметра) в режиме
"для чтения ";
считать данные из файла file и
разместить их в элементах класса документа.
Изменить в методах OnFileSaveAs и OnFileSaveAs (см. выше) вызовы метода
CDocument:: OnSaveDocument на вызовы
OnSaveDocument. Затем переопределить метод On SaveDocument в классе документа приложения, для чего в
определении класса документа необходимо объявить виртуальный метод On
SaveDocument, а в реализации класса документа
необходимо его определить. Причем в переопределенном методе On
SaveDocument выполнить следующие действия
:
- объявить объект
file класса CFile
или производного от него ;
- открыть для объекта
file файл с именем
pszPathName в режиме для
"записи" ;
- записать данные из элементов класса документа в файл
file.
|