"Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2" - читать интересную книгу автора (Фролов Александр Вячеславович, Фролов...)Классы приложения MultiMFC AppWizard создает для приложения Multi, обладающего многооконным интерфейсом, шесть основных классов, что на один класс больше, чем для однооконного приложения. Пять классов из шести представляют основу любого многооконного приложения, созданного MFC AppWizard. Шестой класс управляет информационной диалоговой панелью About. Список названий классов, а также входящие в них методы и элементы данных можно просмотреть на странице ClassView окна Project Workspace (рис. 1.7). В отдельной папке Globals представлены глобальные объекты и переменные приложения. Приложение Multi имеет только один глобальный объект theApp. Это объект главного класса приложения. Рис. 1.7. Окно Project Workspace, классы приложения В следующей таблице кратко описано назначение отдельных классов приложения Multi. Более подробный рассказ об этих классах и их методах расположен ниже.
Кроме пяти основных классов создается также класс CAboutDlg, наследованный от базового класса CDialog. Он отвечает за диалоговую панель About. Если во время определения характеристик приложения вы включите возможность работы с базами данных, работу с сетевыми протоколами или использование технологии OLE, список классов приложения может стать значительно шире. Главный класс приложения CMultiApp управляет работой всего приложения. Методы этого класса выполняют инициализацию приложения, обработку цикла сообщений и вызываются при завершении приложения. Через окно Project Workspace можно просмотреть названия методов класса и загрузить их в текстовый редактор (рис. 1.8). Рис. 1.8. Окно Project Workspace, класс CMultiApp Класс CMultiApp определен в файле Multi.h следующим образом:
В приложении определен только один объект базового класса приложения theApp. Этот объект должен быть один вне зависимости от того, какой интерфейс имеет приложение – однооконный, многооконный или основанный на диалоговой панели:
Конструктор класса, созданный MFC AppWizard, не выполняет никаких действий. В нем вы можете разместить код для инициализации объекта CMultiApp:
Основную работу по инициализации приложения выполняет метод InitInstance главного класса приложения, определенный в файле Multi.cpp. Как видите, он отличается от метода InitInstance, который используется для однооконных приложений:
В начале InitInstance вызываются методы Enable3dControls и LoadStdProfileSettings. Они уже были описаны в предыдущем томе серии “Библиотека системного программиста”, посвященном MFC, поэтому мы не станем на них останавливаться и перейдем к рассмотрению шаблонов документа приложения. Затем создается указатель pDocTemplate на объекты класса шаблона документов. Для однооконных приложений это класс CSingleDocTemplate, а для многооконных – CMultiDocTemplate. Создается новый объект класса и указатель на него записывается в переменную pDocTemplate. Для создания шаблона документа используется оператор new. Конструктору класса CMultiDocTemplate передаются четыре параметра:
Первый параметр nIDResource определяет идентификатор ресурсов, используемых совместно с типом документов, управляемых шаблоном. К таким ресурсам относятся меню, пиктограмма, строковый ресурс, таблица акселераторов. Для приложения Multi в этом параметре указан идентификатор IDR_MULTITYPE. Остальные три параметра pDocClass, pFrameClass и pViewClass содержат указатели на объекты класса CRuntimeClass, полученные с помощью макрокоманд RUNTIME_CLASS из классов документа CMultiDoc, дочернего окна MDI CChildFrame и окна просмотра CMultiView. Таким образом, шаблон документа объединяет всю информацию, относящуюся к данному типу документов. Созданный шаблон документов заносится в список шаблонов, с которыми работает приложение. Для этого указатель на созданный шаблон документа передается методу AddDocTemplate из класса CWinApp. Указатель на шаблон документов передается через параметр pTemplate:
Указатель pTemplate должен указывать на объект класса CDocTemplate, однако мы передаем через него указатель на объект класса CMultiDocTemplate. Это допустимо, так как класс CDocTemplate является базовым классом для CMultiDocTemplate. Если вы разрабатываете приложение, основанное на однооконном или многооконном интерфейсе, объект главного класса приложения управляет одним или несколькими объектами класса шаблона документа. Они, в свою очередь, управляют созданием документов. Один шаблон используется для всех документов данного типа. После создания шаблона документа создается главное окно MDI (главное окно приложения). Для создания главного окна приложения мы формируем объект класса CMainFrame и записываем указатель на него в pMainFrame. Класс CMainFrame определен в нашем приложении. Мы расскажем о нем немного позже:
Затем для только что созданного объекта вызывается метод LoadFrame класса CFrameWnd. Он создает окно, загружает ресурсы, указанные первым параметром, и связывает их с объектом класса CMainFrame. Параметр метода LoadFrame определяет меню, пиктограмму, таблицу акселераторов и таблицу строк главного окна приложения:
Указатель на главное окно приложения, которым является главное окно MDI, записывается в элемент данных m_pMainWnd главного класса приложения. Элемент данных m_pMainWnd, определенн в классе CWinThread. Когда окно, представленное указателем m_pMainWnd закрывается, приложение автоматически будет завершено (в случае если приложение включает в себя несколько задач, завершается только соответствующая задача):
Метод LoadFrame не отображает главное окно приложения на экране. Для этого надо вызвать методы ShowWindow и UpdateWindow:
// Обновляем содержимое окна
В заключение метода InitInstance обрабатывается командная строка приложения. Для этого создается объект cmdInfo класса CCommandLineInfo и для него вызываются методы ParseCommandLine и ProcessShellCommand:
Класс CMultiApp может получать сообщения и имеет таблицу сообщений. Таблицу сообщений класса CMultiApp расположена в файле Multi.cpp. Она содержит четыре макрокоманды для обработки командных сообщений от меню приложения:
Только для одного командного сообщения, имеющего идентификатор ID_APP_ABOUT, вызывается метод обработчик OnAppAbout, определенный в классе CMultiApp. Остальные три командных сообщения ID_FILE_NEW, ID_FILE_OPEN и ID_FILE_PRINT_SETUP передаются для обработки методам класса CWinApp, который является базовым классом для CMultiApp. Метод-обработчик OnAppAbout вызывается объектом главного класса приложения, когда пользователь выбирает из меню Help строку About. OnAppAbout создает объект класса CAboutDlg, представляющий модальную диалоговую панель About и вызывает для него метод DoModal, отображающий панель на экране (рис. 1.9):
Рис. 1.9. Окно Project Workspace, класс CMainFrame Внутри главного окна приложения отображаются панели управления и состояния, дочерние MDI окна, используемые для просмотра документов. Для управления главным окном приложения используется класс CMainFrame, определенный в файле MainFrm.h. Вы можете изучить класс CMDIFrameWnd, просмотрев его структуру в окне Project Workspace, на странице ClassView (рис. 1.10). Выполните двойной щелчок левой кнопкой мыши по названию класса или по названию интересующего вас метода, и соответствующий программный код загрузится в окно редактора Microsoft Visual C++. Рис. 1.10. Окно Project Workspace, класс CMainFrame Ниже мы привели определение класса CMainFrame:
Класс главного окна многооконного приложения CMainFrame практически полностью соответствует классу главного окна однооконного приложения. Даже названия этих классов одинаковы. Однако обратите внимание, что класс CMainFrame наследуется от базового класса CMDIFrameWnd, а не от CFrameWnd, как это было для однооконного приложения. Ниже представлены конструктор и деструктор класса CMainFrame. Изначально они не содержат программного кода и представляют собой простые заготовки. Вы можете использовать их для дополнительной инициализации объекта класса:
Таблица сообщений класса CMainFrame содержит только одну макрокоманду ON_WM_CREATE, которая устанавливает для обработки сообщения WM_CREATE метод OnCreate. Сообщения WM_CREATE приходит во время создания главного окна приложения. Непосредственно перед таблицей сообщений класса CMainFrame располагается макрокоманда IMPLEMENT_DYNAMIC. Она указывает, что объекты класса CMainFrame могут создаваться динамически во время работы приложения:
Метод OnCreate класса CMainFrame создает и отображает на экране панели управления и состояния:
Структура indicators, описывающая индикаторы панели состояния, определена в файле MainFrm.h следующим образом:
Сейчас мы не станем подробно останавливаться на процедуре создания панелей состояния и управления. Во первых, в 24 томе мы уже рассматривали метод OnCreate однооконного приложения Single. Он фактически полностью повторяет метод OnCreate приложения Multi. Во вторых мы посвятили проблеме использования меню, панелей состояния и панелей управления отдельный раздел “Меню, панели управления и панели состояния”. Прочитав его, вы полностью поймете как устроен метод OnCreate класса CMainFrame. Метод PreCreateWindow вызывается перед созданием окна и позволяет изменить его характеристики. В нашем приложении метод PreCreateWindow не используется и просто выполняет обрработку по умолчанию:
В отладочной версии приложения класс CMainFrame содержит переопределения виртуальных методов AssertValid и Dump. Эти методы определены в базовом классе CObject и используются при отладке приложения:
Многооконное приложение строится с использованием большего числа классов, чем однооконное приложение. Помимо классов главного окна приложения и классов окна просмотра документа, в нем определен еще один класс, непосредственно связанный с отображением дочерних окон MDI. Этот класс называется CChildFrame и он наследуется от базового класса CMDIChildWnd , определенного в библиотеке MFC:
Элементы класса CChildFrame вы можете просмотреть в окне Project Workspace на странице ClassView (рис. 1.11). Рис. 1.11. Окно Project Workspace, класс CChildFrame Объекты класса CChildFrame представляют дочерние окна MDI главного окна приложения. Внутри этих окон отображаются окна просмотра документа. MFC AppWizard определяет для класса CChildFrame конструктор и деструктор. По умолчанию они не выполняют никаких действий. Вы можете изменить их для выполнения инициализации объектов класса дочернего окна MDI:
Таблица сообщений класса CChildFrame не содержит обработчиков сообщений:
Метод PreCreateWindow вызывается перед созданием дочернего окна MDI. Вы можете использовать его, чтобы переопределить стили этого окна:
Методы AssertValid и Dump переопределяются в классе CMainFrame только для отладочной версии приложения и используются при отладке приложения:
Класс документа приложения CMultiDoc наследуется от базового класса CDocument библиотеки MFC. Определение этого класса вы можете найти в файле MultiDoc.h. Мы привели структуру класса CMultiDoc на рисунке 1.12. Рис. 1.12. Окно Project Workspace, класс CMultiDoc MFC AppWizard определяет класс CMultiDoc одинаково для однооконных и для многооконных приложений. Единственное исключение составляет название класса документа, которое создается на основе имени проекта:
Конструктор и деструктор класса CMultiDoc не содержит программного кода. Вы можете добавить его по мере необходимости:
Таблица сообщений класса CMultiDoc не содержит ни одного обработчика сообщений:
В классе CMultiDoc переопределены два виртуальных метода – OnNewDocument и Serialize. Виртуальный метод OnNewDocument определен в классе CDocument, от которого непосредственно наследуется класс CSingleDoc. Метод OnNewDocument вызывается, когда надо создать новый документ для приложения. Для одноконных приложений метод OnNewDocument вызывался только один раз при запуске приложения. Для многооконного приложения метод OnNewDocument вызывается каждый раз, когда пользователь создает новый документ. Более подробно об использовании метода OnNewDocument мы расскажем в следующих главах, когда к шаблону приложения, созданному MFC AppWizard, мы будем добавлять собственный код:
Метод Serialize вызывается в тех случаях, когда надо загрузить документ из файла на диске или наоборот, записать его в файл:
Методы AssertValid и Dump переопределяются в классе CMainFrame только для отладочной версии приложения и используются при отладке приложения:
Класс окна просмотра документа, также как класс документа и главный класс приложения, имеют своего двойника в однооконном приложении. Так, в приложении Single определен класс окна просмотра CSingleView, совпадающий с классом CMultiView. Рис. 1.13. Окно Project Workspace, класс CMultiView Вы можете просмотреть список методов, входящих в класс CMultiView, если откроете в окне Project Workspace страницу ClassView (рис. 1.13). А сейчас приведем определение класса CMultiView :
Как видите, класс CMultiView наследуется от базового класса CView. Вы, однако, можете наследовать этот класс и от некоторых других классов библиотеки MFC. В секции атрибутов класса CMultiView после комментария Attributes объявлен метод GetDocument. Этот метод возвращает указатель на документ, связанный с данным окном просмотра. Если окно просмотра не связано ни с каким документом, метод возвращает значение NULL. Метод GetDocument имеет две реализации. Одна используется для отладочной версии приложения, а другая – для окончательной. Окончательная версия GetDocument определена непосредственно после самого класса окна просмотра CMultiView как встраиваемый (inline ) метод:
Переменная m_pDocument является элементом класса CView, определенным как protected. В документации на класс CView описание элемента m_pDocument отсутствует. Однако, вам достаточно знать, что после инициализации документа и окна просмотра в нем записан указатель на соответствующий документ. Если вы желаете получить дополнительную информацию, обратитесь к исходным текстам библиотеки MFC. Вы найдете определение класса CView и элемента этого класса m_pDocument в файле Afxwin.h. Метод GetDocument совпадает с одноименным методом класса окна просмотра однооконного приложения за исключением того, что тип возвращаемого им указателя CMultiDoc. Отладочная версия GetDocument расположена в файле реализации класса окна просмотра MultiView.cpp:
Таблица сообщений класса CMultiView располагается в файле MultiView.cpp. Непосредственно перед ней расположена макрокоманда IMPLEMENT_DYNCREATE:
Конструктор и деструктор класса CMultiView не выполняют полезной работы. MFC AppWizard создает для них только пустые шаблоны, которые вы можете “наполнить” сами:
Виртуальный метод PreCreateWindow определен в классе CWnd. Он вызывается непосредственно перед созданием окна, связанного с объектом класса. MFC AppWizard переопределяет этот метод следующим образом:
Метод OnDraw первоначально определен в классе CView как виртуальный и вызывается, когда приложение должно перерисовать документ в окне просмотра. MFC AppWizard переопределяет для вас метод OnDraw класса CView следующим образом:
Первые две строки метода OnDraw получают указатель pDoc на документ, связанный с данным окном просмотра. Виртуальные методы OnPreparePrinting, OnBeginPrinting и OnEndPrinting, определенные в классе CView, вызываются, если пользователь желает распечатать документ, отображенный в данном окне просмотра:
Многооконное приложение, подготовленное MFC AppWizard, уже “умеет” выводить созданные в нем документы на печатающее устройство. Методы OnPreparePrinting, OnBeginPrinting и OnEndPrinting класса CView предназначены для расширения возможностей печати и в этой книге не рассматриваются. Методы AssertValid и Dump переопределяются в классе CMainFrame только для отладочной версии приложения и используются при отладке приложения:
|
||||||||||||||||||||||||||||||||
|