Управление растровым изображением. Альтернативные способы перерисовки динамического прямоугольника. Работа с растровыми изображениями, страница 6

¨  Скопируйте весь файл приложения, переименуйте его в Step02.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),

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

Для отображения bitmap, хранимого в виде ресурса приложения (простейший случай), следует соблюдать такую последовательность действий:

1.  Загрузить его из ресурсов в память — LoadBitmap (или из файла LoadImage),

2.  Создать контекст устройства в памяти, совместимый с контекстом окна — CreateCompatibleDC,

3.  Выбрать bitmap в этот контекст — SelectObject,

4.  При каждой перерисовке копировать biitmap из контекста в памяти в другой контекст, который связан с окном.

Копирование контекстов—это и есть самый быстрый процесс отображения bitmap (или рисования готовых объектов). При этом обычно пользуются одной из API-функций: BitBlt (простое копирование), или StretchBlt (копирование с изменением размеров).

¨  Скопируйте файл Step02.cpp, переименуйте копию в Step03.cpp, подключите новый файл к проекту, а старый отключите. Внесите в новый файл изменения.

¨  Добавьте в состав оконной процедуры такие переменные:

static HDC hMemDC;  // Контекст устройства в памяти

static HBITMAP hImg;   // Описатель bitmap

static RECT rBmp;   // Текущий прямоугольник bitmap-изображения

static SIZE szSrc;  // Настоящие размеры bitmap

static bool bDrag;  // Флаг перемещения