Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Функция инициализации приложения CWinApp::InitInstanceСодержание книги
Поиск на нашем сайте Один из интересных аспектов приложения документ/вид – способ создания объектов окна-рамки, документа и вида. В функции InitInstance, сгенерированной с помощью AppWizard, содержится примерно следующее:
Следующие операторы:
создают SDI-шаблон документа как объект MFC-класса CSingleDocTemplate. Шаблон документа (document template) – это очень важная компонента SDI-приложения документ/вид. С его помощью сопоставляются классы документа, окна-рамки и вида. В шаблоне документа также хранится идентификатор ресурса (по умолчанию IDR_MAINFRAME), по которому каркас приложения загружает меню, таблицу ускоряющих клавиш и другие ресурсы. Макрос RUNTIME_CLASS, которому в качестве параметра передается имя класса, возвращает указатель на объект CRuntimeClass. Он обеспечивает динамическое создание объектов класса каркасом приложения. После создания шаблона документа он добавляется в список шаблонов, хранящийся в объекте-приложении:
Каждый зарегистрированный шаблон определяет один тип документа, поддерживаемого данным приложением. SDI-приложения регистрируют только один тип документа, а MDI-приложения могут зарегистрировать несколько. Операторы:
вызывают CWinApp::ParseCommandLine для инициализации объекта CCommandLineInfo значениями, переданными через командную строку операционной системы (иногда так передается имя открываемого файла с документом). Далее выполняется "обработка" командной строки:
В частности, ProcessShellCommand вызывает CWinApp::OnFileNew для запуска приложения с пустым новым документом, если в командной строке не было указано имени файла. Если же имя было указано, то вызывается CWinApp::OpenDocumentFile для загрузки документа из файла. Именно на этой стадии выполнения программы каркас приложения создает объект-документ, окно-рамку и окно-вид на основе информации из шаблона документа. ProcessShellCommand возвращает TRUE в случае успешной инициализации или FALSE в случае ошибки. После успешной инициализации окно-рамка (и его дочернее окно-вид) выводятся на экран:
После запуска приложения и создания объектов документа, окна-рамки и вида, запускается цикл обработки сообщений. За обработку сообщений совместно отвечают все эти объекты, и большая часть служебных действий в этой области выполняется каркасом приложения. В Windows сообщения могут получать только окна, поэтому в MFC реализован собственный механизм маршрутизации для передачи сообщений некоторых типов от одного объекта другому, пока сообщение не будет обработано или передано на обработку по умолчанию::DefWindowProc. Этот механизм является одной из наиболее мощных возможностей архитектуры документ/вид в MFC.
Класс-документ В приложении документ/вид данные хранятся в объекте-документе. Это объект класса, унаследованного от CDocument (создается AppWizard 'ом). Термин "документ" несколько неоднозначен, т.к. сразу вызывает аналогию с документами текстовых редакторов или электронных таблиц. В действительности "документ" в архитектуре документ/вид – это просто некоторая структура данных, которая может описывать что-либо, например, колоду карт в карточной игре или имена и пароли пользователей в сетевой программе. Документ – это абстрактное представление данных программы, которое должно быть четко отделено от визуального представления. Обычно у объекта-документа есть открытые функции-члены, с помощью которых другие объекты, в первую очередь, окна-виды, могут обращаться к данным документа. Вся обработка данных выполняется только объектом-документом. Данные документа часто хранятся в виде переменных-членов подкласса CDocument. Можно сделать их открытыми, но, в целях лучшей защищенности, переменные-члены лучше описать защищенными и завести для доступа к данным специальные функции-члены. Например, в текстовом редакторе объект-документ может хранить символы в виде объекта CByteArray и предоставлять доступ к ним с помощью функций-членов AddChar и RemoveChar. Для обслуживания объекта-вида могут потребоваться и более специализированные функции-члены, например, AddLine и DeleteLine.
3.1 Операции CDocument В документации по MFC невиртуальные функции-члены часто называются "операциями". Подклассы CDocument наследуют от него несколько важных операций, перечисленных в следующей таблице. Таблица 9.1. Основные операции класса CDocument
Среди функций табл. 9.1 чаще всего используются SetModifiedFlag и UpdateAllViews. Функцию SetModifiedFlag надо вызывать при каждом изменении данных документа. Она устанавливает флаг, по значению которого MFC при закрытии документа выдает пользователю запрос на сохранение данных. UpdateAllViews вызывает перерисовку всех окон-видов (в MDI-приложениях их может быть несколько), связанных с этим документом. Функция UpdateAllViews вызывает у каждого вида функцию OnUpdate, которая по умолчанию объявляет окно-вид недействительным, а это приводит к его перерисовке.
Виртуальные функции CDocument В CDocument есть несколько виртуальных функций, позволяющих настроить поведение документа в конкретном приложении. Некоторые из них практически всегда перегружаются в подклассах CDocument (табл. 9.2). Таблица 9.2. Часто используемые виртуальные функции CDocument
В SDI-приложении MFC создает объект-документ только один раз – при запуске приложения. При открытии/закрытии файлов этот объект используется повторно. Поэтому заведены две виртуальные функции – OnNewDocument и OnOpenDocument. MFC вызывает OnNewDocument при создании нового документа (например, при выборе команды меню ФайлÞСоздать). Функцию OnOpenDocument MFC вызывает при загрузке документа с диска (при выборе команды ФайлÞОткрыть). В SDI-приложении вы можете выполнить однократную инициализацию документа в конструкторе класса, а также выполнять специфическую инициализацию в перегруженных функциях OnNewDocument и/или OnOpenDocument. В MFC по умолчанию OnNewDocument и OnOpenDocument выполняют все основные действия по созданию новых документов или открытию существующих из файлов. Если вы перегрузите OnNewDocument или OnOpenDocument, то обязательно надо вызвать эти функции из базового класса, например:
В MFC-приложениях чаще перегружается OnNewDocument, а не OnOpenDocument. Т.к. OnOpenDocument неявно вызывает функцию документа Serialize, то в ней обычно и выполняется инициализация данных документа значениями из файла. В OnOpenDocument надо инициализировать только те данные, которые не сохраняются на диске, а они в приложениях есть не всегда. В отличие от этой функции, OnNewDocument по умолчанию никакой инициализации данных приложения не выполняет. Если вы добавите в класс документа какие-либо переменные-члены, то проинициализировать их для каждого нового документа можно в перегруженной функции OnNewDocument. Перед созданием или открытием нового документа, каркас приложения вызывает у объекта-документа виртуальную функцию DeleteContents, предназначенную для удаления текущего содержимого документа. Для непосредственного выполнения операций чтения/записи документа на диск, каркас вызывает функцию документа Serialize. Serialize должна быть реализована так, чтобы помещать данные документа в файловый поток или считывать их оттуда. Каркас приложения делает все остальное, в т.ч. открывает файл для чтения или записи и создает объект класса CArchive, представляющий файловый поток. Например, Serialize в подклассе CDocument обычно выглядит так:
В местах комментариев вы должны расположить операторы для чтения или записи данных документа в поток. Допустим, что в некотором объекте-документе хранятся две строки (объекты класса CString) с именами m_strName и m_strPhone. Тогда функция Serialize может быть написана примерно так:
Если данные вашего документа состоят из переменных основных типов и сериализуемых (для которых у CArchive перегружены операторы ввода/вывода) классов, например, CString, то написать функцию Serialize особенно просто – достаточно применить к каждой переменной оператор << и >>. Для сохранения структур и других несериализуемых типов данных можно пользоваться функциями CArchive::Read и CArchive::Write. В классе CArchive есть функции ReadString и WriteString для сериализации строк произвольной структуры (например, с сохранением пробелов). Если возможностей CArchive для сохранения документа недостаточно, можно вызывать функцию CArchive::GetFile и получить указатель на объект CFile, посредством которого можно напрямую обращаться к файлу, с которым связан поток CArchive. У CDocument есть и реже используемые виртуальные функции, например, OnCloseDocument (вызывается при закрытии документа) и OnSaveDocument (вызывается при сохранении документа).
Класс-вид Назначение объекта-документа – управление данными приложения. Объекты-виды выполняют две задачи: генерируют визуальное представление документа на экране и преобразуют сообщения от пользователя (в основном сообщения от мыши и клавиатуры) в команды, влияющие на данные документа. Следовательно, документы и виды тесно взаимосвязаны, и между ними происходит двунаправленный обмен информацией. В MFC основные свойства объектов-видов определены в классе CView. В MFC также есть набор подклассов CView, расширяющих его функциональные возможности, например, в CScrollView добавлены возможности прокрутки окна-вида. C объектом-документом может быть связано любое количество объектов-видов, но каждый вид принадлежит единственному документу. Каркас приложения хранит указатель на объект-документ в переменной-члене m_pDocument у каждого объекта-вида. Для доступа к этому указателю у объекта-вида есть функция-член GetDocument. Объект-документ может перебрать все связанные с ним виды, просматривая список функциями GetFirstViewPosition и GetNextView, а вид может получить указатель на свой документ простым вызовом GetDocument.
4.1 Виртуальные функции CView Как и у класса CDocument, у класса CView есть несколько виртуальных функций для настройки поведения конкретного объекта-вида (табл. 9.3). Самой важной функцией является OnDraw, которая вызывается объектом-видом при получении сообщения WM_PAINT. В приложениях, не поддерживающих архитектуру документ/вид, сообщения WM_PAINT обрабатываются в обработчиках OnPaint и рисование выполняется посредством объектов CPaintDC. В приложениях документ/вид сообщение WM_PAINT обрабатывается каркасом приложения. В этом обработчике создается объект CPaintDC и вызывается виртуальная функция объекта-вида OnDraw. Например, для вывода в центре окна-вида строки, хранящейся в объекте-документе, функция OnDraw может быть реализована так:
Обратите внимание, что OnDraw использует контекст устройства, переданный в функцию в качестве параметра, а не создает собственный контекст. Таблица 9.3. Важнейшие виртуальные функции CView
То, что окно-вид не создает собственного контекста устройства, вызвано не небольшим сокращением исходного текста, а тем, что каркас приложения использует одну и ту же функцию OnDraw и для вывода в окно, и при печати, и на предварительном просмотре перед печатью. В зависимости от выбранной пользователем команды, каркас приложения передает в OnDraw различные контексты устройства. Т.о. в приложениях документ/вид существенно упрощается вывод данных на принтер. Две других часто перегружаемых виртуальных функции CView –OnInitialUpdate и OnUpdate. Вид, как и документ, в SDI-приложении создается только один раз и затем многократно используется. В SDI-приложениях OnInitialUpdate вызывается каждый раз, когда документ создается или открывается с диска. По умолчанию OnInitialUpdate вызывает OnUpdate, а OnUpdate по умолчанию объявляет все окно-вид недействительным для его перерисовки. В OnInitialUpdate удобно поместить инициализацию переменных-членов окна-вида, а также другие операции инициализации, необходимые при заведении нового документа. Например, в подклассах CScrollView в OnInitialUpdate обычно вызывается функция-член SetScrollSizes для задания границ полос прокрутки. В OnInitialUpdate надо вызывать функцию-член базового класса, иначе окно-вид не будет перерисовано. OnUpdate вызывается, когда происходит изменение данных документа, а также когда кто-нибудь (документ или один из видов) вызывает функцию документа UpdateAllViews. OnUpdate иногда перегружается для ускорения перерисовки с учетом границ областей, связанных с изменившимися данными документа. В MDI-приложениях видов документа может быть несколько, и один из них является активным, а остальные – неактивными. Фокус ввода принадлежит активному виду. Для отслеживания, когда вид становится активным или неактивным, в нем можно перегрузить функцию CView::OnActivateView. Окно-рамка может получить указатель на активный вид или сделать какой-либо вид активным функциями CFrameWnd::GetActiveView и CFrameWnd::SetActiveView.
5. Класс "окно-рамка" До сих пор было рассмотрено назначение трех объектов: приложение, документ и вид. Осталось рассмотреть еще один объект – окно-рамку, которое определяет рабочую область приложения на экране и служит контейнером для вида. В SDI-приложении есть только одно окно-рамка подкласса CFrameWnd, которое служит главным окном приложения и содержит внутри себя окно-вид. В MDI-приложениях есть окна-рамки двух типов – CMDIFrameWnd для главного окна и CMDIChildWnd для окон-видов. Окна-рамки очень важны для приложений документ/вид. Это не просто главное окно приложения, а объект, который реализует значительную часть функциональности приложения документ/вид. Например, в классе CFrameWnd есть обработчики OnClose и OnQueryEndSession, которые дают пользователю возможность записать несохраненный документ перед завершением приложения или перед закрытием Windows. В CFrameWnd реализовано автоматическое изменение окна-вида при изменении размеров окна-рамки с учетом панелей инструментов, строки состояния и других компонент пользовательского интерфейса. В нем есть также функции-члены для работы с панелями инструментов, строкой состояния, для получения активного документа и видов и др. Для лучшего понимания роли класса CFrameWnd можно сравнить его с общим классом окна CWnd. Класс CWnd – это оболочка на языке Си++ для работы с окном Windows. CFrameWnd унаследован от CWnd и в нем добавлено много новых средств, выполняющих типичные действия в приложениях документ/вид.
|
||||||||||||||||||||||||||||||||||||||||||||||
|
Последнее изменение этой страницы: 2016-08-01; просмотров: 558; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.217.21 (0.009 с.) |