Вернуться наверх
aco.ifmo.ru photonic
вернуться в оглавление предыдущая глава предыдущий параграф следующий параграф следующая глава


5.2. Архитектура документ/представление.

Архитектура "документ/вид" (иногда она еще называется "документ/представление" ) позволяет связать данные их представление на экране. Она реализована в виде классов, котопы создаются мастером AppWizard . Дадим общую характеристику этой архитектуры.

В каркасе MFC -приложения документ - это объект, содержащий данные приложения . Вид (представление) - это оконный объект , обычно связанный с клиентской областью окна на экране, с помощью которого пользователь взаимодействует с данными документа .

Такое логическое разделение данных и их визуального представления позволяет отображать документ разными способами, связав eго с несколькими представлениями. Например, в Microsoft Word доступны три вида отображения одного и того же документа: обычный, разметка страницы, структура документа. Кроме того, изменения, внесенные в одном представлении, отражаются во всех других.

Архитектура "документ/вид" упрощает процесс отображения данных. Вы можете сконструировать свое собственное представление, перегрузив функцию его отображения, обработчики сообщений от клавиатуры, мыши и пунктов меню. А использование готовых представлений, основанных на элементах управления, позволит создать приложение, похожее на Проводник Windows , - с элементами просмотра дерева и списка, которые расположены в разделенном на две части окне. Представление, основанное на поле ввода с форматированием, можно использовать для реализации текстового редактора.

Архитектура "документ/вид" упрощает печать и предварительный просмотр данных; при этом применяется та же функция ображения, что и для вывода информации на экран. В этой архитектуре предусмотрены вспомогательные средства для хранения и открытия документов. Данный процесс, называемый сериализацией , позволяет сохранять данные в формате объекта, используемого Вашим приложением, а также в формате любого другого бъекта, унаследованного от класса CObject .

Архитектура "документ/представление" имеет большое значение, так как обеспечивает каркас множеством возможностей для работы с документами приложения. Однако можно работать с MFC , не применяя ее, так как ее использование ведет к определенному падению производительности и увеличению размера приложения.

В некоторых случаях архитектура "документ/вид" не нужна. Например, для приложения, сжимающего текстовые файлы, требуется только диалоговая панель с полем для ввода названия файла и индикатор выполнения операции. Главное окно и представление не понадобятся, так как преимущества архитектуры "документ/вид" не были бы заметны. В данном случае можно использовать каркас приложения на базе диалогового окна, созданный мастером AppWizard .

AppWizard способен генерировать каркас приложения на основе архитектуры "документ/вид", который в дальнейшем можно изменить.

Этот каркас реализует документы и представления средствами классов, производных от CDocument и CView . Для работы приложения кроме них еще необходимы классы CWinApp , CFrameWnd и CDocTemplate .

В таблице 1 описаны все объекты и связанные с ними классы приложения на базе архитектуры "документ/вид".

Таблица 1. Объекты и связанные с ними классы приложения на базе архитектуры "документ/вид" Объект Класс и его назначение
Документ Производный от CDocument . Определяет данные приложения
Вид (Представление) Производный от CView . Служит для отображения данных и взаимодействия с пользователем
Окно-рамка Производный от CFrameWnd . Представления отображаются внутри таких окон. В SDI -приложениях (однодокументных приложениях) являются главным окном
Шаблон документа Производный от CDocTemplate . Управляет созданием документов, представлений и окон. Один класс шаблона документа отвечает за все открытые документы одного типа
Приложение Производный от CWinApp . Управляет всеми объектами приложения и определяет его действия, в частности, инициализацию и очистку памяти

Все объекты приложения на базе архитектуры "документ/вид" реагируют на действия пользователя совместно, будучи связаны между собой командами и сообщениями.

Дадим краткую характеристику некоторых из перечисленных объектов.

Шаблон документа

Шаблоны документа создаются и управляются объектом приложения. Одна из главных задач, выполняемая функцией InitInstance() , - создание одного или нескольких шаблонов документа соответствующего типа. В следующем примере показаны эти действия в SDI -приложении:

	//Из CMyAppApp::InitInstance()
	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CMyAppDoc),
		RUNTIME_CLASS(CMainFrame),       // главное окно SDI-приложения
		RUNTIME_CLASS(CMyAppView));
	AddDocTemplate(pDocTemplate);

При создании шаблон документа связывает класс документа с ресурсами (меню, значками и т. д.), окном-рамкой и представлением. Шаблон добавляется к приложению средствами функции CWinApp::AddDocTemplate() .

В SDI -приложении пользователь просматривает документ и работает с ним с помощью представления, находящегося в главном окне, производном от CFrameWnd . На рисунке 1 показаны взаимосвязи объектов SDI -приложения.

MDI -приложение использует объект CMultiDocTemplate , которое хранит список открытых документов одного типа. Для создания главного окна в таких приложениях применяются классы, производные от CMDIFrameWnd . Представления же содержатся в дочерних oкнах, которые реализуются средствами класса CMDIChildWnd . Дочерник окна выглядят, как обычные окна-рамки, но располагаются не на рабочем столе, а внутри главного окна приложения. У них нет собственного меню, поэтому они используют меню главного окна, которое автоматически изменяется в зависимости от активного дочернего окна.

В следующем примере показано создание объекта CMultiDocTemplate : //Из CMyAppApp::InitInstance() CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MYMDITYPE, RUNTIME_CLASS(CMyMDIAppDoc), RUNTIME_CLASS(CChildFrame), // дочернее окно MDI-приложения RUNTIME_CLASS(CMyMDIAppView)); AddDocTemplate(pDocTemplate);

Документ

Документ представлен в приложении классом, производным от CDocument . Он сохраняет и загружает данные, а также управляет ими. В нем есть функции для доступа к этим данным и работы с ними. Для взаимодействия между документами и представлениями каждый объект документа содержит список связанных с ним представлений, доступ к которым можно получить через функции CDocument::GetFirstViewPosition() и CDocument::GetNextView() .

Класс CDocument содержит функцию UpdateAllViews() , которая передает всем связанным с документом представлениям уведомление о необходимости перерисовки окна (для этого она вызывает функцию CView::OnUpdate() ).

Приложение должно обновлять представления при любом изменении данных, способном повлиять на их отображение.

Вид (Представление)

Объект вида отвечает за работу с клиентской областью приложения. Он отображает информацию, содержащуюся в документе, и позволяет пользователю вводить данные. С документом разрешено связать несколько представлений, но представление может принадлежать только одному документу. Если мастеру AppWizard не указать специализированное представление, то представление в Вашем приложении будет основано на классе CView . Кроме него существуют еще классы CScrollView (с возможностью прокрутки окна), CListView и CTreeView (позволяют использовать для отображения данных элементы просмотра списка и дерева соответственно).

Фукнция GetDocument() из класса CView позволяет получить указатель, связанный с представлением объекта документа.

В заключение приведем перечень файлов, которые создаются AppWizard при создании SDI -приложения с именем Hello .

Таблица 2. Перечень созданных файлов Название файла Назначение
Hello.clw Файл ClassWizard
Hello.dsw Основной файл рабочей области
Hello.h Заголовочный файл приложения
Hello.cpp Исходный текст приложения
StdAfx.h Заголовочный файл для стандартного "каркаса" приложения
StdAfx.cpp Исходный текст стандартного "каркаса" приложения
MainFrm.h Заголовочный файл главного окна
MainFrm.cpp Исходный текст главного окна
HelloDoc.h Заголовочный файл документа
HelloDoc.cpp Исходный текст документа
HelloView.h Заголовочный файл вида
HelloView.cpp Исходный текст вида
Resource.h Файл с ресурсными константами
Hello.re Файл с ресурсами
Hello.ncb Файл с информацией о представлении и взаимных связях
Hello.dsp Файл проекта
Res Каталог для ресурсов.

AppWizard также создает файл с именем ReadMe.txt , в котором более подробно разъясняется назначение некоторых файлов, созданных AppWizard :

	=====================================================
	MICROSOFT FOUNDATION CLASS LIBRARY : Hello
	=====================================================
	AppWizard создал приложение Hello за вас. Оно не только 
	демонстрирует основные принципы использования классов 
	Microsoft Foundation, но и является отправной точкой для 
	написания вашего собственного приложения.
	
	В этом файле содержится краткое описание всех файлов, 
	составляющих приложение Hello.
	
	hello.h - главный заголовочный файл приложения. Он 
	включает другие  заголовочные файлы проекта (в том 
	числе Resource.h) и объявляет класс приложения CHelloApp.
	hello.cpp - главный файл с исходным текстом приложения, 
	содержащий класс приложения CHelloApp.
	hello.rc   - перечисление всех ресурсов Microsoft Windows, 
	используемых в программе. В их число входят значки, 
	растровые изображения и курсоры, все они хранятся в подкаталоге 
	RES. Данный файл можно, редактировать непосредственно в 
	Microsoft Developer Studio. 
	res\hello.ico - файл с изображением, используемым в качестве 
	значка приложения. Включается в главный ресурсный файл hello.гс.
	res\hello.гс2 - файл содержит ресурсы, не редактируемые в 
	Microsoft Developer Studio. В него следует помещать все ресурсы, 
	для которых отсутствуют специализированные редакторы. 
	hello.сlw - файл содержит информацию, которая используется 
	ClassWizard для модификации существующих или добавления новых классов. 
	ClassWizard также пользуется им для хранения информации, необходимой 
	для создания и модификации схем сообщений и схем данных в окнах 
	диалогов, а также для создания прототипов функций
	//////////////////////////////////////////////////////////////
	 Главное обрамленное окно:
	MainFrm.h, MainFrm.cpp - файлы содержат класс обрамленного окна 
	CMainFrame, производный от CFrameWnd и отвечающий за все аспекты 
	работы с обрамленными окнами в интерфейсе SDI.
	res\Toolbar.bmp - растровый файл содержит изображения значков на 
	панели инструментов. Исходная панель инструментов и строка состояния 
	конструируются в классе CMainFrame. Измените файл вместе с массивом 
	из файла MainFrm.cpp, чтобы добавить новые кнопки на панель инструментов.
	//////////////////////////////////////////////////////////////
	AppWizard создает один тип документа и один вид:
	helloDoc.h, helloDoc.срр - документ. Файлы содержат класс CWelcomeDoc. 
	Отредактируйте их, чтобы внести в документ специфические данные и 
	реализовать сохранение/ загрузку файлов (через CHelloDoc: Serialize).
	helloView.h, helloView. cpp - вид документа. Файлы содержат класс CHelloView. 
	Объекты CHelloView используются для просмотра объектов CHelloDoc.
	//////////////////////////////////////////////////////////////
	Другие стандартные файлы:
	StdAfx.h, StdAfx.cpp - файлы используются для построения предварительно 
	компилированных файлов - заголовочного (РСН) с именем hello.pen, а также 
	файла типов StdAfx.obj.
	Resource.h - стандартный заголовочный файл, в котором определяются 
	идентификаторы новых ресурсов. Microsoft Developer Studio читает этот 
	файл и обновляет его содержимое.
	//////////////////////////////////////////////////////////////
	Примечания :
	AppWizard помечает комментарием "TODO:" те части исходного текста, которые 
	вам следует дополнить или изменить.
	Если ваше приложение использует MFC в виде совместной DLL-библиотеки и его 
	язык отличается от текущего языка операционной системы, вам придется 
	скопировать соответствующую библиотеку с локализованными ресурсами 
	MFC40XXX.DLL с Visual C++ CD-ROM в каталог system или system32 и переименовать 
	ее в MFCLOC.DLL.  (Сокращение "XXX" определяет используемый язык. Например, 
	MFC40DEU.DLL содержит ресурсы, переведенные на немецкий). Если не сделать 
	этого, некоторые элементы пользовательского интерфейса в ваших приложениях 
	сохранят язык операционной системы.
	//////////////////////////////////////////////////////////////