Клас для перегляду зображень

Клас представлення документа CRightView служить для ілюстрації вмісту всіх документів, виявлених в поточній вибраній теці. У вікні CRightView ми рядами і стовпцями розмістимо інші прості вікна, керовані класом CWndGeom, які матимуть однаковий розмір і змальовуватимуть геометрію конструкції, відповідної даним документа. Причому зображення в контексті вікна відтворять самі документи, точніше об'єкти m_poly, які є в кожному з них. Далі вікна класу CWndGeom ми називатимемо картинками.

Оскільки кількість документів в поточній теці довільно і заздалегідь не відомо (але вони всі мають бути доступні користувачеві), то, аби розмістити всі картинки, розміри вікна CRightView мають бути змінними. Вікно має бути «гумовим». Клас CRightView був спочатку створений майстром AppWizard як клас, здатний прокручувати вміст свого вікна, оскільки як базовий клас для нього був вибраний csroliview. Завдяки цьому клас придбав здатність стежити за розмірами свого вікна і при необхідності створювати смуги горизонтальної і вертикальної прокрутки. Наша мета - навчитися програмно управляти розмірами вікна прокрутки, динамічно створювати і знищувати вікна картинок і правильно змальовувати в них геометрію конструкції, спираючись на дані документа. Скоректуйте коди стартової заготівки з інтерфейсом класу так, як показано нижче:

#pragma once

//====== Клас для демонстрації вмісту документів

class CRightView : public CScrollView {

//====== Попереджуюче оголошення класу картинок

friend class CWndGeom; protected:

CSize m_szView; // Реальні розміри вікна

CSize m_szScroll; // Розміри прокручуваного вікна

CSize m_szltem; // Розміри картинки

CSize m_szMargin; // Розміри полів

CString m_WndClass; // Рядок реєстрації картинки

CRightView () ;

DECLARE_DYNCREATE(CRightView) public: //====== Контейнер картинок

vector<CWndGeom*> m_pWnds;

CTreeDoc* GetDocument()

{

return dynamic_cast<CTret=Doc*> (m_pDocument) ;

}

virtual -CRightView();

void Show(); // Демонстрація картинок

void Clear();

// Звільнення ресурсів

// Overrides public:

virtual void OnDraw(CDC* pDC);

protected:

virtual void OnlnitialUpdate() ;

DECLARE_MESSAGE_MAP() };

Внесіть скорочення і зміни в коди реалізації класу так, як показано нижче:

IMPLEMENTJDYNCREATE(CRightView, CScrollView)

BEGIN_MESSAGE_MAP(CRightView, CScrollView) END_MESSAGE_MAP()

CRightView::CRightView()() CRightView::-CRightView(){}

void CRightView::OnDraw(CDC* pDC)

{

CTreeDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

}

Смуги прокрутки автоматично з'являються, коли реальні розміри вікна (m_szview) стають менше розмірів прокручуваного вікна (m_szScroll), які треба задати як аргументу функції SetScrollSizes. Якщо користувач збільшив розміри вікна і вони стали рівними або більше тих, що були вказані, то смуги автоматично зникають. Звідси витікає, що програміст повинен якось задати первинні розміри m_szScroll, коли ще не відомі вимоги до них. Зазвичай це робиться у функції OnlnitialUpdate. Проглянете коди цієї функції, і ви побачите, які розміри прокручуваного вікна (за умовчанням) задав майстер AppWizard. Для стеження за розмірами вікна вистави введіть в клас CRightview реакцію на повідомлення WM_SI ZE, так само як ви це робили в класі CDrawView. Зміните коди цієї функції, а також функції OnlnitialUpdate, в якій ми прирівнюємо початкові розміри прокручуваного вікна до реальних:

void CRightView::OnSize(UINT nType int ex int су)

{ CScrollView::OnSize(nType, ex, су);

if (cx==0 || cy==0)

return;

//====== Запам'ятовуємо розміри вікна вистави

m_szView = CSize (ex, су);

}

void CRightView::OnInitialUpdate()

{

CScrollView::OnInitialUpdate();

//====== Початкові розміри вікна

m_szScroll = m_szView; SetScrollSizes(MM_TEXT, m_szScroll);

}

Функція SetScrollSizes одночасно з розмірами задає і режим перетворення координат. Найнеприємнішим і незрозумілішим моментом в спадкоємстві від класу CScrollView є те, що функція SetScrollSizes не дозволяє задавати режими MM_ISOTROPIC і MM_ANISOTROPIC, які дозволяють, як ви пам'ятаєте працювати з формулами. Цей недолік MFC широко дискутувався як в MSDN, так і на одному з найпопулярніших сайтів для програмістів - www. CodeGuru.com. Там же ви можете виявити деякі вирішення цієї проблеми. Зміните конструктор класу. У момент свого народження об'єкт класу CRi'ghtView повинен підготуватися до роботи з вікнами, керованими класом CWndGeom. До того моменту, коли йому знадобиться створити серію таких вікон, їх тип (клас вікон в сенсі структури типа WNDCLASS) вже має бути відомий системі.

Примітка

Прекрасне рішення дав Brad Pirtle, і ви можете знайти його в одному з разде-лов CodeGuru, включивши пошук по імені. Він створив свій клас CZoomView (похідний від CScrolLView), в якому замінив функцію SetScrollSizes на іншу, - SetZoomSizes, а також перевизначив (overrode) віртуальну функцію OnPrepareDC, батьківська версія якої виявляє і забороняє спробу використовувати формульные режими. У своїй версії OnPrepareDC він обходить виклик батьківської версії, тобто версії CSrollView, і замість цього викликає «дідову» версію CView::OnPrepareDC, яка терпимо відноситься до формульным режимів. Цей приклад, на мій погляд, дуже переконливо демонструє гнучкість об'єктно-орієнтованого підходу при розробці досить складних застосувань.

CRightView::CRightView() {

m_szltem = CSize (200,150); // Розміри картинки

m_szMargin = CSize (20,20); // Розміри полів

try

{

//====== Спроба зареєструвати клас вікон

m_WndClass=AfxRegisterWndClass(CS_VREDRAWICS_HREDRAW::LoadCursor(GetModuleHandle(0),(char*) IDC_MYHAND), (HBRUSH)CreateSolidBrush(GetSysColor(COLOR_INFOBK)));

}

catch (CResourceException* pEx)

{

AfxMessageBox(_T("Клас вже зареєстрований")); pEx->Delete ();

}

}

У конструкторі класу CRightView відбувається спроба зареєструвати новий клас вікон. Зазвичай відмов тут не буває, але технологія вимагає перевірити наявність збоївши, тому включаємо механізм обробки виключень (try-catch). Ми хочемо добитися особливої поведінки вікон з картинками, тому задамо для них свою форму курсора і свій колір фону. Колір фону вибирається з того набору, який надає система (див. довідку по функції GetSysColor), а курсор створили самі. Річ у тому, що системний курсор, що ідентифікується як i DC_HAND, працює не у всіх версіях Windows. Якщо ви працюєте в середовищі Windows 2000, то можете замінити в параметрі функції LoadCur sor виклик GetModuleHandle (0) на 0, а ідентифікатор IDC_MYHAND на IDC_HAND і працювати з системним курсором. В цьому випадку ресурс курсора IDC_MYHAND виявиться зайвим і його можна видалити.

В даний момент ми передбачаємо, що в класі документа вже створений динамічний контейнер m_Shapes об'єктів класу CPolygon, кожен елемент якого відповідає даним, отриманим в результаті читання документів, виявлених в поточному каталозі. Тепер приступимо до розробки найскладнішої функції у складі класу CRightView, яка повинна:

  1. Пройті по всьому переліку об'єктів m_shapes класу CPolygon.
  2. Обчислити виходячи з поточного розміру вікна кількість рядів і колонок міні-вікон із зображеннями полігонів.
  3. Створити для кожного з них вікно, кероване класом CWndGeom.

Далі за подію розвиваються автоматично. Після створення вікна cwndGeom система пошле йому повідомлення WM_PAINT, в обробці якого треба створити і набудувати контекст пристрою міні-вікна, а потім викликати функцію Draw для того полігону з контейнера m_Shapes, індекс якого відповідає індексу вікна CWndGeom. Кожен полігон малює себе самого в заданому йому як параметр контексті пристрою. Введіть у файл реалізації класу CRightView наступний код:

void CRightView::Show()

{

CTreeDoc *pDoc = GetDocument0;

//====== Кількість картинок

int nPoly = pDoc->m_Shapes.size();

//=== Обчислення кроку, з яким виводяться картинки

int dx = m_szltem.cx + m_szMargin.ex,

dy = m_szltem.cy + m_szMargin.cy,

nCols = m_szView.cx/dx; // Кількість колонок

//====== Корекція

if (nCols < 1)nCols = 1;

if (nCols > nPoly)nCols = nPoly;

//====== Кількість рядів

int nRows = ceil(double(nPoly) /nCols);

//=== Обчислення і установка розмірів вікна прокрутки

m_szScroll = CSize(nCols*dx, nRows*dy);

SetScrollSizes(MM_TEXT, m_szScroll);

//====== Координати і розміри першої картинки

CRect r (CPoint(0,0), m_szltem);

r.OffsetRect (15,15);

//====== Стиль вікна картинки

DWORD style = WS_CHILD | WS_BORDER | WS_VISIBLE;

//====== Цикл проходу по рядах (n - лічильник картинок)

for (int 1=0, n=0; i<nRows; i++)

{

//====== Цикл проходу по стовпцях

for (int j=0; j<nCols && rKnPoly; j++, n++)

{

//====== Створюємо клас вікна картинки

CWndGeora *pWnd = new CWndGeom(this, n);

//====== Запам'ятовуємо його в контейнері

m_pWnds.push_back(pWnd);

//====== Створюємо Windows-окно

pWnd->Create (m_WndClass, 0, style, r this 0);

//====== Зрушуємо позицію вікна управо

r.OffsetRect (dx, 0);

}

//=== Починаємо новий ряд картинок (зрушення вліво-вниз)

r.OffsetRect (-nCols*dx, dy);

}

}

Істотним моментом в алгоритмі є те, що розмір прокручуваного вікна (m_szScroll) залежить від кількості картинок. Тому скільки б їх не було в поточній теці - всі будуть доступні за допомогою смуг прокрутки. Розташування і розміри картинок визначаються за допомогою об'єкту класу CRect. Метод Of f setRect цього класу дозволяє зрушувати прямокутник вікна в потрібному нам напрямі.

Обслуговування контейнера m_pWnds дочірніх вікон типа cwndGeom зв'язане з необхідністю стежити за звільненням пам'яті, займаної вікнами, в ті моменти, коли відбувається перехід від теки до теки у вікні CLef tview. Для цієї мети служить допоміжна функція Clear, яку треба викликати як у відмічені вище моменти, так і при закритті вікна. Останній випадок супроводиться автоматичним викликом деструкції класу CRightview. З врахуванням сказаного введіть такі добавки у файл RightView.cpp:

void CRightview::Clear()

{

//====== Цикл проходу по всіх адресах контейнера

for (UINT i=0; Km_pWnds. size () ; i++)

{

//====== Знищення Windows-окна

m_pWnds[i]->DestroyWindow();

// Звільнення пам'яті, займаної об'єктом

delete m_pWnds[ i ];

}

//===== Звільнення пам'яті, займаної контейнером m_pWnds.clear();

}

//===== Деструкція класу викликає

Clear CRightview::~CRightview()

{

Clear () ;

}

 

рекламодавці:

/ LF KS выполнена доставка грузов Челябинск конечная

::  Меню ::

Введення

Початок роботи з Visual Studio.Net

Режими відображення координат

Традиційне Windows-приложение

Аналізатор код помилок

Управління файловим деревом

Графіка OPENGL

Тривимірні графіки функцій

Від сирих COM API до проекту ATL

Тривимірна графіка в проекті ATL

З життя студентів

Вирішуємо краєву задачу

Деякі відомості про архітектуру Windows


:: Реклама ::

Створи сайт за допомогою MS Office AsenKat - каталог сайт

:: Статистика ::

Індекс цитування

:: Навигация ::

Головна
Додати у вишукане  

 

 

 


Copyright © Asentli, 2008