В общем так. Обстоятельства несколько изменились и мне, видимо, придется
свернуть рассылку. Прошу прощения за доставленные неудобства. Этот выпуск -
один из последних. Я просто выдам предварительно подготовленный материал.
Спустя 5-6 выпусков я закрою рассылку. Спасибо за внимание.
Рисование по требованию
Если в неграфических операционных системах момент перерисовки окна определял
программист, то Windows сама определяет необходимость отрисовки. Окно
программы должно быть всегда готово к тому, что система потребует отрисовать
(обновить) содержимое окна или любую его часть. Система заявляет об этом,
вызывая оконную процедуру с сообщением WM_PAINT. Стандартная обработка этого
сообщения (в оконной процедуре) такова:
case WM_PAINT: { //Обработка отрисовки по требованию системы
PAINTSTRUCT ps; //Структура под параметры рисования
HDC hdc = BeginPaint(hWnd, (LPPAINTSTRUCT)&ps); //Получение контекста
... //Собственно рисование
EndPaint(hWnd, (LPPAINTSTRUCT)&ps); //Завершение рисования
}
break;
Перерисовке подвержена т.н. клиентная область окна - прямоугольник,
включающий в себя все окно кроме заголовка и рамки. Начало системы координат
изображения находится в левом верхнем углу клиентной области, ось абсцисс
направлена вправо, ось ординат - вниз. Для рисования используются следующие
примитивы:
LineTo(hdc, x,y); //Провести пером линию от текущей точки в (x,y)
MoveToEx(hdc, x,y, NULL); //Переставить перо в точку (x,y) без рисования
SetPoint(hdc, x,y, color); //Установить цвет точки (x,y) в цвет color
Rectangle(hdc, x1,y1, x2,y2); //Закрашенный прямоугольник, обведенный линией
Ellipse(hdc, x1,y1, x2,y2); //Эллипс, вписанный в заданный прямоугольник
Там, где необходимо указать цвет, можно применять запись: RGB(r,g,b),
где r,g,b - компоненты соответственно красного, зеленого и синего цветов.
Размер окна может меняться, но на время отрисовки он постоянен. Узнать его
можно вызовом:
RECT rc; GetClientRect(hWnd, &rc);
после которого rc.right - ширина, rc.bottom - высота клиентной области.
Рисование по WM_PAINT не должно быть очень долгим! Если вы хотите, чтобы
изображение динамично менялось с течением времени, программируйте это
с использованием таймера.
Контекст устройства
Первым параметром при вызове всех графических примитивов передается контекст
устройства (device context, DC) - это графический экран, в котором можно
рисовать. Контекст содержит в себе графические ресурсы, используемые
в настоящий момент для рисования (перо, кисть, шрифт) и задает текущий режим
рисования - способ вывода линий и закраски областей, выравнивание и способ
вывода текста и т.п. Но самое главное - контекст определяет устройство,
в которое направлено рисование - экран, принтер, либо битмап.
Перья и кисти
Все линии и дуги рисуются пером (pen). Перо может иметь различную ширину
и цвет, быть сплошным, либо пунктирным, штриховым и т.д. Контекст рисования
можно рассматривать как автомат с единственным гнездом под рабочий
инструмент - перо. В гнезде всегда находится какое-то одно перо. Изначально
это сплошное перо черного цвета единичной ширины. Чтобы рисовать линии
другим цветом, нужно заменить перо (SelectObject). Но заменить мы можем
только на что-то существующее. Стало быть, новое перо еще нужно создать
(CreatePen):
HPEN hpen = CreatePen(PS_SOLID, 3, RGB(255,0,0)); //Создаем сплошное перо
// красного цвета шириной 3 пиксела
HGDIOBJ hOldPen = SelectObject(hdc, hpen); //Подставляем новое перо в экран
... //Рисование подставленным пером
SelectObject(hdc, hOldPen); //Подставляем старое перо - освобождаем новое
DeleteObject(hpen); //Удаляем созданное нами перо
Операция создания пера всегда должна дополняться операцией его уничтожения
(DeleteObject): если ресурсы не освобождаются, то память, отведенная под
них, переполняется.
Линия, нарисованная пером с толщиной больше единицы, имеет закругленные
концы. Для рамок и других фигур, требующих рисования горизонтальных
и вертикальных линии с острыми концами, используем PatBlt - закрашивание
прямоугольника:
PatBlt(hdc, x,y, w,h, BLACKNESS);
Для закраски областей служит кисть (brush). Кисти различаются по цвету,
могут быть сплошными либо штриховыми с разным направлением штриховки, либо
задаются битовым шаблоном. Работа с кистью полностью аналогична работе
с пером: