Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
WinAPI.docx
Скачиваний:
49
Добавлен:
16.12.2018
Размер:
3.43 Mб
Скачать

4.10.9 Дополнительные сведения о контексте памяти

Мы использовали контекст памяти для передачи существующих битовых образов на экран. Вы можете также использовать контекст памяти для рисования на поверхности битового образа. Во-первых, вы строите контекст памяти:

hdcMem = CreateCompatibleDC(hdc);

Затем вы создаете битовый образ желаемого размера. Если вы хотите создать монохромный битовый образ, его можно сделать совместимым с hdcMem:

hBitmap = CreateCompatibleBitmap(hdcMem, xWidth, yHeight);

Для создания битового образа с такой же организацией цветов, как и у видеотерминала, сделайте битовый образ совместимым с hdc:

hBitmap = CreateCompatibleBitmap(hdc, xWidth, yHeight);

Теперь вы можете выбрать битовый образ в контекст памяти:

SelectObject(hdcMem, hBitmap);

А затем вы можете рисовать в этом контексте памяти (т. е. на поверхности битового образа), используя все функции GDI, рассмотренные в этой главе. Когда вы впервые создаете битовый образ, он содержит случайные биты. Поэтому есть смысл начать с использования функции PatBlt с ROP кодом WHITENESS или BLACKNESS для стирания фона контекста памяти.

Когда вы закончите рисование в контексте памяти, просто удалите его:

DeleteDC(hdcMem);

Теперь битовый образ будет содержать все, что вы нарисовали, пока он был выбран в контекст памяти.

Программа SCRAMBLE очень "грубая", и не следовало бы показывать ее вам. Но она использует контекст памяти, как временный буфер для операций BitBlt, меняющих местами содержимое двух прямоугольных фрагментов экрана.

В программе SCRAMBLE нет оконной процедуры. В функции WinMain она получает контекст устройства для всего экрана:

hdc = CreateDC("DISPLAY", NULL, NULL, NULL);

а также контекст памяти:

hdcMem = CreateCompatibleDC(hdc);

Затем она определяет размеры экрана и делит их на 10:

xSize = GetSystemMetrics(SM_CXSCREEN) / 10;

ySize = GetSystemMetrics(SM_CYSCREEN) / 10;

Программа использует эти размеры для создания битового образа:

hBitmap = CreateCompatibleBitmap(hdc, xSize, ySize);

и выбирает его в контекст памяти:

SelectObject(hdcMem, hBitmap);

Используя функцию rand языка C, программа SCRAMBLE формирует четыре случайных величины, кратные значениям xSize и ySize:

x1 = xSize *(rand() % 10);

y1 = ySize *(rand() % 10);

x2 = xSize *(rand() % 10);

y2 = ySize *(rand() % 10);

Программа меняет местами два прямоугольных блока дисплея, используя три функции BitBlt. Первая копирует прямоугольник с вершиной в точке (x1, y1) в контекст памяти:

BitBlt(hdcMem, 0, 0, xSize, ySize, hdc, x1, y1, SRCCOPY);

Вторая копирует прямоугольник с вершиной в точке (x2, y2) в прямоугольную область с вершиной в точке (x1, y1):

BitBlt(hdc, x1, y1, xSize, ySize, hdc, x2, y2, SRCCOPY);

Третья копирует прямоугольник из контекста памяти в прямоугольную область с вершиной в точке (x2, y2):

BitBlt(hdc, x2, y2, xSize, ySize, hdcMem, 0, 0, SRCCOPY);

Этот процесс эффективно меняет местами содержимое двух прямоугольников на дисплее. SCRAMBLE делает это 200 раз, что может привести к полному беспорядку на экране. Но этого не происходит, потому что программа SCRAMBLE отслеживает свои действия, и перед завершением восстанавливает экран.

Вы можете также использовать контекст памяти для копирования содержимого одного битового образа в другой.

Предположим, вы хотите создать битовый образ, содержащий только левый верхний квадрант другого битового образа. Если исходный битовый образ имеет описатель hBitmap, то вы можете скопировать его размеры в структуру типа BITMAP:

GetObject(hBitmap, sizeof(BITMAP),(LPVOID) &bm);

и создать новый неинициализированный битовый образ размером в одну четверть исходного:

hBitmap2 = CreateBitmap(bm.bmWidth / 2, bm.bmHeight / 2, bm.bmPlanes, bm.bmBitsPixel, NULL);

Теперь создаются два контекста памяти и в них выбираются исходный и новый битовые образы:

hdcMem1 = CreateCompatibleDC(hdc);

hdcMem2 = CreateCompatibleDC(hdc);

SelectObject(hdcMem1, hBitmap);

SelectObject(hdcMem2, hBitmap2);

Теперь копируем левый верхний квадрант первого битового образа во второй:

BitBlt(hdcMem2, 0, 0, bm.bmWidth / 2, bm.bmHeight / 2, hdcMem1, 0, 0, SRCCOPY);

Все сделано, кроме очистки:

DeleteDC(hdcMem1);

DeleteDC(hdcMem2);

DeleteObject(hBitmap);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]