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

4.10.7 Функция DrawBitmap

Функция BitBlt наиболее эффективна при работе с битовыми образами, которые выбраны в контекст памяти. Когда вы выполняете перенос блока битов (bit block transfer) из контекста памяти в контекст устройства вашей рабочей области, битовый образ, выбранный в контексте памяти переносится в вашу рабочую область.

Ранее упоминалась гипотетическая функция DrawBitmap, которая выводила бы битовый образ на поверхность отображения. Такая функция должна иметь следующий синтаксис:

DrawBitmap(hdc, hBitmap, xStart, yStart);

Было обещано, что мы ее напишем. Вот она:

void DrawBitmap(HDC hdc, HBITMAP hBitmap, int xStart, int yStart)

{

BITMAP bm;

HDC hdcMem;

DWORD dwSize;

POINT ptSize, ptOrg;

hdcMem = CreateCompatibleDC(hdc);

SelectObject(hdcMem, hBitmap);

SetMapMode(hdcMem, GetMapMode(hdc));

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

ptSize.x = bm.bmWidth;

ptSize.y = bm.bmHeight;

DPtoLP(hdc, &ptSize, 1);

ptOrg.x = 0;

ptOrg.y = 0;

DPtoLP(hdcMem, &ptOrg, 1);

BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y,hdcMem, ptOrg.x, ptOrg.y, SRCCOPY);

DeleteDC(hdcMem);

}

Здесь предполагается, что вы не хотите растягивать или сжимать высоту или ширину битового образа. Таким образом, если ваш битовый образ имеет ширину 100 пикселей, то вы сможете с его помощью закрыть любой прямоугольник, имеющий ширину 100 пикселей, независимо от режима отображения.

Функция DrawBitmap сначала создает контекст памяти, используя функцию CreateCompatibleDC, затем выбирает в него битовый образ с использованием функции SelectObject. Режим отображения контекста памяти устанавливается таким же, как режим отображения контекста устройства вывода. Поскольку функция BitBlt работает с логическими координатами и логическими размерами, и учитывая то, что вы не предполагаете растягивать или сжимать битовый образ, параметры xWidth и yHeight функции BitBlt должны иметь значения в логических координатах, соответствующих размерам битового образа в физических координатах. Поэтому, функция DrawBitmap определяет размеры битового образа, используя функцию GetObject, и создает структуру POINT для сохранения в ней ширины и высоты. Затем она преобразует эту точку в логические координаты. Аналогичные действия осуществляются и в отношении начала координат битового образа — точки (0, 0) в координатах устройства.

Обратите внимание, что не имеет никакого значения, какая кисть выбрана в приемном контексте устройства (hdc), поскольку режим SRCCOPY не использует кисть.

4.10.8 Использование других rop кодов

SRCCOPY — самое часто встречающееся значение параметра dwROP функции BitBlt. Вам будет трудно найти примеры использования других 255 ROP кодов. Поэтому здесь будет показано несколько примеров, в которых используются другие ROP коды.

Первый пример: пусть у вас есть монохромный битовый образ, который вы хотите перенести на экран. При этом вы хотите отобразить битовый образ так, чтобы черные (0) биты не оказывали влияния на текущее содержание рабочей области. Более того, вы хотите, чтобы для всех белых (1) битов рабочая область закрашивалась кистью, возможно цветной, созданной функцией CreateSolidBrush. Как это сделать?

Предполагается, что вы работаете в режиме отображения MM_TEXT, и что вы хотите отобразить битовый образ, начиная в точке (xStart, yStart) вашей рабочей области. У вас также есть описатель монохромного битового образа (hBitmap) и описатель цветной кисти (hBrush). Вы также знаете ширину и высоту битового образа, и они хранятся в переменной bm структуры BITMAP. Вот код программы:

hdcMem = CreateCompatibleDC(hdc);

SelectObject(hdcMem, hBitmap);

hBrush = SelectObject(hdc, hBrush);

BitBlt(hdc, xStart, yStart, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, 0xE20746L);

SelectObject(hdc, hBrush);

DeleteDC(hdcMem);

Функция BitBlt выполняет логическую операцию над приемным контекстом устройства (hdc), исходным контекстом устройства (hdcMem) и кистью, выбранной в приемном контексте устройства. Вы создаете контекст памяти, выбираете в него битовый образ, выбираете цветную кисть в контекст устройства вашей рабочей области, и вызываете BitBlt. Затем вы выбираете исходную кисть в контекст устройства вашего дисплея и удаляете контекст памяти.

Осталось объяснить значение ROP кода 0xE20746 приведенного фрагмента программы. Этот код задает Windows выполнение следующей логической операции:

((Destination ^ Pattern) & Source) ^ Destination

Если опять непонятно, попробуйте разобраться в следующем:

Для каждого черного бита битового образа (который будет выбран в исходный контекст памяти), вы хотите, чтобы приемный контекст устройства оставался неизменным. Это означает, что везде, где Source равен 0, вы хотите, чтобы Result равнялся Destination:

Полдела сделано. Теперь для каждого белого бита битового образа вы хотите, чтобы приемный контекст закрашивался шаблоном. Кисть, выбранная вами в приемный контекст устройства — это шаблон. Таким образом, везде, где Source равен 1, вы хотите, чтобы Result равнялся Pattern:

Это означает, что старшее слово ROP кода равняется 0xE2. Вы можете заглянуть в таблицу ROP кодов пакета (например, в http://msdn.microsoft.com/en-us/library/aa452783.aspx) и обнаружить, что полный ROP код равен 0xE20746.

Если обнаружится, что вы перепутали белые и черные биты при создании битового образа, то это легко исправить, используя другую логическую операцию:

Теперь старшее слово ROP кода равно 0xB8, а весь ROP код равен 0xB8074A, что соответствует логической операции:

((Destination ^ Pattern) & Source) ^ Pattern

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

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

Windows выбирает битовый образ Bitmap1 в контекст памяти и использует функцию BitBlt с ROP кодом SRCAND для переноса битового образа на экран. Этот ROP код соответствует логической операции:

Destination & Source

Она сохраняет неизменными биты приемника, соответствующие единичным битам Bitmap1, и устанавливает в 0 биты, соответствующие нулевым битам Bitmap1. Затем Windows выбирает Bitmap2 в контекст устройства и использует функцию BitBlt с параметром SRCINVERT. Логическая операция такова:

Destination ^ Source

Данная операция сохраняет неизменными биты приемника, соответствующие нулевым битам Bitmap2, и инвертирует биты, соответствующие единичным битам Bitmap2.

Взгляните на первый и второй столбцы таблицы: Bitmap1 и SRCAND делают биты черными, а Bitmap2 и SRCINVERT инвертируют выбранные биты в белый цвет. Эти операции устанавливают белые и черные биты, которые составляют значок и курсор. Теперь посмотрите на третий и четвертый столбцы таблицы: Bitmap1 и SRCAND сохраняют дисплей неизменным, а Bitmap2 и SRCINVERT инвертируют цвета указанных битов. Эти операции делают значки и курсоры прозрачными или позволяют инвертировать цвет закрываемой области экрана.

Другой пример творческого использования ROP кодов приводится далее в этой главе при описании функции GrayString.

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