¨ 32 bpp — 4 млрд. цветов, задаваемых 4-мя последовательными байтами (red, green, blue, alfa),
Для отображения bitmap, хранимого в виде ресурса приложения (простейший случай), следует соблюдать такую последовательность действий:
1. Загрузить его из ресурсов в память — LoadBitmap (или из файла LoadImage),
2. Создать контекст устройства в памяти, совместимый с контекстом окна — CreateCompatibleDC,
3. Выбрать bitmap в этот контекст — SelectObject,
4. При каждой перерисовке копировать biitmap из контекста в памяти в другой контекст, который связан с окном.
Копирование контекстов—это и есть самый быстрый процесс отображения bitmap (или рисования готовых объектов). При этом обычно пользуются одной из API-функций: BitBlt (простое копирование), или StretchBlt (копирование с изменением размеров).
Добавьте в состав оконной процедуры такие переменные:
static HDC hMemDC; // Контекст устройства в памяти
static HBITMAP hImg; // Описатель bitmap
static RECT rBmp; // Текущий прямоугольник bitmap-изображения
static SIZE szSrc; // Настоящие размеры bitmap
static bool bDrag; // Флаг перемещения
static HBRUSH hbrBkgnd; // Описатель кисти для закраски фона
RECT rTmp; // Временный прямоугольник
Вы помните, что переменные типа static не уничтожаются при выходе из оконной процедуры? Введите ветвь обработки сообщения WM_CREATE (первоначальное создание окна):
case WM_CREATE:
{
hImg = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_BITMAP));// Загружаем bitmap из ресурсов
BITMAP bm; // Определяем его размеры с помощью структуры BITMAP
GetObject (hImg, sizeof(BITMAP),&bm);
szSrc.cx = bm.bmWidth;
szSrc.cy = bm.bmHeight;
hdc = GetDC(hWnd); // Добываем контекст устройства, связанный с окном
hMemDC = CreateCompatibleDC(hdc); // Создаем контекст в памяти, совместимый с hdc
SelectObject(hMemDC, hImg); // Выбираем bitmap в этот контекст
ReleaseDC (hWnd, hdc); // Освобождаем лимитированный ресурс системы
hbrBkgnd = CreateSolidBrush (RGB(255,255,220));// Кисть цвета фона (для стирания bitmap при его перемещении)
SetRect (&rBmp, 1, 1, szSrc.cx-2, szSrc.cy-2); // Размеры прямоугольника с учетом толщины рамки
break;
}
Введите ветвь обработки сообщения WM_ERASEBKGND (закрашивание фона окна):
case WM_ERASEBKGND:
{
hdc = (HDC)wParam; // Добываем контекст устройства, который прислала система
HBRUSH hOld = (HBRUSH)SelectObject (hdc, hbrBkgnd); // Выбираем нашу кисть, запоминая текущую
RECT r;
GetClientRect(hWnd, &r); // Определяем размеры клиентской области окна
PatBlt(hdc, r.left, r.top, r.right - r.left, r.bottom - r.top, PATCOPY); // Закрашиваем
SelectObject(hdc, hOld); // Возвращаем перо в контекст устройства
return TRUE;
}
Реакция окна на сообщение о перерисовке вызывает функцию StretchBlt, которая копирует изображение из одного контекста устройства (в памяти) в другой (связанный с окном). Эта функция, в отличие от BitBlt, способна растянуть или сжать изображение, подстраивая его под заданный размер.
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
if (!IsRectEmpty (&rBmp))// Копируем изображение из контекста в памяти в контекст окна, одновременно изменяя размеры
StretchBlt (hdc,rBmp.left,rBmp.top,rBmp.right-rBmp.left,rBmp.bottom-rBmp.top, // Куда
hMemDC, 0, 0, szSrc.cx, szSrc.cy, // Откуда
SRCCOPY); // Как
SetRectEmpty (&rTarget); // Обнуляем прямоугольник - мишень
EndPaint (hWnd, &ps);
break;
Для управления изображением с помощью мыши выберем такой алгоритм:
¨ Если пользователь захватил изображение, то он может его переместить в любое место клиентской области окна. Здесь надо использовать ограничитель перемещения курсора,
¨ Если пользователь щелкнул мышью вне изображения, то он может обозначить желаемый его размер. Здесь будем выявлять факт пересечения двух прямоугольников и переносить изображение в новый прямоугольник.
case WM_LBUTTONDOWN:
ClipCursor(&rClient);
ptOld.x = LOWORD(lParam);
ptOld.y = HIWORD(lParam);
if (PtInRect(&rBmp, ptOld))
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.