Партнерка на США и Канаду по недвижимости, выплаты в крипто
- 30% recurring commission
- Выплаты в USDT
- Вывод каждую неделю
- Комиссия до 5 лет за каждого referral
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 и в нем добавлено много новых средств, выполняющих типичные действия в приложениях документ/вид.
6. Динамическое создание объектов
Чтобы каркас приложения мог автоматически создавать объекты документ, вид, и окно-рамку, эти классы должны поддерживать специальную возможность MFC – динамическое создание (dynamic creation). Для описания динамически создаваемых классов в MFC предназначены два макроса – DECLARE_DYNCREATE и IMPLEMENT_DYNCREATE. Они применяются следующим образом:
1) Создается подкласс CObject.
2) В интерфейсной части класса записывается макрос DECLARE_DYNCREATE. Ему указывается один параметр – имя динамически создаваемого класса.
3) В реализации класса размещается вызов макроса IMPLEMENT_DYNCREATE с двумя параметрами – именем динамически создаваемого класса и именем его родительского класса.
Объект динамически создаваемого класса можно создавать так:
RUNTIME_CLASS( CMyClass )->CreateObject(); |
Этот вызов в приложении по сути приводит к вызову оператора new. Этот механизм сделан, поскольку в Си++ нельзя динамически создавать объекты по имени класса, которое хранится в какой-либо переменной, например:
CString strClassName = "CMyClass"; CMyClass* ptr = new strClassName; // Так объект CMyClass создать нельзя |
Механизм динамического создания класса MFC позволяет зарегистрировать классы так, что каркас приложения сможет автоматически создавать объекты этих классов.
Макрос DECLARE_DYNCREATE добавляет в описание класса три компонента: статическую переменную CRuntimeClass, виртуальную функцию GetRuntimeClass и статическую функцию CreateObject. Например, если записать в интерфейсе класса:
DECLARE_DYNCREATE( CMyClass ) |
то препроцессор Си++ раскроет этот макрос так:
public: static const AFX_DATA CRuntimeClass classCMyClass; virtual CRuntimeClass* GetRuntimeClass() const; static CObject* PASCAL CreateObject(); |
Макрос IMPLEMENT_DYNCREATE обеспечивает инициализацию структуры CRuntimeClass (информацией вроде имени класса и размера объекта класса) и создает функции GetRuntimeClass и CreateObject. Допустим, IMPLEMENT_DYNCREATE вызывается так:
IMPLEMENT_DYNCREATE( CMyClass, CBaseClass ) |
Тогда CreateObject будет реализована так:
CObject* PASCAL CMyClass::CreateObject() { return new CMyClass; } |
6.1 Назначение шаблона SDI-документа
При рассмотрении функции CWinApp::InitInstance уже встречался вызов для создания объекта CSingleDocTemplate – шаблона SDI-документа. Конструктору CSingleDocTemplate передаются 4 параметра: целочисленный идентификатор (IDR_MAINFRAME) и три указателя RUNTIME_CLASS. Сначала опишем смысл первого параметра. Это идентификатор ресурса, который присвоен ресурсам четырех типов:
· пиктограмма (значок) приложения;
· верхнее меню приложения;
· таблица ускоряющих клавиш для команд верхнего меню;
· строка параметров документа (document string), которая задает, в частности, расширение файлов документов "по умолчанию" и имя "по умолчанию" для новых документов.
В SDI-приложениях каркас создает главное окно приложения как окно-рамку класса, который указан в шаблоне документа. Затем у окна-рамки вызывается функция-член LoadFrame. Ей передается идентификатор ресурса, указывающий на ресурсы перечисленных выше типов. LoadFrame загружает все эти ресурсы, но чтобы это получилось удачно, действительно в RC-файле должны быть такие ресурсы с одинаковыми идентификаторами (AppWizard генерирует их автоматически).
В строке параметров документа отдельные параметры хранятся в подстроках, отделенных друг от друга служебными символами "\n". В порядке "слева-направо" могут быть указаны следующие параметры:
· Текст заголовка окна-рамки. Обычно это название приложения, например, "Microsoft Draw".
· Имя, присваиваемое новым документам. Если эта подстрока не заполнена (сразу идет "\n"), то в качестве имени будет использоваться "Untitled".
· Краткое описание типа документа, которое выводится в диалоговом окне по команде FileÞNew в MDI-приложениях, чтобы пользователь мог выбрать один из нескольких документов. В SDI-приложениях не используется.
· Краткое описание типа документа с маской имени файла, например, "Drawing Files (*.drw)". Эта подстрока используется в диалоговых окна открытия и сохранения файлов.
· Расширение имени файла "по умолчанию", например, ".drw".
· Имя без пробелов, идентифицирующее тип документа в реестре, например, "Draw. Document". Если приложение вызовет CWinApp::Register - ShellFileTypes для регистрации типа документа в оболочке Windows,. то эта подстрока запишется в реестр в раздел HKEY_CLASSES_ROOT после расширения имени файла документа.
· Краткое описание типа документа, например, "Microsoft Draw Document". Может содержать пробелы. Если приложение выполнит регистрацию типа документа вызовом CWinApp::RegisterShellFileTypes, то это описание будет выводиться в качестве типа файла в его окне свойств (например, в программе Проводник).
В строке параметров документа необязательно указывать все семь подстрок, некоторые можно пропускать, только ставить для них разделитель "\n". При генерации приложения с помощью AppWizard строка параметров документа создается автоматически на основе данных из диалогового окна Advanced Options, которое можно вызвать на 4-м шаге создания приложения (AppWizard's Step 4). Типичная строка параметров документа для SDI-приложения в RC-файле выглядит так:
STRINGTABLE BEGIN IDR_MAINFRAME "Microsoft Draw\n\n\nDraw Files(*.drw)\n. drw\n Draw. Document\nMicrosoft Draw Document" END |
В данном примере после запуска окно-рамка будет иметь заголовок "Untitled - Microsoft Draw". Расширение имени файла "по умолчанию" для документов приложения – ".drw", а в окнах открытия и сохранения файла будет выбрана строка типа файлов "Draw Files (*.drw)".
7. Маршрутизация командных сообщений
Одна из наиболее заметных особенностей архитектуры документ/вид в том, что приложение может обрабатывать командные сообщения "почти везде". Командными сообщениями (command messages) в MFC называются сообщения WM_COMMAND, которые генерируются после выбора команд меню, по нажатию ускоряющих клавиш и при нажатии кнопок панелей инструментов. Окно-рамка – это физический получатель большинства командных сообщений, но их можно также обрабатывать в окне-виде, в документе или даже в объекте-приложении. Для этого надо только добавить соответствующие записи в карту сообщений класса. Маршрутизация команд позволяет помещать командные обработчики там, где их разумнее разместить по структуре приложения, а не собирать все обработчики в классе окна-рамки. Обработчики обновления для команд меню, панелей инструментов и других компонент пользовательского интерфейса также включены в механизм маршрутизации, поэтому вы можете помещать обработчики ON_UPDATE_COMMAND_UI за пределами окна-рамки.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |


