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

Технология разработки программных систем

..pdf
Скачиваний:
13
Добавлен:
05.02.2023
Размер:
1.31 Mб
Скачать

171

Класс CControlBar и классы, наследуемые от него, предназначены для создания управляющих панелей. Такие панели могут содержать различные элементы управления и отображаются, как правило, в верхней части главного окна приложения.

Класс CToolBar предназначен для создания панели управления. Эта панель обычно содержит ряд кнопок, дублирующих действие меню приложения.

Класс CStatusBar является отображением панели состояния в виде полосы в нижней части окна. В этой панели приложение может размещать всевозможную информацию, например, краткую подсказку о выбранной строке меню.

Большие возможности представляет управляющая панель, созданная на основе класса CDialogBar. Такая панель использует обычный шаблон диалоговой панели, которую можно разработать в редакторе ресурсов.

15.12. CMenu – класс меню приложений

CObject CMenu

Практически каждое приложение имеет собственное меню. Для управления меню в состав MFC включен специальный класс CMenu, наследованный непосредственно от базового класса CObject. Методы класса CMenu позволяют выполнять различные операции по изменению состава пунктов меню, а для модификации существующих пунктов используется другой класс – CCmdUI. Заметим, что этот класс не наследуется от базового класса

CObject.

Объекты класса CCmdUI создаются динамически, когда пользователь выбирает строку меню или нажимает кнопку панели управления. Методы класса CCmdUI позволяют управлять состоянием строк меню или кнопок панели управления. Например, существует метод, который делает строку меню неактивной.

15.13. Массивы, списки, словари

В состав MFC включен целый набор вспомогательных, но весьма полезных классов, предназначенных для хранения информации в массивах, списках и словарях. Все эти классы наследованы от базового класса

CObject.

Массивы

172

В языке C дано классическое понятие массива со множеством ограничений. Классы MFC обеспечивают более широкую трактовку и дают дополнительные возможности при работе с массивами. Так, MFC массивы обеспечивают динамичность, т.е. возможность изменения размерности массива.

Для представления массивов предназначены следующие классы:

MFC класс

Элементы массива

 

 

CByteArray

unsigned char

CDWordArray

unsigned long

CObArray

указатели на объекты класса Cobject

CPtrArray

указатели типа void

CStringArray

объекты класса CString

CUIntArray

unsigned int

CWordArray

unsigned short

Основная схема использования MFC массивов состоит в следующем: 1) объявляется объект класса массив, например,

CByteArray arByte;

2) указывается на сколько элементов будет увеличиваться блок памяти, выделенный под весь массив, при его динамическом расширении.

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

arByte.SetSize(0, 4); // на 4 элемента

3) массив заполняется элементами

arByte.Add(0x17); arByte.Add(0x255);

4) доступ к элементам массива осуществляется через перегруженную операцию индексирования

arByte[k] = 20;

или метод GetAt()

BYTE bTest = arByte.GetAt(k);

5) освобождать память, выделенную под массив, не требуется, т.к. это происходит автоматически при вызове деструктора класса.

173

Списки Для решения многих задач применяются такие структуры хранения

данных, как списки. MFC включает ряд классов, наследованных от базового класса CObject, которые предоставляют разработчику готовое решение для создания собственных списков. В этих классах определены все методы, необходимые при работе со списками: добавление нового элемента, вставка нового элемента, определение следующего или предыдущего элемента в списке, удаление элемента и проч.

Ниже перечислены классы, позволяющие построить списки из элементов любых типов:

MFC класс

Элементы списка

 

 

CObList

указатели CObject

CPtrList

указатели типа void

CStringList

объекты класса CString

Словари Словарь – это информационная структура, которая представляет собой

таблицу из двух колонок, устанавливающих соответствие между парами значений. Первая величина представляет собой ключевое значение и записывается в первую колонку, а вторая – связанное с ней значение, хранящееся во второй колонке. Словарь позволяет добавлять в него пары связанных величин и осуществлять выборку значений по ключевому слову.

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

Класс

Ключевое слово

Связанное значение

 

 

 

CMapPtrToPtr

указатель типа void

указатель типа void.

CMapPtrToWord

указатель типа void

WORD

CMapStringToOb

объекты класса CString

указатель класса CObject

CMapStringToPtr

объекты класса CString

указатель типа void

CMapStringToString

объекты класса CString

указатель класса CObject

CMapWordToOb

WORD

указатель класса CObject

CMapWordToPtr

WORD

указатель типа void

15.14. Файловая система

CStdioFile

CObject CFile CMemFile

CSocketFile

174

Библиотека MFC включает класс CFile, предназначенный для работы с файловой системой Windows, и также наследуемый от базового класса CObject. Класс CFile инкапсулирует все необходимые операции для работы с файлом, как последовательностью байт. Если же файл содержит текстовую информацию и строки разделены сепараторами \r\n, то удобнее воспользоваться методами класса CStdioFile, специально предназначенного для манипулирования такими файлами.

Кроме того, от класса CFile наследуются еще несколько классов, среди которых упомянем CMemFile и CSocketFile. Первый представляет собой файл, спроецированный в оперативную память, а второй – файл, передаваемый через сокеты.

При работе с файловой системой может потребоваться различная информация о некотором файле, например, дата создания, его размер и проч. Для получения этих данных предназначен специальный класс CFileStatus. Заметим, что этот класс не наследуются от базового класса

CObject.

Класс CFileStatus используется также для решения задачи об определении существования файла с заданным именем.

15.15. Контекст отображения

CObject CDC

Для отображения информации в окне или на любом другом устройстве приложение должно получать контекст отображения. Основные свойства контекста отображения определены в классе CDC. От него наследуется еще четыре класса, представляющие контекст отображения различных устройств:

CClientDC контекст отображения, связанный с клиентской областью окна. Для получения контекста конструктор класса вызывает функцию GetDC из Win32 API, а деструктор - функцию

ReleaseDC.

CPaintDC конструктор класса CPaintDC для получения контекста отображения вызывает метод CWnd::BeginPaint, а деструктор - метод CWnd::EndPaint. Объекты данного класса можно использовать только при обработке сообщения WM_PAINT в обработчике OnPaint.

CWindowDC контекст отображения, связанный со всем окном. Для полу-

175

чения контекста конструктор класса вызывает функцию GetWindowDC из Win32 API, а деструктор – функцию

ReleaseDC.

CMetaFileDC класс предназначен для работы с метафайлами.

15.16. Объекты графического интерфейса

CObject CGdiObject

Для отображения информации используются различные объекты графического интерфейса – GDI-объекты. Для каждого из этих объектов библиотека MFC содержит соответствующий класс, наследованный от базового класса CGdiObject:

CBitmap

изображение bitmap

CBbrush

кисть

CFont

шрифт

CPalette

палитра цветов

CPen

перо

CRgn

произвольная область

 

внутри окна

15.17. Исключения

CObject CException

Напомним, что стандарт языка С++ включает такую конструкцию, как try блок. Любые ошибки, возникающие в коде, охваченном try блоком, генерируют исключения посредством throw операторов. При возникновении ошибки, выполнение кода прекращается, а управление передается на соответствующие catch обработчики, расположенные за пределами try блока.

MFC, не меняя самой идеи перехвата ошибок, проводит структуризацию исключений, так что каждая ошибочная ситуация имеет собственный catch обработчик. Коллекция, насчитывающая 11 классов, обслуживает все возможные исключительные ситуации, среди которых отметим:

Класс CException, является базовым для этой группы, но сам практически не используется.

176

CMemoryException класс, объекты которого локализует все исключительные ситуации, возникающие в памяти.

CFileException класс, объекты которого локализует все исключительные ситуации, возникающие при работе с файлами.

CDBException исключения, возникающие при работе MFC объектов, основанных на ODBC технологии.

CUserException исключения, которые может генерировать разработ-

чик, вызывая MFC функцию AfxThrowUserException().

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

TRY {

(1)// код приложения, который может // вызвать исключение или исключения

}

//в эту точку попадем только тогда,

//когда исключений не было

CATCH ( CUserException, e ) {

//обработка исключений

//разработчика

ViewUserError(e);

}

AND_CATCH ( CDBException, e ) { // обработка DB исключений

ViewDBError(e);

}

AND_CATCH ( CFileException, e ) {

// обработка файловых исключений

(2)ViewFileEerror(e);

}

END_CATCH

Из схемы видно, что MFC заменяет ключевые слова языка С++ try и catch аналогичными макросами. Объясняется это необходимостью передачи информацию из точки возникновение исключения (1) в точку его обработки (2). Достичь этого можно динамическим созданием объекта, например класса CFileException, в точке возникновение исключения. Однако это потребует динамического разрушения объекта в точке (2), что и выполняют MFC макросы, выводя данную операцию из зоны ответственности разработчика.

177

Как правило, обработчики исключений только отображают текстовое сообщение о характере возникшей ошибки. Классы исключений несут информацию об ошибке, но в виде целочисленного кода, поэтому возникает задача преобразования этого кода в его текстуальное представление. Наиболее просто данная задача решается с помощью вызова Win32 API функции FormatMessage, так что обработчик файловых исключений мог бы иметь вид:

void ViewFileEerror (CFileException* e)

{

//e->m_lOsError системной код ошибки

//e->m_strFileName имя файла, вызвавшего ошибку

//буфер для текстового представления ошибки

TCHAR szErrs[4*1024];

//получение текста ошибки по ее коду

::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, e->m_lOsError,

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), szErrs, sizeof(szErrs), NULL);

.

.

.

}

15.18. Классы, не имеющие базового класса

Кроме классов, наследованных от базового класса CObject, библиотека MFC включает ряд самостоятельных классов. У них нет общего базового класса, и все они имеют различное назначение. Несколько классов, которые не наследуются от базового класса CObject, уже упоминались – это классы CCmdUI, CFileStatus и CDataExchange. Среди других укажем наиболее интересные.

Простые геометрические фигуры. CPoint объекты класса описывают точку.

CRect объекты класса описывают прямоугольник.

CSize объекты класса определяют размер прямоугольной области.

Дату и время определяют два класса:

CTime объекты класса служат для хранения даты и времени. Большое количество методов класса позволяет выполнять различные преобразования.

178

CTimeSpan объекты класса определяют период времени.

Строка. Объекты класса CString представляют собой текстовые строки переменной длины. Этот класс интересен еще и тем, что имеет метод GetBuffer, который дает возможность захватывать блоки памяти произвольной длины. Данный путь предпочтительнее, поскольку не приводит к столь сильной фрагментации CRT “кучи”, как многократное использование оператора new.

Архивный класс. Класс CArchive используется для сохранения и восстановления состояния объектов в файлах на магнитном носителе. Перед использованием объекта класса CArchive он должен быть привязан к объекту класса CFile.

Информация о классе объекта. Во многих случаях бывает необходимо уже во время выполнения приложения получить информацию о классе и его базовом классе. Для этого любой класс, наследованный от базового класса CObject, связан со структурой CRuntimeClass. Она позволяет определить имя класса объекта, размер объекта в байтах, получить указатель на конструктор по умолчанию и деструктор класса. Можно также узнать подобную информацию о базовом классе и некоторые дополнительные сведения.

Отладка приложения. В отладочной версии приложения можно использовать класс CDumpContext. Он позволяет выдавать состояние различных объектов в текстовом виде. Класс CMemoryState позволяет локализовать проблемы, связанные с динамическим выделением оперативной памяти. Такие проблемы обычно возникают, когда пользователь выделяет память оператором new, а затем забывает вернуть эту память операционной системе.

Печать документа. Класс CPrintInfo предназначен для управления печатью документов на принтере. Когда пользователь отправляет документ на печать или выполняет предварительный просмотр документа перед печатью, создается объект класса CPrintInfo. Он содержит различную информацию о диапазоне печати, о том, какие страницы документа печатаются в данный момент и проч.

179

Итак, в данном разделе проведен обзор основных классов, с помощью которых строятся типичные MFC приложения. Информацию о других MFC классах вы можете найти в справочной литературе.

180

16. Структура простейших MFC приложений

Самые простейшие приложения с использованием библиотеки классов MFC можно создавать в Microsoft Developer Studio без применения автоматизированных средств разработки приложений MFC AppWizard. Необходимо только создать проект типа Win32 Application и включить в его установках поддержку библиотеки MFC.

16.1. Приложение без главного окна

С целью изучения внутренней структуры типичного MFC приложения, создадим приложение Simple1, отображающее на экране диалоговую панель, которая содержит строку текста. В этом приложении используется единственный класс, наследованный от базового класса CWinApp. Приведем исходный текст приложения:

//включаем поддержку MFC

(1)#include <afxwin.h>

class CSimple1App: public CWinApp { public:

//переопределяем метод InitInstance

(3)virtual BOOL InitInstance(); };

//создаем объект приложения

(2)CSimple1App theApp;

// Метод InitInstance

BOOL CSimple1App::InitInstance()

{

AfxMessageBox("Simple1 MFC application");

(4) return FALSE;

}

Рассмотрим, как работает это приложение.

(1) В текст приложения включается файл afxwin.h. В этом файле определены классы, методы, константы и другие структуры для библиотеки классов MFC. Кроме того, этот включаемый файл автоматически подключает другой файл – windows.h, необходимый для вызовов функций стандартного программного интерфейса Windows.

(2) В исходном тексте программы нет хорошо знакомой функции WinMain. Не видно также переменных, представляющих параметры этой функции. В приложениях, основанных на классах MFC, функция WinMain скрыта от программиста в определении класса CWinApp. В каждом приложении определяется главный класс приложения, наследуемый от базового класса CWinApp. Приложение должно иметь только один объект главного

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]