Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ІК (Говорущенко) Методичка.doc
Скачиваний:
6
Добавлен:
23.02.2016
Размер:
762.88 Кб
Скачать

Встановлення атрибутів контексту відображення

Контекст відображення, крім характеристик пристрою виводу, містить вказівники на обрані в контекст інструменти малювання. Інструменти налагоджують за допомогою атрибутів контексту відображення (їх біля 20). Наприклад, атрибути описують систему координат, задають налагодження кольору графічних об'єктів та кольору фону. За їх допомогою можна обрати перо для малювання ліній та пензль для зафарбовування внутрішньої області замкнених фігур. При одержанні контексту відображення атрибути малювання містять значення за замовчуванням.

Функції встановлення значень атрибутів:

  • SetBkColor - встановлює колір для фону операції виводу;

  • RGB - повертає значення кольору в форматі COLORREF у вигляді інтенсивності червоної, зеленої та блакитної складової кольору;

  • SetBkMode - встановлю режим фону (прозорий TRANSPARENT та непрозорий OPAQUE);

  • SetROP2 - встановлює новий режим малювання;

  • SetTextColor - втсановлює колір виводу символів тексту;

  • SetTextCharacterExtra - встановлює відстань між бувами тексту;

  • CreateSolidBrush - створює пензль кольору сrColor;

  • CreateHatchBrush - створює штрихований пензль;

  • SelectObject- вибір пензля або пера в контекст;

  • DeleteObject - видаляють створений пензль або перо з контексту;

  • CreatePen - створює перо стилю fnPenStyle шириною nWidth кольору crColor;

  • SetMapMode - змінює режим відображення, який впливає на систему координат (напрямок і масштаб координатних вісів);

  • SetWindowExtEx, SetViewportExtEx - встановлюють орієнтації вісів та одиниць;

  • SetWindowOrgEx - встановлює початок (xWin0, yWin0) логічної системи координат;

  • SetViewportOrgEx - встановлює зміщення фізичної і логічної систем координат.

Приклади.

Задача. Створити пензль в клітинку з горизонтальних і вертикальних ліній малінового кольору, обрати її в контекст, зафарбувати фігури та видалити створений пензль.

Розвязок.

HBRUSH hNewBrush=CreateHatchBrush(HS_CROSS, RGB(255, 0, 255));

HBRUSH hOldBrush=(HBRUSH) SelectObject(hdc, hNewBrush);

//Тут можуть бути зафарбовані фігури

SelectObject(hdc,hOldBrush);

DeleteObject(hNewBrush);

Задача. Створити перо для малювання суцільних ліній шириною в 3 пікселя блакитного кольору, обрати його в контекст, намалювати лінії і видалити створене перо.

Розвязок.

HPEN hNewPen=CreatePen(PS_SOLID, 3, RGB(0, 255, 255));

HPEN hOldPen=(HPEN)SelectObject(hdc,hNewPen);

SelectObject(hdc,hOldPen); DeleteObject(hNewPen);

Задача. Створити систему координат з початком відліку в лівому нижньому куті вікна. Вісь Х направити зліва направо, вісь У - знизу догори. Логічні значення виости і ширини змінювати від 0 до 1000. Встановити однаковий масштаб за вісями Х і У.

Розвязок.

SetMapMode(hdc, MM_ISOTROPIC);

SetWindowExt(hdc, 1000, 1000);

SetViewportExt(hdc, cxClient, -cyClient);

SetViewportOrg(hdc, 0, cyClient);

Вивід тексту

Налагодження параметрів шрифта. В контекст відображення за замовчуванням обрано системний шрифт. Логічний шрифт створює функція CreateFondIndirect:

HFONT WINAPI CreateFontIndirect(const LOGFONT FAR* lplf);

Вона повертає дескриптор створеного шрифта. В якості аргумента передають вказівник на структуру LOGFONT:

typedef struct

{LONG lfHeight;

LONG lfWidth;

LONG lfEscapement;

LONG lgOrientation;

LONG lfWeight;

BYTE lfItalic;

BYTE lfUnderline;

BYTE lfStrikeOut;

BYTE lfCharSet;

BYTE lfOutPrecision;

BYTE lfClipPrecision;

BYTE lfQuality;

BYTE lfPitchAndFamily;

TCHAR lfFaceName[LF_FACESIZE];

} LOGFONT;

Призначення полів структури LOGFONT:

  • lfHeight - висота шрифта в логічних одиницях;

  • lfWidth - ширина символів в логічних одиницях;

  • lfEscapement - кут (в напрямку проти годинникової стрілки) в десятих долях градуса між лінією виводу рядка та віссю Х;

  • lfOrientation - кут (в напрямку проти годинникової стрілки) в десятих долях градуса між лінією основи символа та координатною віссю Х;

  • lfWeight - насиченість (жирність) шрифта;

  • lfItalic - якщо цей параметр відмінний від 0, то шрифт з нахиленими літерами;

  • lfUnderline - якщо цей параметр відмінний від 0, то шрифт з підкресленням літер;

  • lfStrikeOut - якщо цей параметр відмінний від 0, то шрифт з перекресленими літерами;

  • lfCharSet - найважливіше поле структури; задає набір потрібних символів;

  • lfOutPrecision - задає необхідний ступінь відповідності між параметрами запитаного та наданого шрифта;

  • lfClipPercision - задає спосбі урізання зображення символа на межі виводу;

  • lfQuality - задає якість відображення символів;

  • lfPitchAndFamily - задає вимоги до ширини символів завантажуваного шрифта;

  • lfFaceName - рядок з іменем шрифта довжиною не більше 32 символів.

Вибір шрифта в контекст відображення. Для вибору шрифта hfontв контекст відображення hdc викликають функцію SelectObject:

SelectObject (hdc,hfont);

Функції виводу тексту:

  • TextOut- виводить символьний рядок у вказану позицію, дотримуючись обраних атрибутів контексту відображення;

  • SetTextAlign - встановлю режим вирівнювання тексту в контекст відображення.

Приклад.

Задача. Cтворити і обрати шрифт з заданими характеристиками. В лівому нижньому куті вікна додатку з різними нахилом, кольорами фону і тексту 10 раз вивести один і той же текст..

Розвязок.

#include "Functions.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);

HINSTANCE hInstance;

char szClass[]="TextOutClass";

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT nCmdShow)

{MSG msg; HWND hwnd; ::hInstance=hInstance;

if (!RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE;

hwnd=CreateWindow (szClass, "Виведення тексту", WS_OVERLAPPEDWINDOW|

WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, 0, 0, hInstance, NULL);

if (!hwnd) return FALSE;

while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);

return(int)msg.wParam; }

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{char szFont[]="Будь-який текст";

static short cyClient;

switch (msg)

{ case WM_SIZE: {cyClient=HIWORD(lParam); return 0;}

case WM_PAINT:

{PAINTSTRUCT ps; HDC hdc=BeginPaint(hwnd, &ps);

static LOGFONT lf;

lf.lfCharSet=DEFAULT_CHARSET;

lf.lfPitchAndFamily=DEFAULT_PITCH;

strcpy(lf.lfFaceName, "TimesNewRoman");

lf.lfHeight=20;

// lf.lfQuality=DEFAULT_QUALITY;

//lf.lfOutPrecision=OUT_TT_ONLY_PRECIS;

lf.lfWeight=FW_BOLD;

for (int i=0;i<10;i++)

{lf.lfOrientation=lf.lfEscapement=i*100;

HFONT hNFont=CreateFontIndirect(&lf);

HFONT hOFont=(HFONT)SelectObject(hdc,hNFont);

SetTextColor(hdc, RGB(i*15, i*20, i*25));

SetBkColor(hdc, RGB(255-i*15, 255-i*20,255-i*25));

TextOut(hdc, 0, cyClient-30, szFont, strlen(szFont));

SelectObject(hdc, hOFont); DeleteObject(hNFont); }

EndPaint(hwnd, &ps); return 0; }

case WM_DESTROY: {PostQuitMessage(0); return 0;}

} return DefWindowProc(hwnd, msg, wParam, lParam);}

Визначення метрик шрифта. Метрику шрифта, обраного в контекст відображення hdc, визначають за допомогою функції GetTextMetrics:

GetTextMetrics(HDC hdc,LPTEXTMETRIC lptm);

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

typedef struct

{ LONG tmHeight;

LONG tmAscent;

LONG tmDescent;

LONG tmInternalLeading;

LONG tmExternalLeading;

LONG tmAveCharWidth;

LONG tmMaxCharWidth;

LONG tmWeight;

LONG tmOverhang;

LONG tmDigitizedAspectX;

LONG tmDigitizedAspectY;

BCHAR tmFirstChar;

BCHAR tmLastChar;

BCHAR tmDefaultChar;

BCHAR tmBreakChar;

BYTE tmItalic;

BYTE tmUnderlined;

BYTE tmStruckOut;

BYTE tmPitchAndFamily;

BYTE tmCharSet;

} TEXTMETRIC;

Призначення полів структури TEXTMETRIC:

  • tmHeight - загальна висота літер

  • tmAscent - частина висоти літер від базової лінії з врахуванням таких елементів, як діакритичний знак в літері "й";

  • tmDescent - частина висоти літер нижче базової лінії;

  • tmInternalLeading - висота виступаючих елементів;

  • tmExternalLeading - висота міжрядкового інтервалу;

  • tmAveCharWidth - середня ширина рядкових літер;

  • tmMaxCharWidth - ширина найширшої літери;

  • tmWeight - насиченість (жирність) шрифта;

  • tmOverhang- величина зміни ширини символів при побудові нахиленого або жирного шрифта з нормального шрифта;

  • tmDigitizedAspectX- розрішення пристрою відображення по горизонталі;

  • tmDigitizedAspectY- розрішення пристрою відображення по вертикалі;

  • tmFirstChar- код першого символа в шрифті;

  • tmLastChar- код останнього символа в шрифті;

  • tmDefaultChar - код символа, який заміняє будь-який відсутній в шрифті символ;

  • tmBreakChar- код символа переносу слів з одного рядка на інший при вирівнюванні тексту;

  • tmItalic0 - нахилений шрифт;

  • tmUnderlined0 - підкреслений шрифт;

  • tmStruckOut0 - перекреслений шрифт;

  • tmPitchAndFamily - код сімейства шрифта;

  • tmCharSet- код використовуваного набору символів.

Приклад.

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

Розв‘язок (виведення таблиці у вікно).

#include "Functions.h"

#include <math.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hInstance;

char szClass[]="TableClass";

//Описуємо тип структури стовпця даних

typedef struct

{char str[15]; //Поле заголовку стовпця

doubleva[50]; //Масив даних стовпця

} COLUMN; //Ім'я типу

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT nCmdShow)

{ MSG msg; HWND hwnd; ::hInstance=hInstance;

if (!RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE;

hwnd=CreateWindow (szClass, "ТАБЛИЦЯ", WS_OVERLAPPEDWINDOW|

WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, 0, 0, hInstance, NULL);

if (!hwnd) return FALSE;

while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);

return(int)msg.wParam; }

BOOL DrawLine(HDC hdc, int x0, int y0, int x, int y)

{MoveToEx(hdc, x0, y0, NULL); return LineTo(hdc, x, y); }

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{ //Описуємо масив з 10 стовпців

static COLUMN cols[10];

static int cx, cy, cxChar, cyChar;

switch(msg)

{case WM_SIZE:

{c[=LOWORD(lParam); cy=HIWORD(lParam); return 0; }

case WM_CREATE:

{ //Заповнюємо заголовки стовпців

strcpy(cols[0].str,"i"); strcpy(cols[1].str,"10*sin(i/10.)");

strcpy(cols[2].str,"20*sin(i/20.)"); strcpy(cols[3].str,"30*sin(i/30.)");

strcpy(cols[4].str,"40*sin(i/40.)"); strcpy(cols[5].str,"50*sin(i/50.)");

strcpy(cols[6].str,"60*sin(i/60.)"); strcpy(cols[7].str,"70*sin(i/70.)");

strcpy(cols[8].str,"80*sin(i/80.)"); strcpy(cols[9].str,"90*sin(i/90.)");

//Заповнюємо масиви даних стовпців

for (int i=0; i<50, i++)

{ //В першому стовпці будуть номери рядків

cols[0].val[i]=i;

//В останніх стовпцях будуть дані

for(int j=1; j<10; j++) cols[j].val[i]=10*sin(i/10./j);}

//Визначаємо середні висоту і ширину символів шрифта

{TEXTMETRIC tm;

//Визначаємо метрики тексту

HDC hdc=GetDC(hwnd);

GetTextMetrics(hdc,&tm);

ReleaseDC(hwnd,hdc);

//Кількість пікселів в висоті символа

cyChar=tm.tmHeight+tm.tmExternalLeading;

//Кількість пікселів в середній ширині символів

cxChar=tm.tmAveCharWidth+1;

} return 0; }

case WM_PAINT:

{PAINTSTRUCT ps; HDC hdc=BeginPaint(hwnd,&ps);

char str[20];

//Встановимо почтаокві параметри для виведення

int left=cxChar //Лівий край

top=cyChar/2 //Верх

dx=cxChar, //Пробіл за віссю Х

dy=cyChar/4, //Пробіл за віссю Y

hy=cyChar+dy+dy, //Висота для рядка

right=cx-cxChar, //Правий край

bottom=cy-cyChar, //Низ

bounds[10], //Масив ширин стовпців

i=0, j=0;

//Заповнюємо масив ширинами стовпців

while(j>10)

{//Для j-го стовпця обираємо максимальну ширину

bounds[j]=strlen(cols[j].str);

for(i=0; i<50; i++)

{ _gcvt(cols[j].val[i], 7, str);

int ss=strlen(str);

if (bounds[j]<ss) bounds[j]=ss; }

if (bounds[j]<=3) bounds[j]=4;

if (bounds[j]>10) bounds[j]-=2;

bounds[j]=cxChar*(bounds[j]); j++; }

// Визначаємо максимальну кількість стовпців - maxcol,

// які розміщуються в робочій області

int dd=left, maxcol=0;

while (maxcol<10)

{ if (dd+bounds[maxcol]>right) bresk;

dd+=bounds[maxcol]; maxcol++; }

// right тепер вказує на правий край таблиці

right=dd;

//Підганяємо ширину вікна під кількість стовпців

{ RECT rc; GetWindowRect(hwnd, &rc);

MoveWindow(hwnd, rc.left, rc.top,

//Змінюємо лише ширину вікна

rc.right-rc.left-(cx-right)+dx, rc.bottom-rc.top, TRUE); }

//ПОЧАТОК ВИВЕДЕННЯ ТАБЛИЦІ

//Встановлюємо режим вирівнювання по правому краю

SetTextAlign(hdc, TA_RIGHT);

//Початок виведення заголовку таблиці

int y=top; //Поточна координата за віссю Y

//Горизонтальна лінія на всю ширину

DrawLine(hdc ,left, y, right, y);

//Заголовки стовпців

int x=left; //Поточна координата за віссю Х

//Вертикальна лінія ліворуч від стовпця

DrawLine(hdc, x, y, x, y+hy);

for (j=0; j<maxcol; j++)

{ //Встановлюємо х на правій границі стовпця

x+=bounds[j];

TextOut(hdc, x-dx, y+dy, cols[j].str, strlen(cols[j].str));

//Вертикальна лінія праворуч від стовпця

DrawLine(hdc, x, y, x, y+hy); }

//Горизонтальна лінія на всю ширину

y+=hy; DrawLine(hdc, left, y, right, y);

//Кінець виведення заголовку таблиці

//Початок виведення даних таблиці

i=0; //Лічильник номеру рядка даних

while(i<50 && y<bottom)

{ //Вертикалоьна лінія ліворуч від стовпця

x=left; DrawLine(hdc, x, y, x, y+hy);

for (j=0; j<maxcol; j++)

{ //Встановлюємо х на правій границі стовпця

x+=bounds[j];

if (j==0)

//Перетворюємо ціле число в рядок

_itoa(int)cols[j].val[i], str, 10);

else

//Перетворюємо дійсне число в рядок

_gcvt(cols[j].val[i], 7, str);

TextOut(hdc, x-dx, y+dy, str, strlen(str));

//Вертикальна лінія праворуч від стовпця

DrawLine(hdc, x, y, x, y+hy); }

//Горизонтальна лінія на всю ширину

y+=hy; DrawLine(hdc, left, y, right, y);

i++; }

//Кінець виведення даних таблиці

//Кінець виведення таблиці

EndPaint(hwnd, &ps); return 0; }

case WM_DESTROY: {PostQuitMessage(0); return 0;}

} return DefWindowProc(hwnd, msg, wParam, lParam);}