Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Что такое класс представления




Как уже упоминалось, класс представления отвечает за вывод на экран данных, хранящихся в объекте класса документа, и позволяет пользователю модифицировать эти данные. Объект класса представления содержит указатель на объект класса документа, который используется для доступа к членам-переменным этого класса, где собственно и хранятся данные. Листинг 4.2 содержит текст файла заголовка, который AppWizard сформировал для класса CApplView.

Большинство программистов, имеющих дело с MFC, включают в класс документа открытые (public) члены с тем, чтобы не затруднять доступ к ним из объекта класса представления. Классический объектно-ориентированный подход, однако, требует включать в класс закрытые (private) или защищенные (protected) члены-переменные и открытые члены-функции считывания и модификации этих переменных.

 


// App1View.h : interface of the CApp1View class

//

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_APP1VIEW_H__528CF70E_0F96_11D7_BBD4_00C0F6B2220A

__INCLUDED_)

#define AFX_APP1VIEW_H__528CF70E_0F96_11D7_BBD4_00C0F6B2220A__INCLUDED_

 

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

 

class CApp1View : public CView

{

protected: // create from serialization only

CApp1View();

DECLARE_DYNCREATE(CApp1View)

 

// Attributes

public:

CApp1Doc* GetDocument();

 

// Operations

public:

 

// Перегрузка.

// ClassWizard генерирует перегрузку виртуальных функций

//{{AFX_VIRTUAL(CApp1View)

public:

virtual void OnDraw(CDC* pDC); // Перегружена для прорисовки

// в этом представлении.

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);

virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

//}}AFX_VIRTUAL

 

// Implementation

public:

virtual ~CApp1View();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

 

protected:

 

// Сформированные функции карты сообщений

protected:

//{{AFX_MSG(CApp1View)

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

#ifndef _DEBUG // debug version in App1View.cpp

inline CApp1Doc* CApp1View::GetDocument()

{ return (CApp1Doc*)m_pDocument; }

#endif

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ будет вставлять дополнительные объявления

// непосредственно перед предыдущей строкой

 

#endif // !defined(AFX_APP1VIEW_H__528CF70E_0F96_11D7_BBD4_

00C0F6B2220A__INCLUDED_)

 


Почти в самом начале текста имеется секция открытых атрибутов, в которой объявлена функция GetDocument(), возвращающая указатель на объект класса CApplDoc. Если, работая с классом представления, вы пожелаете получить указатель на объект класса документа, нужно будет вызвать эту функцию и она вернет вам требуемый указатель. Например, для того чтобы добавить объект класса СРоint в массив таких объектов, который является членом класса документа, можно использовать следующий оператор:

 

GetDocument()->m_points[x] = point;

 

Можно сделать то же самое, запомнив указатель, возвращаемый GetDocument(), в локальной переменной, а затем уже использовать ее для доступа к данным документа:

pDoc = GetDocument();

pDoc-> m_points[x] = point;

 

Второй вариант имеет смысл, если вы будете неоднократно использовать сохраненный указатель в функции или если выражение в форме GetDocument()-> переменная кажется вам сложным для восприятия в тексте программы.

В распространяемой (release) версии приложения функция GetDocument() объявлена как встроенная (inline). В смысле производительности программы нет никакой разницы в обеих формах обращения к членам объекта документа. Но в смысле читабельности текста программы второй вариант, несомненно, имеет преимущество. Встроенные функции расширяются в скомпилированной программе также, как и макросы, но, в отличие от макросов, компилятор при работе со встроенными функциями выполняет проверку типов аргументов.

Обратите внимание на то, что как класс представления, так и класс документа перегружают часть функций-членов своих базовых классов. Функция OnDraw() является одной из важнейших среди всех виртуальных функций, она является именно тем инструментом, с помощью которого производится рисование в окне приложения. Что касается других функций, то MFC вызывает PreCreateWindow() перед тем, как создается и присоединяется к объекту класса окон MFC окно Windows. Эта функция дает возможность модифицировать такие атрибуты окна, как положение и размер. Функция OnPreparePrinting() используется для модификации диалогового окна Print перед его выводом на экран. Функция OnBeginPrinting() дает шанс создать GDI-объект, такой как кисть или перо, который необходим для выполнения некоторых задач в процессе печати. И наконец, в функции OnEndPrinting() можно уничтожить любой объект, созданный функцией OnBeginPri nting().

На первых порах, когда вы только начинаете работать с MFC, многим кажется очень непривычной разница между экземпляром класса окна MFC и элементом Windows, который он представляет. Например, когда вы создаете объект класса фрейма MFC, в действительности создаются два объекта — MFC-объект класса окна, который имеет члены-функции и переменные, и окно Windows, которым можно манипулировать, используя функции MFC-объекта. Элемент Windows ассоциируется с соответствующим классом, но сам по себе также представляет некую сущность.

В классе документа (Doc.cpp) за перерисовку окна отвечает функция

UpdateAllViews()

В классе представления (View.cpp) за перерисовку окна отвечает функция

Invalidate()

Вызов функции Invalidate() приводит к тому, что МFС обращается к функции OnDraw(), которая, в свою очередь, перерисовывает изображение на экране. Invalidate() принимает единственный аргумент (его значение по умолчанию— TRUE), который указывает, нужно ли стирать прежнее изображение перед прорисовкой нового функцией OnDraw(). Хотя и редко, но бывают случаи, когда удобнее вызывать Invalidate() с аргументом FALSE, и тогда OnDraw() будет рисовать поверх прежнего изображения.

 

 



Вывод на экран. Контекст устройства. Классы контекстов устройства в MFC.

Вывод на экран

Большинство приложений нуждается в выводе определенной информации на экран. На первый взгляд кажется, что, поскольку Windows является системой, не зависящей от аппаратных средств, сформировать изображение на экране для нее не сложно. Однако на деле именно эта "независимость" и перекладывает большую часть нагрузки на плечи программиста. Вы не знаете, с устройством какого типа придется иметь дело вашему приложению, но должны задать все необходимые параметры для его настройки. Средства вывода работают с аппаратурой через промежуточное звено, которое называется контекстом устройства (device context — DC).

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

Связывается драйвер с приложением посредством специальной структуры данных, названной контекстом устройства.

Контекст устройства — это структура C++, которая содержит атрибуты рабочего поля окна. Эти атрибуты включают выбранное для текущей операции перо, кисть и шрифт. Контекст устройства в каждый момент времени располагает только одним пером, кистью или шрифтом. Если вам понадобится некоторую часть изображения нарисовать другим пером, например более толстым, придется, во-первых, создать такое новое перо, а во-вторых, внести его в контекст устройства вместо старого. Точно так, если вы хотите заливать контуры красной кистью, придется ее создать и "выбрать ее в контекст" -— так программисты называют операцию замены инструмента в контексте устройства.

Рабочая область окна (window's client area) — это часть поверхности экрана, в которой можно отображать все, что посчитает нужным приложение: текст, таблицы данных, картинку и т.д. Определенную помощь в этом вам окажет библиотека MFC, которая инкапсулирует функции графического интерфейса Windows (Graphic Device Interface— gdi) в свои классы контекста устройств.

 

Контекст устройства также можно представить как лист бумаги, на котором будет производиться рисование.

Драйвер устройства - это специальная программа, которая умеет этот самый контекст перевести на конкретное устройство

В MFC есть несколько контекстов устройств и все наследники от CDC.

 

CObject -       

|     |-> CClientDC          

|     |-> CWindowDC      

CDC----->|-> CMetaFileDC   

                   |-> CPaintDC           

 

Каждый из контекстов рисует в определенном месте, то есть каждый контекст предназначен для рисования в определенной области. При этом CPaintDC и CClientDC очень похожи. Оба эти класса предназначены для рисования внутри клиентской области окна. То есть они не могут добраться до меню или рамки окна. Чем они отличаются ? CPaintDC используется только тогда когда отвечает на сообщение WM_PAINT. Вместе с этим сообщением будет передана та область, которая требует перерисовки. Ведь окно может быть на экране не полностью. Для извещения о перерисовке вызываются функции BeginPaint и EndPaint, без их вызова Windows будет считать, что перерисовка не произошла. Вот в этом и существенные отличия CPaint, в его конструкторе автоматически вызывается BeginPaint, а в деструкторе EndPaint. CClientDC не выполняет эти функции автоматически. CClientDC вызывает функцию GetDC, а деструктор ReleaseDC .

Если вы хотите получить доступ ко всему окну, то должны использовать класс CWindowDC этот класс позволит вам рисовать и поверх меню и везде в пределах рамки окна определенной при создании окна.

Контекст CMetaFileDC используется для работы с метафайлами, рисование из которых может выполняться многократно.

Функции, находящиеся в классе контекста устройства обеспечивают:

· связь с физическим устройством

· набор изобразительных средств

· регулирование вывода

Смысл физической связи в том, что вы можете рисовать на устройстве, не заботясь о том, как это устройство физически работает. Например, монитор. Вас не интересует его производитель, марка и другие особенности. За это отвечает драйвер, связанный с контекстом устройства.

Набор изобразительных средств - это то, чем вы можете рисовать. Контекст устройства дает вам перья, кисти, умеет делать некоторые операции по рисованию примитивов. То есть он дает инструментарий по рисованию.

Регулировка вывода связана с необходимостью следить за тем, что часть экрана может перекрываться другими областями и поэтому в них рисовать нельзя.

 










Последнее изменение этой страницы: 2018-04-12; просмотров: 453.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...