Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Функции взаимодействия «документ-вид»
Вы уже знаете, что объект «документ» содержит данные, а объект «вид» представляет их на экране и позволяет редактировать. В SDI-приложении есть класс «документ», производный от CDocument и один или несколько классов «вид», каждый из которых, в конечном счете происходит от CView. Документ, окно представления и остальные элементы каркаса приложений взаимодействуют весьма тесно. Чтобы в этом разобраться, надо познакомиться с пятью важными функциями-членами классов «документ» и «вид». Две из них — невиртуальные функции базового класса, вызываемые производными классами, остальные — виртуальные функции, часто переопределяемые в производных классах. Рассмотрим их по порядку. Функция CView::GetDocument
С объектом «вид» связан один и только один объект «документ». Функция GetDocument() позволяет выяснить, какому документу сопоставлено данное окно представления. Допустим, объект «вид» получил сообщение о том, что пользователь ввел новые данные в поле ввода. Он должен уведомить об этом документ, чтобы тот обновил свои внутренние данные. GetDocument возвращает указатель на документ; через этот указатель можно обращаться к функциям-членам или открытым переменным-членам класса «документ».
Генерируя класс, производный от CView, мастер создает специальную версию функции GetDocument() для безопасного приведения типов; она возвращает указатель не на CDocument, a на объект производного класса. Эта подставляемая (inline) функция выглядит примерно так: CMyDoc * GetDocument() { return (CMyDoc*) m_pDocument; }
Встретив в коде вашего класса «вид» вызов GetDocument(), компилятор использует версию из производного класса, а не из CDocument, поэтому Вам не надо приводить указатель к производному классу документа.
Функция CDocument::UpdateAllViews
Если содержание документа по какой-либо причине изменилось, надо уведомить об этом все объекты «вид», чтобы те обновили представление данных. При вызове UpdateAllViews() из функции-члена производного класса документа ее первый параметр pSender равен NULL. Если же она вызывается посредством функции-члена производного класса «вид», параметр pSender указывает на текущий объект «вид»: GetDocument()->UpdateAllViews(this);
Значение параметра, отличное от NULL, позволяет каркасу приложений не уведомлять текущий объект «вид» — предполагается, что он уже обновился сам. У этой функции есть необязательные параметры, через которые можно передавать объекту специфичную для приложения информацию о том, какие части представления следует обновить. Как именно уведомляется объект при вызове UpdateAllViews()? Для ответа на этот вопрос сначала рассмотрим другую функцию — OnUpdate.
Функция CView::OnUpdate
Это виртуальная функция, вызываемая каркасом приложений в ответ на вызов вашей программой функции UpdateAllViews(). Конечно, Вы можете вызывать ее прямо в своем классе, производном от CView. Обычно функция OnUpdate() из производного класса обращается к документу и, получив его обновленные данные, либо обновляет переменные-члены класса или соответствующие элементы управления, либо объявляет часть представления недействительной, что заставляет функцию OnDraw() перерисовать часть окна по данным документа. Реализация функции OnUpdate() может выглядеть примерно так: void CMyView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint){ CMyDocument* pMyDoc = GetDocument(); CString lastName = pMyDoc->GetLastName(); m_pNameStatic->SetWindowText(lastName); // m_pNameStatic является членом // класса CMyView}
Вспомогательная информация передается (последние два параметра) в эту функцию функцией UpdateAllViews(). Исходная реализация OnUpdate() объявляет недействительным все окно представления. В переопределенной версии Вы можете объявить недействительным прямоугольник меньшего размера — в соответствии с информацией, полученной от UpdateAllViews (через последние два параметра). Если CDocument-функция UpdateAllViews() вызывается с параметром pSender, указывающим на конкретный объект «вид», то OnUpdtae() вызывается для всех представлений документа, кроме заданного в параметре.
Функция CView::OnInitialUpdate
Эта виртуальная функция класса CView вызывается при запуске приложения, а также при выборе команд New или Open меню File. Версия OnInitialUpdate() в базовом классе CView просто вызывает OnUpdate. Если Вы переопределили ее в своем производном классе, убедитесь, что она вызывает OnInitialUpdate() базового класса или OnUpdate() производного класса. Функция OnInitialUpdate() производного класса пригодна для инициализации объекта «вид». При запуске программы каркас приложений вызывает OnInitialUpdate() сразу после вызова OnCreate(), если Вы задействовали OnCreate() в своем производном классе «вид». Функция OnCreate() вызывается только один раз, но OnInitialUpdate() можно вызывать сколько угодно раз.
Функция CDocument::OnNewDocument
Эту виртуальную функцию каркас приложений вызывает после создания объекта «вид» или выбора в меню File SDI-приложения команды New. Именно здесь удобнее всего инициализировать переменные-члены вашего класса «документ». Для производного класса документа мастер генерирует переопределенную функцию OnNewDocument(). Обязательно оставьте в ней вызов функции базового класса. Простейшее приложение на базе архитектуры «документ-вид»
Допустим, Вам не нужно несколько представлений документа, но необходима поддержка каркаса приложений для работы с файлами. Тогда забудьте о функциях UpdateAllViews() и OnUpdate() и придерживайтесь следующей простой схемы.
В нашей упрощенной среде «документ-вид» события будут разворачиваться в такой последовательности:
Класс CObject
Если посмотреть на иерархию MFC-классов, что на ее вершине находится класс CObject. Остальные классы, кроме CString и таких простых, как CRect и CPoint, — производные от корневого класса CObject. Класс, производный от CObject, наследует ряд важных характеристик. Многие преимущества этого станут очевидны при дальнейшем изучении классов MFC. В этом разделе мы рассмотрим, как наследование от CObject позволяет задействовать объекты в организации вывода диагностической информации, а также включать их в классы наборов (collection classes). |
|||||||||||||||||||||||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 605. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |