Партнерка на США и Канаду по недвижимости, выплаты в крипто
- 30% recurring commission
- Выплаты в USDT
- Вывод каждую неделю
- Комиссия до 5 лет за каждого referral
3.2 Виртуальные функции CDocument
В CDocument есть несколько виртуальных функций, позволяющих настроить поведение документа в конкретном приложении. Некоторые из них практически всегда перегружаются в подклассах CDocument (табл. 9.2).
Таблица 9.2. Часто используемые виртуальные функции CDocument
Функция-член | Описание |
OnNewDocument | Вызывается изнутри каркаса при создании нового документа. Перегружается для выполнения специфической инициализации, необходимой при создании каждого нового документа. |
OnOpenDocument | Вызывается каркасом при загрузке документа из файла. |
DeleteContents | Вызывается каркасом для удаления содержимого документа. Перегружается для освобождения памяти и других ресурсов, выделенных объекту-документу. |
Serialize | Вызывается каркасом для записи/чтения данных документа из файла. Перегружается почти всегда, чтобы документы можно было хранить в файлах. |
В SDI-приложении MFC создает объект-документ только один раз – при запуске приложения. При открытии/закрытии файлов этот объект используется повторно. Поэтому заведены две виртуальные функции – OnNewDocument и OnOpenDocument. MFC вызывает OnNewDocument при создании нового документа (например, при выборе команды меню ФайлÞСоздать). Функцию OnOpenDocument MFC вызывает при загрузке документа с диска (при выборе команды ФайлÞОткрыть). В SDI-приложении вы можете выполнить однократную инициализацию документа в конструкторе класса, а также выполнять специфическую инициализацию в перегруженных функциях OnNewDocument и/или OnOpenDocument.
В MFC по умолчанию OnNewDocument и OnOpenDocument выполняют все основные действия по созданию новых документов или открытию существующих из файлов. Если вы перегрузите OnNewDocument или OnOpenDocument, то обязательно надо вызвать эти функции из базового класса, например:
BOOL CMyDoc::OnNewDocument () { if ( !CDocument::OnNewDocument() ) return FALSE; // Некоторые действия по инициализации данных документа return TRUE; } BOOL CMyDoc::OnOpenDocument( LPCTSTR lpszPathName ) { if ( !CDocument::OnOpenDocument( lpszPathName ) ) return FALSE; // Некоторые действия по инициализации данных документа return TRUE; } |
В MFC-приложениях чаще перегружается OnNewDocument, а не OnOpenDocument. Т. к. OnOpenDocument неявно вызывает функцию документа Serialize, то в ней обычно и выполняется инициализация данных документа значениями из файла. В OnOpenDocument надо инициализировать только те данные, которые не сохраняются на диске, а они в приложениях есть не всегда. В отличие от этой функции, OnNewDocument по умолчанию никакой инициализации данных приложения не выполняет. Если вы добавите в класс документа какие-либо переменные-члены, то проинициализировать их для каждого нового документа можно в перегруженной функции OnNewDocument.
Перед созданием или открытием нового документа, каркас приложения вызывает у объекта-документа виртуальную функцию DeleteContents, предназначенную для удаления текущего содержимого документа.
Для непосредственного выполнения операций чтения/записи документа на диск, каркас вызывает функцию документа Serialize. Serialize должна быть реализована так, чтобы помещать данные документа в файловый поток или считывать их оттуда. Каркас приложения делает все остальное, в т. ч. открывает файл для чтения или записи и создает объект класса CArchive, представляющий файловый поток. Например, Serialize в подклассе CDocument обычно выглядит так:
void CMyDoc::Serialize( CArchive& ar ) { if ( ar. IsStoring() ) { // Запись данных документа в поток ar } else { // Чтение данных документа из потока ar } } |
В местах комментариев вы должны расположить операторы для чтения или записи данных документа в поток. Допустим, что в некотором объекте-документе хранятся две строки (объекты класса CString) с именами m_strName и m_strPhone. Тогда функция Serialize может быть написана примерно так:
void CMyDoc::Serialize( CArchive& ar ) { if ( ar. IsStoring() ) { // Запись в файловый поток ar << m_strName << m_strPhone; } else { // Чтение из файлового потока ar >> m_strName >> m_strPhone; } } |
Если данные вашего документа состоят из переменных основных типов и сериализуемых (для которых у CArchive перегружены операторы ввода/вывода) классов, например, CString, то написать функцию Serialize особенно просто – достаточно применить к каждой переменной оператор << и >>. Для сохранения структур и других несериализуемых типов данных можно пользоваться функциями CArchive::Read и CArchive::Write. В классе CArchive есть функции ReadString и WriteString для сериализации строк произвольной структуры (например, с сохранением пробелов). Если возможностей CArchive для сохранения документа недостаточно, можно вызывать функцию CArchive::GetFile и получить указатель на объект CFile, посредством которого можно напрямую обращаться к файлу, с которым связан поток CArchive.
У CDocument есть и реже используемые виртуальные функции, например, OnCloseDocument (вызывается при закрытии документа) и OnSaveDocument (вызывается при сохранении документа).
4. Класс-вид
Назначение объекта-документа – управление данными приложения. Объекты-виды выполняют две задачи: генерируют визуальное представление документа на экране и преобразуют сообщения от пользователя (в основном сообщения от мыши и клавиатуры) в команды, влияющие на данные документа. Следовательно, документы и виды тесно взаимосвязаны, и между ними происходит двунаправленный обмен информацией.
В 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 может быть реализована так:
void CMyView::OnDraw( CDC* pDC ) { CMyDoc* pDoc = GetDocument(); CString string = pDoc->GetString(); CRect rect; GetClientRect( &rect ); pDC->DrawText( string, rect, DT_SINGLELINE ¦ DT_CENTER ¦ DT_VCENTER ); } |
Обратите внимание, что OnDraw использует контекст устройства, переданный в функцию в качестве параметра, а не создает собственный контекст.
Таблица 9.3. Важнейшие виртуальные функции CView
Функция-член | Описание |
OnDraw | Вызывается для рисования данных документа внутри окна-вида. |
OnInitialUpdate | Вызывается при присоединении окна-вида к объекту-документу. Перегружается для инициализации вида при загрузке документа из файла или при создании нового документа. |
OnUpdate | Вызывается при любом изменении данных документа, когда необходимо перерисовать окно-вид. Перегружается для реализации "интеллектуального" обновления окна-вида, когда перерисовывается не все окно, а только некоторая часть, связанная с измененными данными. |
То, что окно-вид не создает собственного контекста устройства, вызвано не небольшим сокращением исходного текста, а тем, что каркас приложения использует одну и ту же функцию OnDraw и для вывода в окно, и при печати, и на предварительном просмотре перед печатью. В зависимости от выбранной пользователем команды, каркас приложения передает в OnDraw различные контексты устройства. Т. о. в приложениях документ/вид существенно упрощается вывод данных на принтер.
Две других часто перегружаемых виртуальных функции CView –OnInitialUpdate и OnUpdate. Вид, как и документ, в SDI-приложении создается только один раз и затем многократно используется. В SDI-приложениях OnInitialUpdate вызывается каждый раз, когда документ создается или открывается с диска. По умолчанию OnInitialUpdate вызывает OnUpdate, а OnUpdate по умолчанию объявляет все окно-вид недействительным для его перерисовки. В OnInitialUpdate удобно поместить инициализацию переменных-членов окна-вида, а также другие операции инициализации, необходимые при заведении нового документа. Например, в подклассах CScrollView в OnInitialUpdate обычно вызывается функция-член SetScrollSizes для задания границ полос прокрутки. В OnInitialUpdate надо вызывать функцию-член базового класса, иначе окно-вид не будет перерисовано.
|
Из за большого объема этот материал размещен на нескольких страницах:
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 |


