47952 (597372), страница 13
Текст из файла (страница 13)
DWORD GetBitmapDimension (hBmp);
BOOL GetBitmapDimensionEx (hBmp, lpSize);
DWORD SetBitmapDimension (hBmp, nWidth, nHeight);
BOOL SetBitmapDimensionEx (hBmp, nX, nY, lpSize);
Эти процедуры используются для задания/получения справочного размера битмапа, в единицах по 0.1 мм. Никакие иные функции GDI не используют эту информацию при работе с битмапами. Практически вы можете использовать эти размеры сами при необходимости передачи битмапов между устройствами с разной разрешающей способностью.
Получение зависимых от устройства битмапов как ресурсов приложения
Создание битмапов непосредственно в приложении — случай сравнительно редкий. Обычно битмапы рисуются с помощью какого–либо графического редактора и затем загружаются из файла (в этом случае загружается не DDB, а DIB), либо битмап добавляется в ресурсы приложения и затем загружается из ресурсов с помощью функции LoadBitmap. В этом случае выполняется загрузка именно в виде зависимого от устройства битмапа, хотя в ресурсах приложения размещается DIB.
Интересный нюанс — так как битмап из ресурсов приложения загружается как зависимый от устройства, то какому устройству будут соответствовать его характеристики? Microsoft считает, что такие битмапы будут отображаться преимущественно на дисплее, и, следовательно, DDB будет строиться под характеристики дисплея. Указать, для какого устройства битмап надо оптимизировать невозможно. В большинстве случаев этот подход вполне приемлем, однако при необходимости осуществлять вывод битмапа не только в окне, но и на иных устройствах (например на принтере или внедрять его в метафайл), лучше получить доступ непосредственно к самому DIB, записанному в ресурсах приложения (об этом — в разделе «Загрузка независимых от устройства битмапов.»).
Подробнее о применении и описании ресурсов приложения — см. раздел «Ресурсы приложения », здесь же будут представлены основные сведения об описании битмапов в качестве ресурсов приложения. Для описания битмапа в файле описания ресурсов принята следующая форма:
| nameId | уникальное имя или номер ресурса |
| load-opt 0 | режим загрузки ресурса: PRELOAD или LOADONCALL (по умолчанию) |
| mem-opt 0 | тип выделяемой памяти: FIXED, MOVEABLE (по умолчанию) или DISCARDABLE |
| filename.bmp | имя файла, содержащего битмап |
nameId BITMAP [load-opt] [mem-opt] filename.bmp (некоторые редакторы и компиляторы ресурсов, как, скажем, Borland WorkShop, позволяют описывать битмап непосредственно в файле описания ресурсов в текстовом виде. Тогда вместо filename.bmp используются структурные скобки BEGIN...END или {...} с заключенным между ними данными битмапа в виде списка шестнадцатеричных чисел. Этот способ не гарантирует переносимость ресурсов между разными средами разработки приложений.)
Часто режим загрузки ресурса и тип выделяемой памяти при описании битмапов не указывается — предлагаемые по умолчанию значения (загрузка по требованию и перемещаемый блок памяти) как правило являются оптимальными. Примеры описания битмапов:
red_brick BITMAP rbrick.bmp
1 BITMAP firm.bmp
Считается, что лучше использовать уникальные номера ресурсов, а не имена, так как это обеспечивает более быстрый поиск ресурса в приложении и требует меньше памяти для описания ресурсов приложения.
Для загрузки битмапа из ресурсов приложения используются функции:
HBITMAP LoadBitmap (hInstance, lpszName);
HANDLE LoadImage (hInstance, lpszName, uType, cxDesired, cyDesired, fuLoad); 1
где hInstance — хендл копии приложения, содержащего данный битмап, а lpszName — имя ресурса битмапа. Имя ресурса может быть либо текстом — тогда lpszName это обычная строка, оканчивающаяся символом ‘\0’, либо номером — тогда вместо lpszName может стоять или «#number», или MAKEINTRESOURCE (number). Например, для загрузки битмапов «red_brick» и «1» можно воспользоваться такими вызовами функций:
HBITMAP hbmpRedBrick = LoadBitmap (hInstance, red_brick);
HBITMAP hbmp1a = LoadBitmap (hInstance, #1);
HBITMAP hbmp1b = LoadBitmap (hInstance, MAKEINTRESOURCE (1));
Причем последний вариант является самым быстрым и компактным.
Функция LoadImage осуществляет загрузку битмапов, пиктограмм и курсоров. Теоретически она позволяет загружать требуемый ресурс из файла (для этого в fuLoad надо установить флаг LR_LOADFROMFILE и указать hInstance равным NULL). Однако такая операция поддерживается только в случае Windows–95, Windows NT 4.0 и более поздних. Предыдущие реализации Win32 API не поддерживают загрузку изображений из файлов.
Вы можете использовать стандартные битмапы, предоставляемые Windows. Их символические имена начинаются на OBM_... . Для того, что бы вы могли воспользоваться этими идентификаторами, необходимо перед директивой #include определить символ OEMRESOURCE, то есть:
#define OEMRESOURCE
#include
В таблице приведены изображения стандартных битмапов и их идентификаторы, в соответствии с их реализацией в Windows 3.x (Windows API) и Windows NT 3.x (Win32 API); в более поздних версиях (как, например, Windows–95, Windows NT 4.0) внешний вид стандартных битмапов несколько изменен. В таблице заполнены не все клетки просто из соображений построчной группировки схожих битмапов.
| | OBM_UPARROW | | OBM_UPARROWI | | OBM_UPARROWD | | OBM_OLD_UPARROW |
| | OBM_DNARROW | | OBM_DNARROWI | | OBM_DNARROWD | | OBM_OLD_DNARROW |
| | OBM_RGARROW | | OBM_RGARROWI | | OBM_RGARROWD | | OBM_OLD_RGARROW |
| | OBM_LFARROW | | OBM_LFARROWI | | OBM_LFARROWD | | OBM_OLD_LFARROW |
| | OBM_REDUCE | | OBM_REDUCED | | OBM_OLD_REDUCE | ||
| | OBM_ZOOM | | OBM_ZOOMD | | OBM_OLD_ZOOM | ||
| | OBM_RESTORE | | OBM_RESTORED | OBM_OLD_RESTORE | |||
| | OBM_CLOSE | OBM_OLD_CLOSE | |||||
| OBM_MNARROW | | OBM_COMBO | | OBM_SIZE | | OBM_BTSIZE | |
| | OBM_CHECK | | OBM_BTNCORNERS | OBM_CHECKBOX |
Работа с зависимым от устройства битмапом
Небольшое замечание: так как битмап является объектом GDI, то вы обязаны удалить его, как только он станет ненужным. Это относится ко всем битмапам, как созданным с помощью функций CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDiscardableBitmap, так и к загруженным с помощью функции LoadBitmap. Освобождение неиспользуемых битмапов особенно важно, так как это едва–ли не самые большие объекты GDI, занимающие значительные ресурсы.
В GDI практически не содержится функций, использующих зависимые от устройства битмапы непосредственно. Исключение, разве что, функции для создания кисти по образцу, для задания графического образа пункта меню или для передачи изображения в независимый от устройства битмап (подробнее см. в соответствующих разделах):
HBRUSH hbrBrush = CreatePatternBrush (hBmp);
DeleteBitmap (hBmp); // 2
После того, как мы создали кисть, битмап можно удалять, так как его образ скопирован в кисть и больше не используется. Если битмап больше, чем 8x8 пикселей, то для создания кисти будет использован его верхний–левый уголок, размером 8x8.
Все остальные операции по работе с битмапами осуществляются посредством специально создаваемого контекста устройства, ассоциированного с этим битмапом. Для этого был разработан специальный вид контекстов устройства — совместимый контекст (compatible device context, compatible DC, чаще называемый memory device context, memory DC). Такой разнобой в названиях контекста связан, с одной стороны, с названием функции, его создающей — CreateCompatibleDC — создающей контекст устройства, совместимого с другим, реально существующим устройством (см. раздел «Получение хендла контекста устройства»). А, с другой стороны, созданный таким образом контекст устройства не соответствует никакому физическому устройству, его область отображения — некоторое растровое изображение, хранимое в памяти. Отсюда второе название — memory DC.















