- точка (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 | Невидимое перо |
Кисть
Кисть используется для закрашивания замкнутых объектов. Цвет кисти задается с помощью функции
_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, после чего значение контекста устройства нельзя использовать. Возвращает всегда ненулевое значение.
Прошу прощения. Может я что-то не увидел, но какую библиотеку надо подключить?
windows.h
Здравствуйте, Елена, спасибо за Ваш сайт, много интересного.
По поводу графики отмечу, что было бы хорошо, если бы здесь было бы упоминание про двойную буферизацию (это помогает избавиться от эффектов мерцания, если такие наблюдаются при рисовании). Вот часть кода из моей программы.
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);
}