Управление растровым изображением. Структура Windows-приложения. Развитие стартовой заготовки, страница 5

¨  После обработки события Resize (соответствующего сообщению WM_SIZE) автоматически срабатывает перерисовка поврежденной области окна (clip region). Перед перерисовкой вся поврежденная область автоматически стирается. В результате происходит сбой в последовательности пар: рисуй-стирай. Для коррекции этого дефекта в перерисовке динамического прямоугольника надо скорректировать цепочку парных действий, добавив такую установку (ее местоположение вычислите самостоятельно).

  SetRectEmpty (&rTarget);

Альтернативные способы перерисовки динамического прямоугольника

Для изображения динамического прямоугольника мы выбрали растровую операцию R2_XORPEN и пару инструментов: (пунктирное перо, нулевая кисть). Проверьте работу другой растровой операции (параметра функции SetROP2 — R2_NOT), которая успешно отображает динамический прямоугольник, но без эффекта резинки. Убедитесь, что в этом случае необходима нулевая кисть, а пунктирное перо можно выбросить (объясните).

Для изображения прямоугольника возможно и другое сочетание инструменов и установок: растровая операция R2_NOTXORPEN и пунктирное перо. Нулевая кисть теперь не понадобится, ее наличие не портит картины, но она не нужна. Проверьте этот факт и, рассмотрев булевские операции, объясните его механизм.

Среди множества функций API есть функция DrawFocusRect, которая самостоятельно устанавливает растровую операцию (R2_XORPEN), выбирает пунктирное перо (типа PS_DOT) и нулевую кисть для исключения заливки внутренности прямоугольника. Эта функция значительно упрощает код в ветви обработки WM_MOUSEMOVE. Скопируйте весь файл приложения, переименуйте его в DrawFocusRect.cpp, подключите к проекту, отключите старый и внесите в новый файл такие изменения.

case WM_MOUSEMOVE:    // Реакция на движение курсора

{

  if (!(wParam & MK_LBUTTON))

   return 0;

  short x = LOWORD(lParam),  y = HIWORD(lParam);

  hdc = GetDC(hWnd);

  DrawFocusRect(hdc, &rTarget); // Первичное рисование (стираем)

  SetRect (&rTarget, ptOld.x, ptOld.y, x, y);

  if (ptOld.x > x)

  {

   rTarget.left = x;

   rTarget.right = ptOld.x;

  }

  if (ptOld.y > y)

  {

   rTarget.top = y;

   rTarget.bottom = ptOld.y;

  }

  DrawFocusRect(hdc, &rTarget); // Повторное рисование (рисуем)

  ReleaseDC(hWnd, hdc);

  break;

}

Уберите лишние детали (перо) и убедитесь, что алгоритм: рисуй-стирай работает так же успешно, как и ранее.

Работа с растровыми изображениями

Рисование в окне, точнее в контексте устройства, связанном с окном, производится с помощью инструментов подсистемы GDI: pen, brush, font, palette, bitmap, region. Все они управляются с помощью Windows-описателей типа: HPEN, HBITMAP и т. д. Рассмотрим как принято работать с bitmap.

Под растровым изображением (bitmap-image) понимают блок данных специального формата DIB (Device-Independent Bitmap), который используется для хранения и обработки изображений с учетом различных цветовых разрешений экрана. Когда программист видит BMP-Файл, то он представляет себе данные с такой структурой:

Старый формат (DDB) зависит от типа устройства, на котором предполагается избразить bitmap.

¨  Функции: CreateBitmap, CreateCompatibleBitmap, CreateBitmapIndirect работают с DDB.

¨  Функции: CreateDIBitmap. GetDIBits, SetDIBits, SetDIBitsToDevice, StretchDIBits, CreateDIBPatternBrush работают с более новым форматом DIB. 

В буфере обмена (Clipboard) DIB-изображению соответствует описатель формата данных CF_DIB. Последний компонент DIB (Bimap Bits) содержит перечисление цветов всех точек изображения. Способ перечисления зависит от типа bitmap, который определен в заголовке. Так, поле biBitCount определяет количество бит (bit per pixel), описывающих цвет одной точки изображения. Оно может иметь значение:

¨  1 bpp  — цвет (из 2-х возможных) задается индексом массива (палитры), размещенной в Color Table.

¨  4 bpp — 16 цветов палитры, хранимой в Color Table,

¨  8 bpp — 256 цветов палитры, хранимой в Color Table,

¨  16 bpp — 65536 цветов (Color Table используется особым образом),

¨  24 bpp — 16 млн. цветов, задаваемых 3-мя последовательными байтами (red, green, blue),