![](/user_photo/_userpic.png)
книги / Технологии программирования. Программирование графических интерфейсов Microsoft Visual и Borland Delphi
.pdf![](/html/65386/197/html_5HyjfH3RId.4XSp/htmlconvd-_bmh5V101x1.jpg)
7. Запишите обработчик сообщения от команды «Создать объект». Учтите, что созданный объект должен сохраняться
вконтейнере.
8.При активизации диалога «Просмотр объектов» в блок диалога помещается первый объект из массива либо выдается сообщение, если массив пуст.
9.Обработчик сообщения от кнопки «Next» диалога «Просмотр объектов» помещает в блок диалога следующий элемент массива. Просмотр осуществляется по кругу, т.е. после последнего элемента показывается первый.
10.Для доступа к следующему элементу следует поместить
вкласс диалогового окна просмотра объектов переменную, хранящую индекс текущего элемента. Доступ к объекту приложения можно получить с помощью глобальной функции AfxGetApp().
11.Не забывайте, что операции доступа к элементам массива CObArray возвращают указатель типа CObject*. Используйте приведение типов.
12.Откомпилируйте и выполните программу. При выборе команды меню «Создать объект» появляется окно, подобное показанному на рис. 6.1.
Рис. 6.1
101
![](/html/65386/197/html_5HyjfH3RId.4XSp/htmlconvd-_bmh5V102x1.jpg)
Рис. 6.2
13.Используя редактор ресурсов, создайте шаблон блока диалога для просмотра объектов, хранящихся в контейнере.
14.Откомпилируйте и выполните программу. При выборе команды меню «Просмотреть объект» появляется окно, подобное показанному на рис. 6.2.
6.3. Сохранение данных в файле
Класс CFile
Класс CFile обеспечивает универсальный интерфейс для выполнения операций с двоичными файлами. Для использования класса CFile нужно создать объект CFile с заданным именем файла и указать режим доступа к нему.
Объект создается конструктором
CFile(LPCTSTR lpszFileName,UINT nOpenFlags); lpszFileName – строка, содержащая имя дискового файла, nOpenFlags – режим доступа.
Режим доступа задается следующими константами: CFile::modeRead – файл открывается только для чтения; CFile::modeReadWrite – файл открывается для чтения
и записи;
CFile::modeWrite – файл открывается только для записи;
102
CFile::modeCreate – создается новый файл. Если файл с таким именем уже существует, его размер устанавливается равным нулю;
CFile::modeNoTruncate – комбинируется с modeCreate.
Существующий файл не усекается.
Можно также создать объект CFile конструктором без параметров, а затем открыть его методом:
virtual BOOL Open(LPCTSTR lpszFileName, UINT
nOpenFlags, CFileException* pError = NULL );
Методом virtual void Close( ); файл закрывается. Записать в файл можно методом:
virtual void Write(const void* lpBuf,UINT nCount );
Из области lpBuf в файл, начиная с текущей позиции, записывается nCount байт.
Чтение из файла выполняет метод
virtual UINT Read(void* lpBuf,UINT nCount );
Начиная с текущей позиции файла в область lpBuf, читается nCount байт.
Функция возвращает действительное количество прочитанных байт.
Класс CFileDialog
Объекты этого класса используются для создания пользовательского интерфейса для работы с файлами. Класс обеспечивает диалоговое окно для выбора имени файла при его открытии и при сохранении данных.
Конструктор explicit CFileDialog(
BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL,
103
DWORD dwSize = 0
);
Назначение параметров:
bOpenFileDialog – TRUE для диалога File Open и FALSE –
для диалога File Save,
lpszDefExt – расширение файла по умолчанию, lpszFileName – имя файла при инициализации диалого-
вого окна,
dwFlags – комбинация флагов, определяющих внешний вид окна,
lpszFilter – строка, задающая фильтры для выбора имени файлов.
Для организации диалога необходимо:
1)создать объект CFileDialog;
2)инициировать модальный диалог вызовом метода
DoModal();
3) при завершении диалога получить введенное имя файла функцией CString GetFileName( ) const;
6.4. Пример создания программы с сохранением данных в файле
1. В существующей рабочей области создайте проект как приложение MFC AppWizard(exe). Выберите тип приложения SDI. Отключите поддержку архитектуры Document/View.
2.Определите пользовательский класс. Определение класса сохраните в h-файле, определение функций – в cpp-файле.
3.Используя редактор ресурсов, создайте шаблон блока диалога для ввода данных при создании объекта.
4.Используя ClassWizard, создайте класс диалогового окна для ввода данных.
5.Добавьте в класс члены-данные для обмена с блоком диалога. Функции DDX и DDV добавятся автоматически.
104
6.Используя редактор ресурсов, добавьте меню «Диалог»
икоманды «Создать объект» и «Показать объект». В меню «File» добавьте команды «Сохранить объекты» и «Загрузить объекты».
7.Запишите обработчик сообщения от команды «Создать объект». Учтите, что созданный объект должен сохраняться в контейнере.
8.Откомпилируйте и выполните программу.
9.Используя редактор ресурсов, создайте шаблон блока диалога для просмотра объектов, хранящихся в контейнере.
10.Откомпилируйте и выполните программу.
11.Запишите обработчик сообщения от команды «Сохранить объекты».
12.Откомпилируйте и выполните программу. Убедитесь, что объекты сохраняются.
13.Запишите обработчик сообщения от команды «Загрузить объекты».
14.Откомпилируйте и выполните программу. Убедитесь, что объекты загружаются.
105
7.ПРОГРАММИРОВАНИЕ ПРИЛОЖЕНИЙ
САРХИТЕКТУРОЙ «ДОКУМЕНТ–ВИД»
7.1. Архитектура «документ–вид»
Архитектура «документ–вид» является частным случаем архитектуры MVC (модель-вид-контроллер) и означает приблизительно следующее. У вас есть один класс, который отвечает за данные, и второй класс, который отвечает за отображение этих данных на экране.
Класс документа отвечает за хранение данных, сохранение их на диске, чтение с диска.
Класс отображения (вида) отвечает за представление данных на экране. У одного документа может быть несколько представлений (видов).
В ОС Windows пользователь взаимодействует с документом, который изображен (обладает видом) внутри окна-рамки. Система Windows сама справляется с многими типами взаимодействий пользователя с окном-рамкой (перемещение, изменение размеров, сворачивание и т.д.). Программист должен управлять содержимым внутри окна-рамки. Каркас MFC-приложения использует окна-рамки для обрамления окон видов, т.е. он вводит разделение функций окна приложения на два компонента. Оба компонента представлены и управляются двумя различными классами MFС. Класс главного окна приложения, производный от CFrameWnd, управляет рамкой, а класс «Вид», производный от одного из классов – потомков CView, управляет содержимым окна-рамки. Окно «Вид» считается дочерним окном
(Child) окна-рамки.
Существуют два стандарта для приложений: SDI и MDI. В SDI-приложениях может быть открыт только один документ в главном окне, в то время как в MDI-приложениях открыто несколько, каждый документ в отдельном дочернем окне.
106
7.2. Классы SDI-приложения с архитектурой «документ–вид»
Мастер приложения (MFC AppWizard(exe)) создает каркас приложения с четырьмя классами:
CMyPrApp:public CWinApp |
Класс приложения |
CMainFrame:public CFrameWnd |
Классглавногоокна-рамки |
CMyPrDoc:public CDocument |
Класс документа |
CMyPrView:public CView |
Класс вида |
Базовый класс для вида CView задается по умолчанию. Мастер MFC AppWizard(exe) позволяет выбрать следующие базовые классы для вида:
CScrollView – для автоматической прокрутки и масштабирования изображения;
CFormView – для отображения форм, содержащих элементы управления;
CTreeView – для отображения, содержащего объект CTreeCtrl, который позволяет реализовать работу с данными, представляемыми в виде древовидной иерархической структуры; CListView – для отображения, содержащего объект CListCtrl, который может показывать элементы списка различными спо-
собами;
CEditView – для отображения, реализующего свойства окна редактирования. Объект CEditView реализует работу простого текстового редактора;
CRichEditView – для отображения, реализующего текстовый редактор с возможностью форматирования текста.
7.3. Объектыиклассы архитектуры«документ–вид»
Объект документа
Используется для хранения данных приложения. Обычно данные хранятся в самой программе, но это не всегда так. Данные могут располагаться в базе данных или на удаленном носи-
107
теле информации. Важной отличительной чертой документа является то, что он выступает как источник информации для приложения и отвечает за работу с этой информацией. Отвечая за работу с информацией, класс документа производит ее чтение
сносителя и запись на него.
ВMFC объект документа – это объект класса, производного от CDocument. При создании класса документа в него, как правило, включаются переменные для хранения необходимой информации и открытые функции для доступа к этой информации из других объектов приложения.
Воднооконном приложении объект документа создается только один раз и используется повторно при каждом создании или открытии документа. В этом случае однократная инициализация данного объекта производится не в конструкторе, а в функ-
цияхOnNewDocument() иOnOpenDocument().
Объект представления
Хранит указатель на объект документа. Для получения этого указателя вызывается функция CDocument *CView ::
GetDocument().
Класс CView представляет собой абстрактный класс, в котором определены основные свойства представления.
Класс CView и его потомки включают в себя несколько виртуальных функций, перегружаемых для настройки поведения класса представления. Наиболее важной из них является
virtual void CView :: OnDraw(CDC *pDC)=0;
Функция OnDraw() вызывается приложением при обновлении выводимой информации. В функцию передается указатель на контекст устройства. Это основная и единственная функция для изображения видимого образа документа.
В однооконном приложении объекты приложения создаются один раз, а затем многократно используются. Инициализацию объекта представления информацией, содержащейся в документе, следует производить в функции CView :: OnInitial-
Update().
108
![](/html/65386/197/html_5HyjfH3RId.4XSp/htmlconvd-_bmh5V109x1.jpg)
Объект окна-рамки
Определяет физическую рабочую область приложения на экране и служит контейнером для всех объектов представления. В однооконном приложении может существовать только одно окно-рамка – CFrameWnd, используемое приложением как окно верхнего уровня и как рамка для всех объектов представления.
Окна-рамки организуют большинство операций, скрываемых концепцией документ-представление. Их основная задача заключается в управлении одним или несколькими объектами представления, а также различными элементами пользовательского интерфейса: панелями инструментов, строками состояния и диалоговыми панелями.
Ниже показана связь окна-рамки и дочернего окна вида
(рис. 7.1).
Рис. 7.1
Шаблон документа
Используется для объединения компонентов концепции документ-представление: объекта документа, объекта представления, объекта рамочного окна.
Для каждого типа документов, используемых в приложении, создается свой шаблон документа. Шаблон документа отвечает за создание и работу со всеми документами его типа.
109
Объект шаблона документа обеспечивает средства, которые используются MFC для динамического создания экземпляров объектов документа, представления и рамочного окна. Эта операция возможна, поскольку в шаблоне документа хранятся указатели на объекты класса CRuntimeClass, связанные с каждым пользовательским классом документа, представления и рамочного окна. Для определения объектов класса CRuntimeClass при создании шаблона документаиспользуетсямакросRUNTIME_CLASS().
В MFC определены два класса шаблонов документов:
CSingleDocTemplate для SDI-приложения и CMultiDocTemplate для MDI-приложения, которые являются потомками абстрактного базового класса CDocTemplate.
Шаблоны документов создаются, как правило, в функции InitInstance() класса приложения.
После создания объекта шаблона документа он добавляется в список имеющихся шаблонов документов приложения с использованием функции CWinApp :: AddDocTemplate().
Шаблоны документов создаются и управляются объектом приложения. Одна из главных задач, выполняемых функцией InitInstance(), – создание одного или нескольких шаблонов документа соответствующего типа, например:
BOOL CMyApp :: InitInstance()
{CSingleDocTemplate*
pDocTemplate;
pDocTemplate=new CSingleDocTemplate
(
IDR_MAINFRAME, RUNTIME_CLASS(CMyAppDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CMyAppView)
);
AddDocTemplate(pDocTemplate); return TRUE;
}
110