Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Технологии программирования. Программирование графических интерфейс

.pdf
Скачиваний:
3
Добавлен:
15.11.2022
Размер:
2.24 Mб
Скачать

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

1. Cоздать класс объектов, с которыми будет работать приложение:

class CMyClass : public CObject

{

protected:

DECLARE_SERIAL(CMyClass) <данные – члены класса> public: <методы – члены класса>

virtual void Serialize(CArchive &ar);

}; 2. Определить в классе документа контейнер (коллекцию)

для хранения объектов, например :

class CMyPrDoc: public CDocument() {…

CTypePtrMap<CMapStringToOb, CString, CMyClass *>CMap;

}; 3. Переопределить в классе документа методы (в случае

необходимости)

virtual BOOL OnNewDocument();

virtual BOOL OnOpenDocument(LPCTSTR lpszPathName); virtual BOOL OnSaveDocument(LPCTSTR lpszPathName); virtual void DeleteContents();

virtual void Serialize(CArchive &ar);

Метод OnNewDocument() вызывается средой выполнения при создании нового документа как часть выполнения команды File/New. По умолчанию реализация этого метода вызывает метод DeleteContens() для удаления данных документа, а затем помечает документ как «чистый».

При переопределении метода следует вызывать метод OnNewDocument() базового класса для выполнения стандартный действий. Как правило, переопределение метода заключается в инициализации нового документа: для SDI-приложения – это

121

переинициализация уже существующего документа, а для MDIприложений – инициализация нового документа.

Пример 5

BOOL CMyPrDoc :: OnNewDocument() { if (!CDocument :: OnNewDocument())

return FALSE; CFile file;

CFileException except;

CString fn=AfxGetApp()->GetProfileString(“Recent File

List”, “File1”);

/* эта функция возвращает значение строки с именем File1 из секции с именем Recent File List реестра. Таким образом, получаем имя последнего открывавшегося файла.

if (!file.Open(fn, CFile :: modeReadWrite, &except)) if (except.m_cause==CFileException :: fileNotFound) AfxMessageBox(“файл”+fn+”не найден”);

else

AfxMessageBox(“ошибка открытия файла”+fn); return FALSE;

}

//связываем архив с файлами

CArchive ar(&file, CArchive : load); Serialize(ar); //чтение файла

UpdateAllViews(NULL); return TRUE;

}

Метод UpdateAllViews() вызывается видом после изменения документа. Этот метод инициирует для каждого отображение вызов методов CView :: OnUpdate(). В свою очередь, метод OnUpdate() по умолчанию отмечает всю клиентскую область как поврежденную и инициирует сообщение WM_PAINT.

Метод OnOpenDocument() вызывается средой выполнения при открытии нового документа, например, как часть вы-

122

полнения команды File/Open. По умолчанию реализация этого метода открывает указанный файл, вызывает метод DeleteContents(), затем вызывает метод Serialize() для чтения файла и помечает документ как «чистый».

Этот метод может быть переопределен для реализации других механизмов управления данными, без использования архива, а также для определения дополнительного кода инициализации.

Метод OnSaveDocument() вызывается средой выполнения при сохранении документа, например, как часть выполнения команд File/Save или File/Save As. По умолчанию реализация открывает указанный файл, вызывает метод Serialize() для записи данных из документа в файл и помечает документ как «чистый».

Этот метод может быть переопределен для реализации других механизмов управления данными, а также определения дополнительного кода для сохранения данных.

Метод DeleteContents() вызывается средой выполнения для удаления данных объекта без разрушения самого объекта. Метод может также вызываться для очистки содержимого документа с целью повторного использования или для реализации команды Edit/Clear All.

Реализация этого метода по умолчанию не выполняет никаких действий.

Пример 6

void CMyPrDoc :: DeleteContents()

{

cMap.RemoveAll()

CDocument :: DeleteContents();

}

4. Реализовать класс отображения.

Как уже указывалось, класс отображения может быть создан на основе различных базовых классов. В зависимости от этого могут быть предложены различные методики реализации отображения документа. Рассмотрим некоторые из них.

123

Класс отображения создан на основе класса CView class CMyPrView : public CFormView

Класс CFormView является базовым классом, используемым для отображений, содержащих элементы управления. Он поддерживает работу с оконными формами с их прокруткой (используя возможности класса CScrollView).

Создание отображения CFormView аналогично созданию диалогового окна. Надо сделать следующее:

1)Разработать в редакторе диалога шаблон диалогового окна и установить для него следующие атрибуты:

– на панели Style выбрать Child (WS_CHILD вкл.);

– на панели Border выбрать None (WS_BORDER откл.);

– снять флажок Visible (WS_VISIBLE откл.);

– снять флажок Titebar (WS_CAPTION откл.).

2)Используя ClassWizard, добавить в класс отображения переменные для обмена данными с элементами управления диалоговых окон (формой).

ClassWizard формирует функцию DoDataExchange(), добавив в нее соответствующие DDX_ и DDV_ функции.

3)Переопределить метод OnUpdate(). Этот метод определен

вклассе CView и вызывается для обновления отображения окнаформы. При использовании DDX_ функций (методов) можно вызвать метод CWnd :: UpdateData(FALSE). При первичной инициализации отображения вызывается метод OnInitialUpdate(). В классе CFormView этот метод переопределен таким образом, что он выполняет вызов DDX_ методов, устанавливающих первоначальное значение элементов управления.

4)Реализовать методы, выполняющие внесение изменений из отображения в документ. При использовании DDX_ методов следует вызвать метод CWnd :: UpdateData(TRUE) для занесения изменений в переменные класса отображения, а затем, используя значения этих переменных, вносить изменения в документ.

При изменении документа следует вызвать метод

void CDocument :: SetModifiedFlag(BOOL bModified=TRUE);

124

При вызове этого метода с параметром TRUE документ помечается как измененный. Это гарантирует, что перед закрытием документа среда выполнения выдаст пользователю запрос о сохранении сделанных изменений.

Вызов метода с параметром FALSE помечает документ как «чистый» (без изменений).

Класс отображениясоздан на основеклассаCListView.

Если в предыдущем случае для ввода и отображения данных использовались элементы управления окна-формы, то в этом случае для ввода и отображения данных необходимо создавать специальные диалоговые окна. Впрочем, и в предыдущем случае можно создавать эти окна, которые будут активизироваться кнопками в окне-форме (окне вида).

Как в этом случае реализуется диалог? Надо сделать следующее:

1)Разработать в редакторе диалога шаблоны диалоговых окон, например, окна для создания объекта, просмотра объектов, редактирования и т.д.

2)Создать классы диалогов. Для этого, находясь в редакторе ресурсов с открытым шаблоном диалогового окна, вызвать ClassWizard, а затем вызвать команду Add Class.

3)Используя ClassWizard, добавить в классы диалогов переменные для обмена информацией с элементами управления диалоговых окон.

4)В классы отображения добавить переменные – члены класса для хранения объектов, например, ссылку на встроенный список, отображающий наши объекты, хранящиеся в документе (в контейнере map):

CListCtrl &cList;

CMyPrDoc *pDoc; //указатель на документ – для удобства.

5)Определить обработчики событий команд меню для работы сдокументом (добавитьобъект, редактировать объект ит.д.).

6)При необходимости определить обработчики событий от кнопок диалоговых окон.

125

Как получить доступ к документу в объекте диалого-

вого окна? Это можно сделать следующим образом:

1) В классе диалогового окна ввести переменные CMyPr-

View *pView; CMyPrDoc *pDoc.

2) В этом же классе определить конструктор CViewDia-

log(CMyPrView *).

3) Реализовать этот конструктор: CViewDialog :: CViewDialog(CMyPrView *p) :

CDialog(CViewDialog :: IDD, P)

{ pView=p; pDoc=p->GetDocument();

}

4) Вызвать диалог:

void CMyPrView :: OnView()

{

CViewDialog dlg (this);

Dlg.DoModal();

}

7.7. Пример создания приложения с архитектурой «документ–вид»

1.Создайте рабочую область (workspace).

2.В этой рабочей области создайте проект как приложение MFC AppWizard(exe). Выберите тип приложения SDI. Включите поддержку архитектуры Document/View.

3.На 6-м шаге мастера MFC AppWizard выберите базовый класс для класса вида.

4.Создайте класс объектов, с которыми будет работать ваше приложение.

5.Определите в классе документа поле – коллекцию для хранения ваших объектов.

6.Переопределите в классе документа методы (в случае необходимости):

126

virtual BOOL OnNewDocument( );

virtual BOOL OnOpenDocument( LPCTSTR lpszPathName ); virtual BOOL OnSaveDocument( LPCTSTR lpszPathName ); virtual void DeleteContents( );

virtual void Serialize( CArchive& ar );

7.Реализуйте класс отображения. Реализация этого класса зависит от выбранного базового типа. Например, если для отображения вы используете диалоговые окна (класс CFormView либо класс CView с диалогом CDialog для просмотра объектов), создайте в редакторе диалога шаблон диалогового окна с элементамиуправленияи ассоциируйте его склассом диалога.

8.Используя ClassWizard, добавьте в класс отображения (или диалога) переменные для обмена данными с элементами управления формы(диалогового окна).

9.Добавьте в меню пункты «Добавить объект» и «Просмотреть объекты».

10.Разработайте в редакторе диалога шаблон диалогового окна для ввода данных при создании объекта.

11.Создайте класс диалога, ассоциированный с этим шаблоном диалогового окна.

12.Используя ClassWizard, добавьте в класс диалога переменные для обмена данными с элементами управления диалогового окна.

13.Создайте обработчик сообщения «Добавить объект». Данные вводятся с диалогового окна, создается объект и добавляется в коллекцию.

14.Создайте обработчик сообщения «Просмотреть объекты». Объекты просматриваются в окне вида.

15.Переопределите функцию Serialize() для документа.

16.Отладьте программу и сохраните в файле коллекцию, содержащую не менее пяти объектов.

Методические указания

1. Если в качестве базового класса вида выбран класс CView, то класс вида имеет обработчики команд меню «Добавить объект»

127

и «Просмотреть объекты». Соответствующие диалоговые окна имеютвид(рис. 7.3).

а

б

Рис. 7.3

2. Если в качестве базового класса вида выбран класс CFormView, то класс вида может содержать управляющие элементы для просмотра объектов. Можно разместить на форме вида список Listbox, в котором показываются ключевые поля объекта. Полностью объект показывается в элементах Edit, также размещенных на форме. Просмотр объекта осуществляется по двойному щелчку по имени в списке. Соответствующая форма имеет вид

(рис. 7.4).

128

Рис. 7.4

3. Для ввода данных при создании объекта в этом случае создается диалоговое окно, имеющее вид (рис. 7.5).

Рис. 7.5

4. Если все поля объекта размещаются в одной строке Listbox,а, томожноформироватьэтустроку ипоказыватьвListbox,е (рис. 7.6).

129

Рис. 7.6

Рис. 7.7

5. Если в качестве базового класса вида выбран класс CListView, то для отображения объектов используется объект класса CListCtrl, содержащийся в отображении (рис. 7.7).

130