Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Практикум программирования на С++ под Windows #9


Служба Рассылок Subscribe.Ru проекта Citycat.Ru

Практикум программирования на C++ под Windows
comp.soft.prog.cppwin
Выпуск #9
29/10/2000

*** РИСОВАНИЕ ***********************************************************

В общем так. Обстоятельства несколько изменились и мне, видимо, придется свернуть рассылку. Прошу прощения за доставленные неудобства. Этот выпуск - один из последних. Я просто выдам предварительно подготовленный материал. Спустя 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). Кисти различаются по цвету, могут быть сплошными либо штриховыми с разным направлением штриховки, либо задаются битовым шаблоном. Работа с кистью полностью аналогична работе с пером:

  HBRUSH hbr = CreateSolidBrush(RGB(0,0,255)); //Создаем синюю кисть
  HGDIOBJ hOldBr = SelectObject(hdc, hbr); //Подставляем новую кисть в экран
  ... //Рисование текущей кистью
  SelectObject(hdc, hOldBr); //Подставляем старую кисть - освобождаем новую
  DeleteObject(hbr); //Удаляем созданную нами кисть

F.A.Q.

Q: Как узнать разрешение экрана (размеры экрана в пикселах) ? A: Воспользуйтесь функцией GetSystemMetrics:

   int xScr = GetSystemMetrics(SM_CXSCREEN);
   int yScr = GetSystemMetrics(SM_CYSCREEN);


*************************************************************************
Количество подписчиков: 5922
Архив Рассылки

Никита Зимин
Nikita_Zeemin@mail.ru



http://subscribe.ru/
E-mail: ask@subscribe.ru

В избранное