Студопедия

Главная страница Случайная страница

Разделы сайта

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






Ed->SetWindowText(програмування); //Встановлення тексту у полі редагування 3 страница






 

Рисунок 4.4 – Результат роботи програм із логічним шрифтом

 

4.4 Вирішення проблем оновлення вікна

 

4.4.1 Сутність проблеми

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

Ця втрата зображення або тексту не є випадковою: виведення тексту проводилося у такий спосіб:

 

СClientDC dc(this);

dc.TextOut(10, 10, ”Виведення тексту у найпростіший спосіб”, 100);

 

Що, власне, відбувалося? По-перше, отримувався контекст пристрою, пов’язаний із вікном програми. По-друге, проводилося виведення інформації у контекст пристрою, тобто у вікно. Таким чином, інформація про виведення тексту більше у програмі ніде не зберігалася і, надалі, зовсім не випадково зникала з вікна при мінімізації або перекритті поточного вікна програми іншим вікном.

Під час виведення зображень доводилося проводити більш складні операції. Їх ілюструє приклад 4.5, взятий з обробника правої клавіші миші програми 4.3.

 

Приклад 4.5 – Виведення зображення обробником правої клавіші миші

void CMain:: OnRButtonDown(UINT Flag, CPoint Loc)

{BITMAP bm;

bmp2.GetBitmap(& bm);

CClientDC dc(this);

CDC mdc;

mdc.CreateCompatibleDC(& dc);

mdc.SelectObject(& bmp2);

dc.BitBlt(Loc.x, Loc.y, bm.bmWidth, bm.bmHeight, & mdc, 0, 0, SRCCOPY);

}

 

У цьому прикладі використовується додатковий контекст пристрою mdc, сумісний із контекстом пристрою головного вікна dc. Зображення спочатку обирається у цей додатковий контекст, а вже потім копіюється в основний контекст пристрою вікна. Щоправда, цей додатковий контекст є локальним і вилучається з пам’яті, коли закінчується обробник OnRButtonDown().

Яким чином можна вирішити проблему оновлення вікна? З міркувань здорового глузду пропонується три методи [1]:

1) увесь час обраховувати координати тексту та зображень;

2) зберігати запис подій, пов’язаних із виведенням інформації у вікно та, за необхідності, “перегравати” події;

3) підтримувати у програмі “віртуальне вікно”, яке зберігатиме копію усього графічного виведення у пам’яті та копіювати його зміст у реальне (“фізичне”) вікно при отриманні повідомлення WM_PAINT.

Третій метод є найбільш обґрунтованим. Саме він використовується в операційній системі Windows. Можливо, однак, читач помічав на своєму робочому столі “залишки” вже закритих або недієвих, “зависших” програм. Вони також є наслідками віртуальних вікон.

 

4.4.2 Організація віртуального вікна

Для забезпечення функціонування віртуального вікна у програмі необхідно виконати ряд дій. Спочатку необхідно створити контекст області пам’яті, сумісний із контекстом вікна програми. Після цього все виведення направляється через контекст області пам’яті. Щоразу, коли прийматиметься повідомлення WM_PAINT, вміст контексту області пам’яті має копіюватися у контекст вікна та відображатися на екрані. Якщо все виведення направлятиметься черех пам’ять, програма завжди матиме запис поточного вмісту фізичного вікна.

Під час реалізації віртуального вікна використовується декілька функцій.

Створення сумісного контексту забезпечує функція CreateCompatibleDC():

 

virtual BOOL СDC:: CreateCompatibleDC(CDC* pDC);

 

Обирання об’єктів у контекст пристрою – функція SelectOblect():

 

CPen* СDC:: SelectObject(CPen* pPen);

CBrush* СDC:: SelectObject(CBrush* pBrush);

virtual CFont* СDC:: SelectObject(CFont* pFont);

CBitmap* СDC:: SelectObject(CBitmap* pBitmap);

int СDC:: SelectObject(CRgn* pRgn);

 

Ці дві функції вже описувалися раніше.

Створення растрового зображення, сумісного із контекстом пристрою, забезпечує функція CreateCompatibleBitmap():

 

BOOL CBitmap:: CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight);

 

Тут параметрами є: pDC – покажчик на контекст пристрою, до якого створюється сумісне зображення, nWidth та nHeight відповідно ширина та висота растрового зображення. Растрове зображення є необхідним для фізичного зберігання інформації, яка виводиться у віртуальне вікно.

Віртуальне вікно заповнюється тим самим фоном, що й фізичне вікно. Для такої сумісності растрове зображення, відповідне віртуальному вікну, заповнюється функцією PatBlt(), яка заповнює прямокутну область відповідно до кольору та стилю поточного пензля.

 

BOOL СDC:: PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop);

 

Тут параметрами є: (x, y) – координата верхнього лівого кута вікна, Width та Height – ширина та висота прямокутної області заповнення, dwRop – спосіб заповнення. Спосіб заповнення має ряд варіантів, які подаються у таблиці 4.3:

 

Таблиця 4.3 – Режими заповнення функції PatBlt()

PATCOPY Копіювання поточного зображення без змін у цільовий контекст (зображення)
PATINVERT Комбінування цільового зображення з поточним із використанням оператора XOR
DSTINVERT Інвертування цільового зображення
BLACKNESS Переключення всього виведення на чорний колір
WHITENESS Переключення всього виведення на білий колір

 

Для організації віртуального вікна необхідно:

1. У класі вікна оголосити об’єкт контексту пристрою віртуального вікна; об’єкт растрового зображення, відповідно віртуальному вікну; об’єкт пензля заповнення віртуального вікна.

Це може виглядати так:

 

Приклад 4.6 – Реалізація об’єктів віртуального вікна у класі CMainWin

class CMainWin:: CFrameWnd

{public:

CDC memDC; // контекст пристрою віртуального вікна;

CBitmap vbmp; // растрове зображення віртуального вікна;

CBrush mbrush; // пензель для заповнення віртуального вікна;

…………………..

};

2. У конструкторі головного вікна програми здійснити такі зміни:

− отримати розміри фізичного вікна програми;

− реалізувати сумісність контексту віртуального вікна з фізичним вікном;

− створити растрове зображення, сумісне з основним вікном програми та обрати його у контекст віртуального вікна;

− створити фон віртуального вікна (зазвичай – білого кольору), зробити його поточним та обрати у контекст віртуального вікна, заповнити обраним фоном віртуальне вікно. Зазначені зміни ілюструє приклад 4.7.

 

3. В обробнику повідомлення WM_PAINT здійснити копіювання вмісту віртуального вікна у фізичне вікно програми (наведений у прикладі 4.8).

 

Приклад 4.7 – Конструктор CMainWin під час реалізації віртуального вікна

 

CMainWin:: CMainWin()

{Create(NULL, " Image example", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU1));

bmp1.LoadBitmap(IDB_BITMAP1); // завантаження зображення 1

bmp2.LoadBitmap(IDB_BITMAP2); // завантаження зображення 2

m_X=m_Y=0; // поточні координати виведення

maxX=GetSystemMetrics(SM_CXSCREEN); // отримання X – розміру

maxY=GetSystemMetrics(SM_CYSCREEN); // отримання Y – розміру

CClientDC dc(this); // отримання контексту головного вікна

memDC.CreateCompatibleDC(& dc);

vbmp.CreateCompatibleBitmap(& dc, maxX, maxY);

memDC.SelectObject(& vbmp);

mBrush.CreateStockObject(WHITE_BRUSH);

memDC.SelectObject(& mBrush);

memDC.PatBlt(0, 0, maxX, maxY, PATCOPY);

}

 

Приклад 4.8 – Реалізація обробника повідомлення WM_PAINT

void CMainWin:: OnPaint()

{CPaintDC dc(this);

dc.BitBlt(0, 0, maxX, maxY, & memDC, 0, 0, SRCCOPY);

}

 

Прокоментуємо послідовність наших дій у конструкторі головного вікна програми. Спочатку визначаємо розміри екрана. Далі для поточного вікна отримуємо контекст пристрою і використовуємо його для створення сумісного контексту пам'яті memDC. Також у відповідності з контекстом поточного вікна та його фізичними розмірами створюється сумісне растрове зображення vbmp. Растрове зображення обирається у контекст області пам’яті memDC. Крім того створюється об’єкт пензля mBrush білого кольору. Пензель обирається у контекст області пам’яті та використовується для заповнення фону віртуального вікна.

Обробник OnPaint() виконує просту, але важливу роботу. У ньому спочат­ку отримується контекст пристрою, пов’язаний із головним вікном програ­ми. Після цього в отриманий контекст копіюється вміст контексту облас­ті пам’яті. Таким чином, будь-якого разу, коли програма отримує повідомлення WM_PAINT, весь вміст віртуального вікна копіюватиметься у фізичне вікно програми.

 

 

4.4.3 Приклади використання віртуального вікна

Віртуальне вікно, створене у відповідності із прикладами 4.6 – 4.8, може бути використовано для організації виведення інформації як текстового так і графічного вмісту. При цьому, щоразу отримувати контекст поточного вікна вже не буде необхідності і все виведення проводитиметься у контекст віртуального вікна (контекст області пам’яті).

Таким чином із використанням віртуального вікна, у випадку виведення тексту у вікно, обробник OnText() можна переписати у спосіб, що ілюструється прикладом 4.9.

 

Приклад 4.9 – Модифікований обробник OnText()

 

void CMainWin:: OnText()

{char t[255];

TEXTMETRIC tm; CSize size;

memDC.SetTextColor(RGB(255, 0, 0));

memDC.SetBkColor(RGB(0, 255, 0));

memDC.GetTextMetrics(& tm);

wsprintf(t, " Шрифт має висоту %ld логічних одиниць", tm.tmHeight);

memDC.TextOut(m_X, m_Y, t, strlen(t));

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

memDC.SelectObject(& m_AnsiVarFont);

strcpy(t, " Рядок перейшов на наступну позицію шрифтом ANSI_VAR_FONT");

memDC.TextOut(m_X, m_Y, t, strlen(t));

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

wsprintf(t, " Шрифт має насиченість %ld одиниць", tm.tmWeight);

memDC.TextOut(m_X, m_Y, t, strlen(t));

size= memDC.GetTextExtent(t, strlen(t));

wsprintf(t, " Попередній рядок має довжину %ld логічних одиниць", size.cx);

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

memDC.TextOut(m_X, m_Y, t, strlen(t));

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

wsprintf(t, " Розміри екрану: %d %d шрифтом ANSI_FIX_FONT", maxX, maxY);

memDC.SelectObject(& m_AnsiFixFont);

memDC.TextOut(m_X, m_Y, t, strlen(t));

InvalidateRect(NULL); }

Аналогічним чином можна переписати обробник натискання правої клавіші миші OnRButtonDown().

 

Приклад 4.10 – Приклад обробника OnRButtonDown() із віртуальним вікном

 

void CMainWin:: OnRButtonDown(UINT Flags, CPoint Loc)

{CClientDC dc(this);

CDC mdc;

mdc.CreateCompatibleDC(& dc);

BITMAP map;

bmp2.GetBitmap(& map);

mdc.SelectObject(& bmp2);

memDC.BitBlt(Loc.x, Loc.y, map.bmWidth, map.bmHeight, & mdc, 0, 0, SRCCOPY);

CRect a(Loc.x, Loc.y, Loc.x+map.bmWidth, Loc.y+map.bmHeight);

InvalidateRect(a); }

Повний текст програми із використанням віртуального вікна наведений у прикладі 4.11.

 

Приклад 4.11 – Програма із використанням віртуального вікна

 

// im1.h: interface for the CMainWin class.

class CMainWin: public CFrameWnd

{public: void OnPaint();

void OnText();

void OnFont();

void OnRButtonDown(UINT Flags, CPoint Loc);

CMainWin();

DECLARE_MESSAGE_MAP()

private: CBrush mBrush;

CBitmap vbmp;

CDC memDC;

int m_X, m_Y;

CBitmap bmp2;

CFont m_AnsiFixFont, m_AnsiVarFont;

};

 

class CApp: public CWinApp

{public: BOOL InitInstance(); };

 

// im1.cpp: implementation of the CMainWin class.

 

#include < afxwin.h>

#include < afxdlgs.h>

#include " im1.h"

#include " resource.h "

int maxX, maxY;

LOGFONT lf;

int i;

 

CMainWin:: CMainWin()

{Create(NULL, " Image example", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU1));

bmp2.LoadBitmap(IDB_BITMAP2);

m_X=m_Y=0;

maxX=GetSystemMetrics(SM_CXSCREEN);

maxY=GetSystemMetrics(SM_CYSCREEN);

CClientDC dc(this);

memDC.CreateCompatibleDC(& dc);

vbmp.CreateCompatibleBitmap(& dc, maxX, maxY);

memDC.SelectObject(& vbmp);

mBrush.CreateStockObject(WHITE_BRUSH);

memDC.SelectObject(& mBrush);

memDC.PatBlt(0, 0, maxX, maxY, PATCOPY);

m_AnsiVarFont.CreateStockObject(ANSI_VAR_FONT);

m_AnsiFixFont.CreateStockObject(ANSI_FIXED_FONT); }

 

BOOL CApp:: InitInstance()

{m_pMainWnd = new CMainWin;

m_pMainWnd -> ShowWindow(m_nCmdShow);

m_pMainWnd -> UpdateWindow();

return TRUE; }

 

CApp App;

 

BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd)

ON_COMMAND(ID_SECOND_FONT, OnFont)

ON_COMMAND(ID_SECOND_TEXT, OnText)

ON_WM_RBUTTONDOWN()

ON_WM_PAINT()

END_MESSAGE_MAP()

 

void CMainWin:: OnRButtonDown(UINT Flags, CPoint Loc)

{CClientDC dc(this);

CDC mdc;

mdc.CreateCompatibleDC(& dc);

BITMAP map;

bmp2.GetBitmap(& map);

mdc.SelectObject(& bmp2);

memDC.BitBlt(Loc.x, Loc.y, map.bmWidth, map.bmHeight, & mdc, 0, 0, SRCCOPY);

CRect a(Loc.x, Loc.y, Loc.x+map.bmWidth, Loc.y+map.bmHeight);

InvalidateRect(a); }

 

void CMainWin:: OnFont()

{CClientDC dc(this);

CFont font1;

CFontDialog a;

a.DoModal();

a.GetCurrentFont(& lf);

font1.CreateFontIndirect(& lf);

memDC.SelectObject(font1); }

void CMainWin:: OnText()

{char t[255];

TEXTMETRIC tm; CSize size;

memDC.SetTextColor(RGB(255, 0, 0));

memDC.SetBkColor(RGB(0, 255, 0));

memDC.GetTextMetrics(& tm);

wsprintf(t, " Шрифт має висоту %ld логічних одиниць", tm.tmHeight);

memDC.TextOut(m_X, m_Y, t, strlen(t));

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

memDC.SelectObject(& m_AnsiVarFont);

strcpy(t, " Рядок перейшов на наступну позицію шрифтом ANSI_VAR_FONT");

memDC.TextOut(m_X, m_Y, t, strlen(t));

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

wsprintf(t, " Шрифт має насиченість %ld одиниць", tm.tmWeight);

memDC.TextOut(m_X, m_Y, t, strlen(t));

size= memDC.GetTextExtent(t, strlen(t));

wsprintf(t, " Попередній рядок має довжину %ld логічних одиниць", size.cx);

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

memDC.TextOut(m_X, m_Y, t, strlen(t));

m_Y=m_Y+tm.tmHeight+tm.tmExternalLeading;

wsprintf(t, " Розміри екрану: %d %d шрифтом ANSI_FIX_FONT", maxX, maxY);

memDC.SelectObject(& m_AnsiFixFont);

memDC.TextOut(m_X, m_Y, t, strlen(t));

InvalidateRect(NULL);

}

 

void CMainWin:: OnPaint()

{CPaintDC dc(this);

dc.BitBlt(0, 0, maxX, maxY, & memDC, 0, 0, SRCCOPY); }

 

Результат роботи програми зображено на рисунку 4.5.

 

 

Рисунок 4.5 – Результат виведення зображення у програмі із віртуальним вікном

 

4.5 Робота з графічними функціями MFC

 

4.5.1 Основні відомості

Microsoft Windows є графічною операційною системою і тому забезпечується багатим набором графічних функцій. Їх використання тісно пов’язано з організацією виведення інформації у вікно і практично за методами не відрізняється від викликів функції виведення тексту та виведення зображень. Основну роль тут продовжують відігравати контексти вікна, як фізичного, так і віртуального. Ті основи, що закладені у попередньому розділі і стосуються організації роботи із віртуальним вікном, мають бути використані і для графічних функцій.

Під час роботи з графічними функціями використовується та сама система координат, що й під час роботи з текстом. За замовчуванням, верхній лівий кут вікна має координати (0, 0), а логічні одиниці вимірювання координат еквівалентні пікселям. Для позначення координат виведення Windows використовує так званий поточний покажчик (current pointer). Під час запуску програми поточний покажчик встановлюється у координату (0, 0) і є поточною позицією у вікні програми.

 

4.5.2 Пір’я та пензлі

Раніше у прикладах програм вже використовувалися об’єкти пензлів. Їх застосування призначалося для заповнення вікна певним фоновим кольором. У графічних функціях пензлі виконують заповнення замкнених графічних об’єктів, наприклад прямокутників та еліпсів. Пензлям відповідає клас CBrush.

Пір’ям є графічні об’єкти, що забезпечують зображення контурів прямих та кривих ліній, дуг, еліпсів, визначених відповідними графічними функціями. Властивості пір’я забезпечені класом CPen.

За замовчуванням, замкнені графічні об’єкти відображуються пером за замовчуванням, що має чорний колір та товщину у 1 піксель і заповнюються білим пензлем.

Пензлі можна створити двома способами: за допомогою конструктора класу CBrush, за допомогою функції CreateSolidBrush().

 

BOOL CBrush:: CreateSolidBrush(COLORREF crColor);

 

Конструктор класу CBrush має вигляд:

 

CBrush (COLORREF Color);

 

За допомогою конструктора класу можна створити пензель в один рядок: СBrush redBrush(RGB(255, 0, 0));

Інколи, однак, необхідно рознести у часі створення об’єкта пензля (наприклад у класі вікна) та його задання (безпосередньо в обробнику). За таких умов окремо оголошують об’єкт пензля, а потім задають колір:

СBrush yellowBrush;

yellowBrush.СreateSolidBrush(RGB(255, 255, 0));

За допомогою пір’я відображаються графічні об’єкти. За замовчуванням перо має товщину 1 піксель. Серед пір’я є стандартні типи: чорне, якому відповідає константа BLACK_PEN, біле – WHITE_PEN, прозоре – NULL_PEN.

Стандартні пір’я можуть бути задані за допомогою функції CreateStockObject():

 

CPen whitePen;

whitePen.CreateStockObject();

 

Найчастіше створюють свої власні пір’я. Як і пензлі – у два основних способи: за допомогою функції CreatePen() та за допомогою конструктора класу CPen.

Функція CreatePen() описується у такий спосіб:

 

BOOL CPen:: CreatePen(int nPenStyle, int nWidth, COLORREF crColor);

 

Серед параметрів: nPenStyle – стиль пера, Width – товщина пера у пікселях, crColor – колір у форматі RGB.

Стиль пера задається константами, вказаними у таблиці 4.4.

 

Таблиця 4.4 – Стилі пір’я

PS_DASH Штрихова лінія
PS_DASHDOT Штрих-пунктирна лінія
PS_DASHDOTDOT Штрих-крапка-крапка
PS_DOT Пунктирна лінія
PS_SOLID Безперервна лінія
PS_NULL Прозоре перо

За допомогою CreatePen(), можна задати перо у такий спосіб:

 

СPen bluePen;

bluePen.CreatePen(PS_SOLID, 10, RGB(0, 0, 255));

 

Конструктор класу СPen має ті cамі параметри, що й функція CreatePen():

CPen:: CPen (int nPenStyle, int nWidth, COLORREF crColor);

 

При використанні конструктора класу CPen, процедура створення пера вписується в один рядок:

 

СPen greenPen(PS_SOLID, 7, RGB(0, 255, 0));

 

Використання кожного варіанта обумовлюється умовами програми. Якщо створення об’єкта пера і його використання рознесені, використовують функцію CreatePen(). В інших випадках доцільно використовувати конструктор класу.

 

4.5.3 Графічні функції MFC

Усі графічні функції у MFC забезпечуються класом CDC, тому не випадково, що саме об’єкти цього класу надалі використовуватимуть графічні функції. Як вже зазначувалося в п. 4.5.1, під час роботи графічних функцій використовуватиметься поточний покажчик. Його позицію, що при запуску програми має значення (0, 0) можна змінити функцією MoveTo().

 

1. Функція зміни положення поточного покажчика:

 

CPoint CDC:: MoveTo(int x, int y);

CPoint CDC:: MoveTo(POINT point);

 

де (x, y) або point – координати точки, на яку змінюється положення поточного покажчика. Використання функції дуже просте:

 

memDC.MoveTo(100, 100); // переміщення поточного покажчика у точку (100, 100)

 

Як параметр, що повертається функцією, виступає попереднє положення поточного покажчика.

 

2. Функція відображення ліній:

 

BOOL CDC:: LineTo(int x, int y);

BOOL CDC:: LineTo(POINT point);

 

Функція LineTo() забезпечує проведення лінії з точки положення поточного покажчика у точку (x, y) або point. Проведення лінії забезпечується за допомогою обраного пера. За замовчуванням використовується чорне перо товщиною 1 піксель. Таким чином, щоб провести червону щільну лінію товщиною 3 пікселі, наприклад з точки (10, 10) у точку (200, 30), можна реалізувати обробник OnPaintLine() з таким кодом:

 

Приклад 4.12 – Використання функції LineTo()

void CMainWin:: OnPaintLine()

{ CPen redPen(PS_SOLID, 3, RGB(255, 0, 0)); // визначаємо червоне перо

memDC.SelectObject(& redPen); // обираємо перо

memDC.MoveTo(100, 100); // переміщуємо поточний покажчик

memDC.LineTo(250, 300); // відображаємо лінію

InvalidateRect(NULL); // оновлюємо усе вікно

}

У цьому та подальших прикладах виведення забезпечується за допомогою об’єкта memDC, який є контекстом пристрою віртуального вікна, визначеного у спосіб, заданий у попередньому розділі.

 

3. Побудова прямокутників

 

BOOL CDC:: Rectangle(int x1, int y1, int x2, int y2);

BOOL CDC:: Rectangle(LPCRECT lpRect);

 

У цих функціях верхній лівий кут прямокутника описується координатами (x1, y1), нижній правий кут – координатами (x2, y2). Другий варіант функції використовує покажчик на об’єкт прямокутника, який можна задати, наприклад, у такий спосіб:

 

СRect a(100, 100, 300, 300);

memDC.Rectangle(& a);

 

Ще один варіант прямокутника задає функція RoundRect(). Відмінністю цієї функції є заокруглення кутів. Ширина та висота еліпсу заокруглення задається додатково або безпосередньо координатами, або точкою, з якої ці координати отримуються. Приклад 4.13 показує побудову прямокутників.

 

BOOL CDC:: RoundRect(int x1, int y1, int x2, int y2, int x3, int y3);

BOOL CDC:: RoundRect(LPCRECT lpRect, POINT point);

 

Приклад 4.13 – Побудова прямокутників

memDC.SelectObject(& redPen);

memDC.SelectObject(& yellowBrush);

CRect d(50, 220, 170, 300);

memDC.Rectangle(& d); // стандартний прямокутник

CPoint p3(50, 50);

CRect e(200, 220, 270, 300);

memDC.RoundRect(& e, p3); // прямокутник з заокругленими кутами

 

4. Функції відображення поліліній:

 

BOOL CDC:: Polyline(LPPOINT lpPoints, int nCount);

BOOL CDC:: PolylineTo(LPPOINT lpPoints, int nCount);

 

Серед параметрів Polyline() має масив lpPoints точок – складових полілінії, nCount – кількість точок у масиві (щонайменше дві).

 

Приклад 4.13 – Використання функції Polyline()

void CMainWin:: OnPaintPolyline()

{ CPen redPen(PS_SOLID, 3, RGB(255, 0, 0));

memDC.SelectObject(& redPen);

CPoint pl[4];

pl[0].x=5; pl[0].y=100;

pl[1].x=25; pl[1].y=20;

pl[2].x=75; pl[2].y=20;

pl[3].x=125; pl[3].y=100;

memDC.Polyline(pl, 4);

InvalidateRect(NULL);

}

 

На відміну від попередньої функції LineTo(), функція Polyline() не залежить від значення поточного покажчика та не змінює його кінцеве положення. Функція PolylineTo() починає креслення з точки положення поточного покажчика, вона ж змінює кінцеве положення поточного покажчика.

Окрім поліліній звичайного плану, клас CDC містить функції для відображення Без’є-сплайнів.

 

BOOL PolyBezier(const POINT* lpPoints, int nCount);

BOOL PolyBezierTo(const POINT* lpPoints, int nCount);

 

Вхідні дані для цих поліліній є тими самими: масив точок - складових полілінії та кількість точок у масиві. Перший сплайн будується з першої точки масиву до четвертої із використанням другої та третьої точок як контрольних. Кожний наступний сплайн потребуватиме у точності три точки і використовуватиме кінцеву точку попереднього сплайна як свою початкову, дві наступні – як контрольні, а третю – як кінцеву.

Відмінність функції PolyBezier() від PolyBezierTo() полягає у способі використання масиву точок та використанні поточного покажчика. PolyBezier() не залежить від його положення, а PolyBezierTo() проводить побудову сплайна з позиції поточного покажчика до третьої точки масиву, використовуючи дві перші точки як контрольні. Кінцева точка попереднього сплайна слугує початковою для наступного. Функція PolyBezierTo() також потребує триразового перевищення кількості точок над кількістю поліліній.

Обробник із функцію PolyBezier(), наведено у прикладі 4.14.

 

Приклад 4.14 – Використання функції PolyBezier ()

void CMainWin:: OnPaintBezier()

{ CPen redPen(PS_SOLID, 3, RGB(255, 0, 0));

memDC.SelectObject(& redPen);

CPoint pl[10];

pl[0].x=10; pl[0].y=70; // початкова точка першого сплайна

pl[1].x=20; pl[1].y=20; pl[2].x=40; pl[2].y=20;

pl[3].x=60; pl[3].y=70;

pl[4].x=80; pl[4].y=70; // другий сплайн

pl[5].x=100; pl[5].y=20; pl[6].x=110; pl[6].y=20;

pl[7].x=120; pl[7].y=30; // третій сплайн

pl[8].x=110; pl[8].y=70; pl[9].x=100; pl[9].y=60;

memDC.PolyBezier(pl, 10);

InvalidateRect(NULL);

}

5) Використання криволінійних функцій:

Усі криволінійні функції, а до їх складу ми віднесемо Arc(), Ellipse(), Pie(), використовують поняття базового прямокутника, зображеного на Рис.4.6.

(LowX, LowY)

Рисунок 4.6 – Базовий прямокутник криволінійних функцій

 

Базовий прямокутник обмежується координатами верхнього лівого (UpX, UpY) та нижнього правого (LowX, LowY) кутів. Всередині базового прямогутника вміщується вписаний еліпс, який і є основою для побудови криволінійних об’єктів. Перш за все такий стан об’єктів використовується функцією Ellipse():

 

BOOL CDC:: Ellipse(int UpX, int UpY, int LowX, int LowY);

BOOL CDC:: Ellipse(LPCRECT lpRect);

 

Тут UpX, UpY, LowX, LowY – вже наведені координати кутів прямокутника, у який вписується еліпс. Еліпс зображується за допомогою поточного пера і заповнюється у стилі поточного пензля.

Функція Arc() забезпечує побудову дуги, яка будується на основі базового прямогутника. Дуга є елементом еліпса, вписаного до базового прямокутника. Кінцеві точки дуги обмежуються двома променями, що виходять з центру еліпса.

 

BOOL CDC:: Arc(int UpX, int UpY, int LowX, int LowY,

int StartX, int StartY, int EndX, int EndY);

BOOL CDC:: Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd);

 

Тут, як і раніше, UpX, UpY, LowX, LowY – координати кутів базового прямокутника; StartX, StartY – точка напряму першого обмежуючого променя, EndX, EndY – точка напряму другого обмежуючого променя.

У другому варіанті lpRect містить увесь прямокутник, а точки ptStart та ptEnd – точки напрямів першого та другого обмежуючих променів.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.