Рисование, печать и предварительный просмотр

   
На этом шаге мы рассмотрим общие положения, связанные в выводом информации на различные устройства.

   
На этом шаге мы расскажем, какие возможности отображения данных на устройства вывода - экран и принтер -
предоставляет класс CView.
Контекст устройства и GDI

   
В Windows приложения и устройства вывода взаимодействуют п другом посредством интерфейса
графических устройств (Graphics Device Interface, GDI). Его использование гарантирует правильный вывод
на все GDI-совместимые устройства.

   
GDI управляет структурой данных, называемой контекстом устройства, которая содержит информацию о текущих
атрибутах данного устройства. В нее можно включить информацию о цветовой палитре, шрифтах, толщине пера, рисующего
линии, типе кисти, закрашивающей области. В Windows API есть GDI-функции для рисования линий и
других геометрических фигур, для закрашивания областей и печати текста. Все эти функции осуществляют вывод на контекст
устройства, описатель которого передается в качестве параметра.

   
В MFC контекст устройства и многие функции GDI инкапсулирует класс CDC. В нем представлены
функции создания и инициализации контекста устройства, а также функции рисования. Помимо класса CDC существует
масса специализированных классов, производных от него (таблица 1).

Таблица 1. Классы, производные от CDC

КлассОписание
CPaintDCИнкапсулирует контекст устройства, подготовленный для перерисовки недействительной области окна при получении сообщения WM_PAINT.
Конструктор этого класса вызывает функцию CWnd::BeginPaint(), которая создает контекст устройства и подготавливает клиентскую область к
графическому выводу. Для очистки памяти из деструктора вызывается функция CWnd::EndPaint()
CClientDCОписывает контекст устройства, представляющего клиентскую область окна
CWindowDCИнкапсулирует контекст устройства, представляющего все окно вместе с рамкой
CMetafileDCСодержит набор структур, хранящих изображение в аппаратно-независимом формате, который необходим при рисовании в метафайл Windows

Рисование в представлении

   
Графический вывод данных приложения осуществляется функцией-членом объекта представления OnDraw(). В производном от CView
классе, котьорый создал мастер АррWizard, имеется функция-заглушка OnDraw(). К ней можно
добавлять свой код для отображения данных. Она выглядит следующим образом:

void CMyAppView::OnDraw(CDC* pDC)
{
	CMyAppDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

   
Обратите внимание на то, что в эту функцию передается указатель на объект CDC. Он необходим для вызова рисующих функций контекста устройства.
Кроме того, функция OnDraw() получает указатель на объект документа, который Вы можете использовать для обращения к данным приложения.

   
Приведем простую реализацию функции OnDraw().

  • Реализация функции OnDraw().
  • Перейдите в проект МуАрр.
  • В окне ClassView щелкните правой кнопкой значок класса CMyAppDoc.
  • В появившемся контекстном меню выберите пункт Add Member Variable.
    Рис.1. Выбор пункта Add Member Variable
  • В диалоговом окне Add Member Variable в поле Variable Type введите CString и в поле Variable Name - m_string.
  • Оставьте переключатель Access установленным в Public и, чтобы создать переменную, щелкните кнопку ОК.
    Рис.2. Создание переменной
  • Раскройте ветвь CMyAppDoc и убедитесь, что переменная m_string была добавлена в класс.
  • Найдите значок конструктора класса CMyAppDoc (он находится под значком самого класса и называется CMyAppDoc).
    Обратите внимание на значок, изображающий ключ, рядом с названием функции. Он показывает, что данная функция является
    защищенным членом класса. Для перехода к редактированию конструктора дважды щелкните его значок.


    Рис.3. Выбор конструктора

  • Добавьте в конструктор следующую строку: m_string = "Hello, World!";
    Рис.4. Добавление строки
  • Раскройте узел CMyAppView. Перейдите к редактированию функции OnDraw(), дважды щелкнув ее значок.
  • Вместо комментария, начинающегося с //TODO, добавьте в функцию OnDraw() следующий код:
        CSize TextSize = pDC->GetTextExtent(pDoc->m_string); 
        CRect rect(10,10, 10+TextSize.cx,10+TextSize.cy); 
        rect.InflateRect(4,4);
    
        pDC->Rectangle(&rect); 
        pDC->TextOut(10,10,pDoc->m_string);
    


    Рис.5. Функция OnDraw()

  • Соберите и запустите программу. Проверьте, отображается ли в левом верхнем углу прямоугольник с надписью "Hello World!".

Текст измененного приложения можно взять здесь (39 Кб).

   
Выводы:

  • для вывода на экран функциям-членам класса СDC необходим указатель на контекст устройства;
  • указатель на документ используется для получения данных приложения;
  • код рисования создается так, чтобы при изменении данных они во всех случаях отображались корректно - в данном примере прямоугольник
    всегда обрамляет текст. Попробуйте изменить строку CMyAppDoc::m_string на более длинную, перекомпилируйте программу и запустите ее -
    все элементы отображаются правильно.

Вызов функции OnDraw() каркасом приложения

   
Если изменение данных документа может повлиять на их отображение, то представление должно быть перерисовано.
Обычно такое происходит при внесении пользователем изменений в представление. При этом код, обновляющий
данные документа, должен вызывать функцию-член класса документа UpdateAllViews(), уведомляющую все
представления о необходимости перерисовки.

   
Функция UpdateAllViews() вызывает функцию-член каждого представления OnUpdate(). По умолчанию
при этом перерисовывается вся клиентская область представления. Вы можете переопределить эту
функцию так, что перерисовываться будут только те части окна, в которых произошло изменение.

   
Когда представление становится недействительным, Windоws сылает ему сообщение WM_PAINT. Обработчик
этого cooбщения OnPaint() создает контекст устройства на основе класса CPaintDC и
передает его в функцию OnDraw().
Печать и предварительный просмотр

   
В программировании для Windows практически не существует разницы между выводом на экран и на принтер, потому что
GDI - аппаратно-независимый интерфейс. Одни и те же функции могут использоваться для отображения на экран и
для печати на принтер в зависимости от контекста устройства. Если объект класса CDC, который получает функция OnDraw(),
представляет принтер, то и вывод выполняется на него.

   
Библиотека MFC позволяет осуществить печать документа. Каркас приложения сам отображает диалоговое окно Print и создает
контекст устройства для принтера. При выборе пункта Print в меню File представление передает этот контекст устройства
в функцию OnDraw(), которая и осуществляет вывод.


Рис.6. Вызов каркасом приложения функции OnDraw()

   
Однако между выводом на принтер и на экран есть существенные различия. При печати документ должен быть разделен на страницы,
поэтому Вам необходимо знать размер листа бумаги. Кроме того важна на ориентация листа (книжная или альбомная). Для этого в
классе CView предусмотрены специальные функции.

   
На следующем шаге мы рассмотрим конкретный пример приложения в архитектуре "документ/вид".



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий