Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Сопоставление сообщений в библиотеке MFC
Вспомним функцию-член OnLButtonDown из предыдущего примера. Можно подумать, что OnLButtonDown — идеальный кандидат на роль виртуальной функции. При таком подходе базовый класс определил бы виртуальные функции для сообщений о событиях, связанных с мышью, и других стандартных сообщений, а производные классы окна могли бы при необходимости переопределять эти функции. Некоторые библиотеки классов для Windows именно так и устроены. Но каркас приложений библиотеки MFC не использует виртуальные функции для сообщений Windows. Вместо этого с помощью макросов он соотносит (mapping) определенные сообщения с функциями-членами производных классов. Чем же объясняется отказ от виртуальных функций? Представьте себе, что виртуальные функции для сообщений в MFC все-таки используются. Класс CWnd должен был бы объявлять виртуальные функции более чем для 100 сообщений. Для каждого производного класса, задействованного в программе, C++ требует наличия таблицы диспетчеризации виртуальных функций (vtable) (виртуальная таблица). Для каждой виртуальной функции в этой таблице потребуется 4-байтовая запись — независимо от того, переопределена ли функция в производном классе на самом деле. Таким образом, для каждого типа окна или элемента управления приложению для поддержки виртуальных обработчиков сообщений нужна таблица размером более 400 байтов. А как насчет обработчиков сообщений о командах меню и щелчках кнопок мыши? Их не определишь как виртуальные функции в базовом классе, поскольку в каждом приложении может быть свой набор команд меню и кнопок. Система таблиц сообщений, принятая в библиотеке MFC, позволяет обойтись без длинных виртуальных таблиц и сглаживает различия между обычными Windows-сообщениями и командными сообщениями, специфичными для программ. Поэтому отдельные классы, отличные от оконных (классы «документ» и «приложение»), могут обрабатывать и командные сообщения. Для сопоставления (или увязки) сообщений Windows с функциями-членами C++ в MFC используются макросы. Никакие расширения языка C++ не нужны. MFC-обработчик сообщения требует наличия прототипа функции, тела функции и соответствующей записи в таблице сообщений. Вставлять обработчики сообщений в классы помогает ClassWizard. Вы выбираете идентификатор Windows-сообщения из списка, a ClassWizard генерирует код с необходимыми параметрами функций и возвращаемыми значениями.
Документы и их представление В предыдущем примере мы использовали объект «приложение» и объект окно-рамка (frame window object). Но большинство ваших приложений на базе библиотеки MFC будут гораздо сложнее. Как правило, в них, помимо только что упомянутых классов, будут содержаться еще два класса: «документ» (document) и «вид» или «представление» (view). Такая архитектура «документ-вид» — стержень каркаса приложений; она напоминает классы Model/View/Controller, принятые в среде Smalltalk. Проще говоря, архитектура «документ-вид» отделяет данные от их представления. Очевидное преимущество этого подхода — возможность представить одни и те же данные по-разному. Предположим, на диске хранится документ с биржевыми сводками за месяц, а данные представлены в виде таблицы и графика. Мы изменяем значения в окне табличного представления, и содержимое окна графического представления тоже изменяется, потому что оба окна отображают одну и ту же информацию (но представленную в разных видах). В библиотеке MFC документам и их представлениям сопоставляются экземпляры (instances) классов C++. Например, на рис. 5.1 показаны три объекта класса CStockDoc, соответствующие фирмам: AT&T, IBM и GM. Все три документа связаны с табличным представлением, а один из них — еще и с графическим. Как видите, здесь четыре объекта «вид» (они в правой части рис. 5.1): три объекта класса CStockListView и один — класса CStockChartView. Код базового класса «документ» взаимодействует с командами Open и Save меню File; действительное чтение и запись данных объекта «документ» реализуют производные классы «документ». (Каркас приложений берет на себя большую часть работы по выводу на экран диалоговых окон File и File Save, а также по открытию, закрытию, чтению и записи файлов.) Базовому классу «вид» сопоставлено окно, содержащееся внутри окна-рамки; производный класс «вид» взаимодействует со своим, сопоставленным ему классом «документ» и отвечает за вывод информации на экран и принтер. Производный класс «вид» и его базовые классы обрабатывают сообщения Windows. Библиотека MFC «дирижирует» всеми взаимосвязями между документами, их представлениями, окнами и объектом «приложение» в основном за счет виртуальных функций. Не подумайте, что объект «документ» должен быть связан с дисковым файлом, целиком считываемым в память. Если, например, «документ» — на самом деле база данных, Вы можете переопределить выбранные функции-члены класса «документ», и тогда команда Open меню File будет выдавать вместо списка файлов список баз данных.
Рис. 5.1. Взаимосвязь документов и их представления
|
|||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 425. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |