Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы алгоритмизации и программирования .Язык си.pdf
Скачиваний:
104
Добавлен:
16.03.2016
Размер:
4.49 Mб
Скачать

Приложение 6

«книжные» с засечками (переменный шаг), FF_SWISS – без засечек (переменный шаг), FF_SCRIPT – «рукописные» и курсивные;

lpszFace – имя шрифта, обычно совпадает с именем его дискового файла; если NULL – система подбирает шрифт, наиболее отвечающий заданным требованиям, иначе явно указанный шрифт перекрывает их.

Функция CreateFontIndirect (const LOGFONT* lplgFont); использует в качестве аргумента структуру с полями аналогичного назначения.

Параметры шрифта не включают цвет отображающего инструмента.

Управление цветом выводимого текста осуществляется функциями

Р

 

COLORREF SetTextColor (hdc, crColor);

 

 

 

COLORREF GetTextColor (hdc);

 

 

Базовой функцией вывода символа является

 

 

 

BOOL TextOut (hdc, nXStart, nYStart, lpString, cbString);

 

 

 

 

 

 

 

 

 

 

 

 

 

И

Позицией символа считается верхний левый угол его знакоместа.

 

 

 

 

6.7. Закрашивание пустот

У

 

 

 

 

 

 

 

 

 

 

Г

 

 

 

Если выбранные перо или кисть не сплошные, то они не воздействуют

на фоновые промежутки, например, междуБштрихами, однако эти

промежутки заполняются фоновым цветом, для работы с которым служат

функции

 

 

 

 

 

 

 

а

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

COLORREF SetBkColor(hdc, crColor);

 

 

 

 

 

 

 

 

 

 

 

к

 

 

 

 

 

COLORREF GetBkColor(hdc);

 

 

 

 

первая из

которых устанавлив

е

 

 

 

 

текущий

 

новый, а вторая – получает

фоновые

цвета; признак шибки

– значение CLR_INVALID.

 

Функция

SetBkColor возвращает значение предыдущего цвета.

 

 

 

 

Функции

 

 

ает

 

 

 

 

 

 

 

о

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

int SetBkMode (hdc, iBkMode);

 

 

 

 

 

 

 

и

 

 

 

 

 

 

 

 

 

int GetBkMode (hdc);

 

 

 

 

 

 

 

 

 

л

 

 

 

 

 

 

 

 

 

соответственно устанавливают новый или определяют текущий режим фона,

0 – пр знакбошибки; параметр int iBkMode – режим фона, по умолчанию

белый (OPAQUE) – сначала рисуется фон, затем передний план; режим

и

 

 

 

 

 

 

 

 

 

 

 

TRANSPARENT – отменяет заполнение пустот, в этом случае цвет фона

игнорируется и пустоты заполняться не будут.

 

 

 

 

Б

 

 

 

 

 

 

 

 

 

 

 

 

6.8. Рисование линий и кривых

Теоретически все, что необходимо драйверу устройства для рисования,

это функции SetPixel и GetPixel.

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

225

Приложение 6

На представление линий, созданных с использованием функций, влияют атрибуты контекста устройства: текущая позиция, перо, режим фона (для несплошных перьев), цвет фона (для режима фона OPAQUE) и режим рисования.

Функция

LineTo (hdc, xEnd, yEnd);

рисует отрезок прямой из текущего положения пера, определенного в контексте устройства, до точки (xEnd, yEnd), которая не включается в

отрезок. В контексте текущее положение пера по умолчанию

установки текущей позиции нарисует отрезок, начинающийсяРв левом верхнем углу рабочей области окна.

устанавливается в точку (0,0) и функция LineTo без предварительной

Для рисования отрезка из точки (xStart, yStart) в точку (xEnd, yEnd) необходимо сначала для установки (изменения) текущего положения пера

использовать функцию

 

И

MoveToEx (hdc, xStart, yStart, &pt);

 

У

 

pt – структура типа POINT, определяющая предыдущую позицию. После

чего, используя LineTo (hdc, xEnd, yEnd); будет нарисованГ

отрезок до точки

(xEnd, yEnd), не включая ее в отрезок, и текущее положение пера установится

в точку (xEnd, yEnd).

 

Б

Узнать текущее положение пера можно с помощью функции

 

GetCurrentPositionEx (hdc,а&pt);

Следующий фрагме программыкотображает в рабочей области окна

сетку с интервалом в 100 пиксел й, начиная от левого верхнего угла:

 

 

 

е

 

GetClientRect (hwnd, &rect); (см. Пример 1, Сообщение WM_PAINT);

for (x = 0; x < rect.right; x += 100)

{

 

MoveToEx (hdc, x, 0, NULL);

 

 

 

нт

 

 

LineTo (hdc, x, rect.bottom);

 

}

 

о

 

 

for (y = 0; yи< rect.bottom; y += 100) {

 

MoveToEx (hdc, 0, y, NULL);

 

 

л

 

 

 

 

LineTo (hdc, rect.right, y);

 

} б

 

 

 

Когда необходимо соединить отрезками массив точек pt размером

и

 

 

 

 

cPoint, можно использовать функцию

 

Б

Polyline (hdc, pt, cPoint);

 

 

 

 

 

Например, определим массив из 5 точек (10 значений), описывающих контур прямоугольника:

POINT pt [5] = { 100, 100, 200, 100, 200, 200, 100, 200, 100, 100 };

используем функцию Polyline (hdc, pt, 5). Следует обратить внимание, что первая и последняя точки совпадают.

226

Приложение 6

Функция Polyline не учитывает и не изменяет текущее положение пера. Функция PolylineTo использует текущее положение для начальной точки и устанавливает текущее положение в конец последнего нарисованного отрезка. Предыдущий пример будет выглядеть

MoveToEx (hdc, pt[0].x, pt[0].y, NULL); PolylineTo (hdc, pt + 1, 4);

Для рисования дуги эллипса (рис. П 6.2) используется функция

Arc (hdc, x1, y1, x2, y2, xStart, yStart, xEnd, yEnd);

 

Р

в которой значения (x1, y1) задают левый верхний угол, (x2, y2) – правый

нижний; (xStart, yStart) – начало дуги; (xEnd, yEnd) – конец дуги.

 

 

 

x1

yStart

xStart

 

 

 

И

 

 

 

 

 

 

 

y1

 

 

 

 

 

У

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Г

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

xEnd

 

 

 

 

 

 

Б

 

 

 

yEnd

 

 

 

 

 

а

 

 

 

 

 

 

 

 

 

 

 

x2

y2

 

 

 

 

 

 

к

 

 

 

 

 

 

 

 

 

 

 

 

 

 

е

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. П 6.2. Фигура, нарисованная с использованием функции Arc

 

 

т

 

 

 

 

 

 

 

 

 

Чтобы нарисовать одну или более связанных кривых Безье,

используются функции

 

 

 

 

 

 

 

 

 

 

 

о

 

 

 

 

 

 

 

 

 

 

PolyBezier (hdc, pt, iCount);

 

 

 

 

 

 

PolyBezierTo (hdc, pt, iCount);

 

 

 

 

 

и

 

 

 

 

 

 

 

 

 

 

 

pt – массив структур т па POINT. В функции PolyBezier первые четыре точки идут в таком лпорядке: начальная точка, первая контрольная точка, вторая контрольнаябточка, конечная точка кривой Безье. Каждая следующая кривая Безье тре ует три новых точки, поскольку начальная точка следующей кривойиесть конечная точка предыдущей и т.д. Параметр iCount = 1+3*n – равен ед н це плюс три, умноженное на число отображаемых кривых.

Б 6.9. Пример изображения графика функции sin

Программа содержит массив из 1000 структур POINT. В цикле от 0 до 999 член x структуры растет от 0 до cxClient. В каждом цикле член структуры определяет значение синуса и масштабируется до размеров клиентской области окна. Вся кривая целиком отображается с использованием одного вызова функции Polyline (рис. П 6.3).

Текст программы может быть следующим:

#include <windows.h> #include <math.h>

227

Приложение 6

#define NUM 1000

#define TWOPI (2 * 3.14159)

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

 

 

 

 

 

 

 

 

 

 

 

static char szAppName[] = "Sin" ;

 

 

 

 

 

 

HWND

hwnd ;

 

 

 

 

 

 

 

 

 

 

MSG

msg ;

 

 

 

 

 

 

 

 

 

 

WNDCLASSEX wndclass ;

 

 

 

 

 

И

wndclass.cbSize

= sizeof (wndclass) ;

 

 

 

 

Р

wndclass.style

= CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc

 

= WndProc ;

 

Г

 

 

wndclass.cbClsExtra

= 0 ;

 

 

 

 

У

 

wndclass.cbWndExtra

 

= 0 ;

 

 

Б

 

wndclass.hInstance

= hInstance ;

 

wndclass.hIcon

= LoadIcon (NULL, IDI APPLICATION) ;

wndclass.hCursor

= LoadCursor (NULL, IDC_ARROW) ;

 

 

 

 

 

 

 

а

 

 

 

 

wndclass.hbrBackground=(HBRUSH) GetStockObject(WHITE_BRUSH);

 

 

 

 

 

к

 

 

 

 

 

wndclass.lpszMenuName = NULL ;

 

 

 

 

 

 

 

 

 

е

 

 

 

 

 

 

wndclass.lpszClassName = szAppName ;

 

 

 

 

 

wndclass.hIconSm

 

= LoadIcon (NULL, IDI_APPLICATION) ;

 

 

т

 

 

 

 

 

 

 

RegisterClassEx (&wndclass) ;

 

 

 

 

 

 

hwnd = CreateWindow (szAppName, "Second Example",

 

 

 

о

 

 

 

 

 

 

 

 

 

WS OVERLAPPEDWINDOW,

 

 

 

 

и

 

 

 

 

 

 

 

 

 

 

 

CW USEDEFAULT, CW_USEDEFAULT,

 

 

CW USEDEFAULT, CW_USEDEFAULT,

 

 

NULL, NULL, hInstance, NULL) ;

 

 

 

ShowWindow (hwnd, iCmdShow) ;

 

 

 

 

 

б

 

 

 

 

 

 

 

 

 

 

UpdateWindow (hwnd) ;

 

 

 

 

 

 

 

 

и}

 

(&msg, NULL, 0, 0)) {

 

 

 

 

while (GetMessageл

 

 

 

 

TranslateMessage (&msg) ;

 

 

 

 

 

 

Б}

 

 

 

 

 

 

 

 

 

 

 

DispatchMessage (&msg) ;

 

 

 

 

 

 

return msg.wParam ;

 

 

 

 

 

 

 

 

 

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg,

WPARAM wParam, LPARAM lParam)

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

static int cxClient, cyClient ;

 

 

 

 

 

 

HDC

hdc ;

 

 

 

 

 

 

 

 

 

 

int

i ;

 

 

 

 

 

 

 

 

 

 

228