Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 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