Для рисования графических примитивов в оконных приложениях используются 4 основных типа объектов:
- точка (Pixel);
- перо (Pen);
- кисть (Brush);
- фон (Background).
Точка
Цвет точки задается с помощью функции
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int X, // x-координата точки
_In_ int Y, // y-координата точки
_In_ COLORREF crColor ); // цвет точки
В случае удачного завершения возвращаемое значение функции дублирует цвет точки, в случае ошибки возвращает -1.
Цвет точки представляет собой 32-битное число, заданное в системе RGB:

Можно также воспользоваться функцией
_ Red As Integer, // красный
_ Green As Integer, // зеленый
_ Blue As Integer); // синий
Значения красного, зеленого и синего используются в диапазоне 0…255.
Перо
Перо используется для рисования линий и контуров замкнутых фигур. Цвет пера задается функцией
_In_ int fnPenStyle, // стиль пера
_In_ int nWidth, // ширина пера (в пикселях)
_In_ COLORREF crColor ); // цвет пера
Стили пера fnPenStyle могут быть заданы согласно таблице
Значение | Тип | Описание | |
PS_SOLID | 0 | ![]() |
Сплошное перо |
PS_DASH | 1 | ![]() |
Прерывистое (пунктирное) перо. |
PS_DOT | 2 | ![]() |
Точечное (штриховое) перо. |
PS_DASHDOT | 3 | ![]() |
Штрих-пунктир |
PS_DASHDOTDOT | 4 | ![]() |
Две точки — пунктир |
PS_NULL | 5 | Невидимое перо |
При успешном завершении функция возвращает дескриптор пера, в случае неудачи — константу NULL.
Кисть
Кисть используется для закрашивания замкнутых объектов. Цвет кисти задается с помощью функции
_In_ COLORREF crColor ); // цвет кисти
При успешном завершении функция возвращает дескриптор кисти, в случае неудачи — константу NULL.
Эта же функция используется для задания цвета фона.
Можно заранее создать несколько кистей и перьев, а затем выбирать нужные с помощью функции
_In_ HDC hdc, // дескриптор контекста устройства
_In_ HGDIOBJ hgdiobj ); // дескриптор объекта
Рисование графических примитивов
Перемещение в указанную точку осуществляется функцией:
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int X, // координата x точки
_In_ int Y, // координата y точки
_Out_ LPPOINT lpPoint ); // указатель на структуру POINT
Координаты точки x и у определяются в пикселях относительно левого верхнего угла.
В случае успешного выполнения возвращает ненулевое значение.
Структура POINT имеет вид
LONG x;
LONG y; } POINT, *PPOINT;
Рисование отрезков осуществляется функцией:
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nXEnd, // координата x конечной точки
_In_ int nYEnd ); // координата y конечной точки
В случае успешного выполнения возвращает ненулевое значение.
Рисование прямоугольника осуществляется функцией:
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nLeftRect, // x-координата верхнего левого угла
_In_ int nTopRect, // y-координата верхнего левого угла
_In_ int nRightRect, // x-координата нижнего правого угла
_In_ int nBottomRect); // координата нижнего правого угла
Рисование прямоугольника начинается из точки, в которую осуществлено перемещение с помощью функции MoveTo().
В случае успешного выполнения возвращает ненулевое значение.
Рисование эллипса осуществляется функцией:
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nLeftRect, // x-координата верхнего левого угла
_In_ int nTopRect, // y-координата верхнего левого угла
_In_ int nRightRect, // x-координата нижнего правого угла
_In_ int nBottomRect); // координата нижнего правого угла

В случае успешного выполнения возвращает ненулевое значение.
Рисование дуги осуществляется функцией:
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nLeftRect, // x-координата верхнего левого угла
_In_ int nTopRect, // y-координата верхнего левого угла
_In_ int nRightRect, // x-координата нижнего правого угла
_In_ int nBottomRect, // y-координата нижнего правого угла
_In_ int nXRadial1, // x- координата конца первого радиуса
_In_ int nYRadial1, // y- координата конца первого радиуса
_In_ int nXRadial2, // x- координата конца второго радиуса
_In_ int nYRadial2 ); // y- координата конца второго радиуса
В случае успешного выполнения возвращает ненулевое значение.
Вывод текста в окно
Для вывода текста в поле окна используется функция
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nXStart, // x-координата начала вывода текста
_In_ int nYStart, // y-координата начала вывода текста
_In_ LPCTSTR lpString, // указатель на строку текста
_In_ int cchString ); // количество символов для вывода
В случае успешного выполнения возвращает ненулевое значение.
Задать цвет фона под буквами можно с помощью функции
_In_ HDC hdc, // дескриптор контекста устройства
_In_ COLORREF crColor ); // цвет
Задать цвет букв можно с помощью функции
_In_ HDC hdc, // дескриптор контекста устройства
_In_ COLORREF crColor ); // цвет
В случае неудачного завершения эти функции возвращают константу CLR_INVALID=0xFFFF.
Использование графических функций
Для перерисовки окна, в котором будут отображаться графические объекты, будем использовать обработку сообщения WM_PAINT.
Обработка сообщения WM_PAINT почти всегда начинается с вызова функции:
_In_ HWND hwnd,
_Out_ LPPAINTSTRUCT lpPaint );
При обработке вызова BeginPaint(), Windows обновляет фон рабочей области с помощью кисти, заданной в поле hbrBackground структуры WNDCLASS, описанной здесь. Вызов BeginPaint() делает всю рабочую область действительной (не требующей перерисовки) и возвращает описатель контекста устройства. Контекст устройства описывает физическое устройство вывода информации (например, экран) и его драйвер. Описатель контекста устройства необходим для вывода в рабочую область окна текста и графики.
Аргументы функции:
- hwnd – дескриптор окна;
- lpPaint – указатель на структуру PAINTSTRUCT.
Структура PAINTSTRUCT имеет вид
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32]; } PAINTSTRUCT, *PPAINTSTRUCT;
Члены структуры:
- hdc – дескриптор контекста устройства.
- fErase – ненулевое значение стирает фон.
- rcPaint – структура RECT, определяющая верхний левый и нижний правый углы рабочей области.
typedef struct _RECT {
LONG left; LONG top;
LONG right; LONG bottom; } RECT, *PRECT; - fRestore, fIncUpdate, rgbReserved – зарезервировано, используется системой.
Обработка сообщения WM_PAINT почти всегда заканчивается вызовом функции:
_In_ HWND hWnd,
_In_ const PAINTSTRUCT *lpPaint );
Функция EndPaint() освобождает описатель контекста устройства, после чего его значение нельзя использовать. Возвращает всегда ненулевое значение.
Получение дескриптора контекста устройства осуществляется вызовом функции:
hWnd – дескриптор окна, для которого используется контекст устройства.
Возвращаемое значение – дескриптор контекста устройства.
Функция
_In_ HWND hWnd,
_In_ HDC hDC );
освобождает контекст устройства hDC для данного окна hWnd, после чего значение контекста устройства нельзя использовать. Возвращает всегда ненулевое значение.
Пример График функции y=sin(x).
Назад: Создание Windows-приложений
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
switch (message)
{
//...
case WM_PAINT:
PaintAll(hwnd);
return 0;
case WM_ERASEBKGND:
return 0;
//...
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
namespace e
{
extern HWND hpicturebox; // это окно где что-то рисуется
}
void PaintAll(HWND hwnd)
{
HDC hdc, hcmpdc;
HBITMAP hbmp;
HBRUSH hbrush;
HPEN hpen;
PAINTSTRUCT ps;
RECT rect;
BeginPaint(hwnd, &ps); // здесь hwnd окна на котором расположен hpicturebox
EndPaint(hwnd, &ps);
GetClientRect(e::hpicturebox, &rect);
hdc = GetDC(e::hpicturebox);
hcmpdc = CreateCompatibleDC(hdc);
hbmp = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
hbrush = CreateSolidBrush(RGB(255, 255, 255));
hpen = CreatePen(PS_INSIDEFRAME, 1, RGB(255, 255, 255));
BeginPaint(e::hpicturebox, &ps);
SelectObject(hcmpdc, hbmp);
SelectObject(hcmpdc, hbrush);
SelectObject(hcmpdc, hpen);
Rectangle(hcmpdc, rect.left, rect.top, rect.right, rect.bottom);
//
PaintPicturebox(hcmpdc); // <----- здесь ваше рисование
//
SetStretchBltMode(hdc, COLORONCOLOR);
BitBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hcmpdc, 0, 0, SRCCOPY);
EndPaint(e::hpicturebox, &ps);
ReleaseDC(e::hpicturebox, hdc);
DeleteDC(hcmpdc);
DeleteObject(hbmp);
DeleteObject(hbrush);
DeleteObject(hpen);
}