Поделиться через


Сведения о списках изображений

Список изображений — это коллекция изображений одного размера, каждая из которых может ссылаться на его индекс. Списки изображений используются для эффективного управления большими наборами значков или растровых изображений. Все изображения в списке изображений содержатся в одном широкоформатном растровом изображении в формате экрана. Список изображений также может содержать монохромное растровое изображение, содержащее маски, которые используются для прозрачного рисования изображений (стиль значка).

API Microsoft Win32 предоставляет функции списка изображений и макросы, которые позволяют создавать и уничтожать списки изображений, добавлять и удалять изображения, заменять и объединять изображения, рисовать изображения и перетаскивать изображения. Чтобы использовать функции списка изображений, включите общий файл заголовка элемента управления в файлы исходного кода и свяжите с общей библиотекой экспорта элементов управления. Кроме того, перед вызовом функции списка изображений используйте функцию InitCommonControls или InitCommonControlsEx, чтобы обеспечить загрузку библиотеки DLL общего элемента управления.

В этом разделе рассматриваются следующие разделы:

Типы

Существует два типа списков изображений: немаскированные и маскированные. Список немаскированных изображений состоит из цветовой растровой карты, содержащей один или несколько изображений. Список маскированных изображений состоит из двух растровых изображений равного размера. Первое — это цветовая растровая карта, содержащая изображения, а второй — монохромное растровое изображение, содержащее ряд маск — по одному для каждого изображения в первом растровом рисунке.

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

Создание и уничтожение списков изображений

Создайте список изображений, вызвав функцию ImageList_Create. Параметры включают тип списка изображений для создания, размеры каждого изображения и количество изображений, которые вы планируете добавить в список. Для немаскированного списка изображений функция создает достаточно большое одно растровое изображение, чтобы содержать указанное количество изображений заданных измерений. Затем он создает контекст устройства, совместимый с экраном, и выбирает в него растровое изображение. Для списка маскированных изображений функция создает два битмапа и два контекста устройства, совместимых с экраном. Он выбирает растровое изображение в одном контексте устройства и изображение маски в другом. Библиотека DLL общих элементов управления содержит исполняемый код для функций списка изображений.

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

Если ImageList_Create успешно, он возвращает дескриптор в тип HIMAGELIST. Этот идентификатор используется в других функциях для доступа к списку изображений и управления ими. Вы можете добавлять и удалять изображения, копировать изображения из одного списка изображений в другой и объединять изображения из двух разных списков изображений. Если список изображений больше не нужен, его можно уничтожить, указав его дескриптор в вызове функции ImageList_Destroy.

Добавление и удаление изображений

Вы можете добавить битовые изображения, значки или курсоры в список изображений. Вы добавляете растровые изображения, указав дескрипторы для двух битмапов в вызове функции ImageList_Add. Первая растровая карта содержит одно или несколько изображений для добавления в растровое изображение, а вторая растровая карта содержит маски для добавления в растровое изображение. Для немаскированных списков изображений второй дескриптор битмапа игнорируется; его можно задать равным NULL.

Функция ImageList_AddMasked также добавляет растровые изображения в список маскированных изображений. Эта функция аналогична ImageList_Add, за исключением того, что вы не указываете растровое изображение маски. Вместо этого вы указываете цвет, который система объединяет с растровым изображением изображения, чтобы автоматически создавать маски. Каждый пиксель указанного цвета в растровом изображении изменяется на черный, а соответствующий бит в маске имеет значение 1. В результате любой пиксель в изображении, соответствующий указанному цвету, является прозрачным при рисовании изображения.

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

Значок можно создать на основе изображения и маски в списке изображений с помощью функции ImageList_GetIcon. Функция возвращает дескриптор новой иконки.

ImageList_Add, ImageList_AddMaskedи ImageList_AddIcon назначают индексы каждому изображению по мере добавления в список изображений. Индексы основаны на нулях; То есть первый образ в списке имеет индекс нуля, следующий имеет индекс одного и т. д. После добавления одного изображения функции возвращают индекс изображения. При добавлении нескольких изображений одновременно функции возвращают индекс первого изображения.

Функция ImageList_Remove удаляет изображение из списка изображений.

Замена и объединение образов

Функции ImageList_Replace и ImageList_ReplaceIcon заменяют изображение в списке изображений новым изображением. ImageList_Replace заменяет изображение растровым изображением и маской, а ImageList_ReplaceIcon заменяет изображение значком или курсором.

Функция ImageList_Merge объединяет два образа, сохраняя новый образ в новом списке образов. Новое изображение создается путем наложения второго изображения прозрачным образом на первое. Маска для нового изображения является результатом выполнения логической ИЛИ операции на битах маски для двух существующих изображений.

Рисование изображений

Чтобы нарисовать изображение, используйте функцию ImageList_Draw или ImageList_DrawEx. Вы указываете дескриптор списка изображений, индекс рисунка для рисования, дескриптор контекста конечного устройства, расположение в контексте устройства и один или несколько стилей рисования.

При указании стиля ILD_TRANSPARENTImageList_Draw или ImageList_DrawEx используется двухэтапный процесс для рисования маскированного изображения. Во-первых, он выполняет логическую И операцию на битах изображения и битах маски. Затем он выполняет логическую операцию XOR над результатами первой операции и фоновыми битами контекста устройства назначения. Этот процесс создает прозрачные области в полученном изображении; То есть каждый белый бит в маске приводит к тому, что соответствующий бит в результирующем изображении будет прозрачным.

Перед рисованием маскированного изображения на сплошном цвете фона следует использовать функцию ImageList_SetBkColor, чтобы задать цвет фона списка изображений таким же цветом, что и назначение. Настройка цвета устраняет необходимость создания прозрачных областей на изображении и позволяет ImageList_Draw или ImageList_DrawEx просто копировать изображение в контекст целевого устройства, что приводит к значительному увеличению производительности. Чтобы нарисовать изображение, укажите стиль ILD_NORMAL в вызове ImageList_Draw или ImageList_DrawEx.

Цвет фона для списка маскированных изображений можно задать в любое время, чтобы он правильно рисовал на любом сплошном фоне. Установка цвета фона на CLR_NONE приводит к тому, что изображения будут вырисовываться прозрачно по умолчанию. Чтобы получить цвет фона списка изображений, используйте функцию ImageList_GetBkColor.

Стили ILD_BLEND25 и ILD_BLEND50 создают эффект дизеринга изображения с использованием системного цвета выделения. Эти стили полезны, если вы используете маскированные изображения для представления объекта, который пользователь может выбрать. Например, можно использовать стиль ILD_BLEND50 для рисования изображения, когда пользователь выбирает его.

Немаскированное изображение копируется в контекст целевого устройства с помощью операции растрового изображения SRCCOPY. Цвета в изображении отображаются одинаково независимо от цвета фона контекста устройства. Стили рисования, указанные в ImageList_Draw или ImageList_DrawEx, также не влияют на внешний вид немаскированного изображения.

Перетаскивание изображений

API Win32 включает функции для перетаскивания изображения на экране. Функции перетаскивания плавно перемещают изображение в цвете, без мигания курсора. Можно перетаскивать как маскированные, так и незамаскированные изображения.

Функция ImageList_BeginDrag начинает операцию перетаскивания. Параметры включают дескриптор списка изображений, индекс изображения, которое нужно перетаскивать, и расположение горячей точки в изображении. Горячая точка — это один пиксель, который функции перетаскивания распознают как точное расположение экрана изображения. Как правило, приложение устанавливает горячее место таким образом, чтобы оно совпадало с горячей точкой курсора мыши. Функция ImageList_DragMove перемещает изображение в новое расположение.

Функция ImageList_DragEnter задает начальную позицию изображения перетаскивания в окне и отображает изображение в этой позиции. Параметры включают дескриптор окна, в котором рисуется изображение, и координаты начальной позиции в окне. Координаты относительно левого верхнего угла окна, а не клиентской области. То же самое верно для всех функций перетаскивания изображений, которые принимают координаты в качестве параметров. Это означает, что при указании координат необходимо компенсировать ширину элементов окна, таких как граница, строка заголовка и строка меню. Если при вызове ImageList_DragEnterуказан дескриптор окна NULL, то функции перетаскивания отображают изображение в контексте устройства, которое связано с окном рабочего стола, а координаты указываются относительно левого верхнего угла экрана.

Функция ImageList_SetDragCursorImage создает новое изображение перетаскивания путем объединения заданного изображения (обычно изображения курсора мыши) с текущим изображением перетаскивания. Поскольку функции перетаскивания используют новое изображение во время операции перетаскивания, следует использовать функцию ShowCursor, чтобы скрыть фактический курсор мыши после вызова ImageList_SetDragCursorImage. В противном случае в системе могут отображаться два курсора мыши в течение операции перетаскивания.

Когда приложение вызывает ImageList_BeginDrag, система создает временный, внутренний список изображений, а затем копирует указанное изображение для перетаскивания во внутренний список. Вы можете получить дескриптор временного списка изображений перетаскивания с помощью функции ImageList_GetDragImage. Функция также извлекает текущую позицию перетаскивания и смещение изображения перетаскивания относительно позиции перетаскивания.

Сведения об изображении

Существует ряд функций, которые извлекают информацию из списка изображений. Функция ImageList_GetImageInfo заполняет структуру IMAGEINFO сведениями об одном изображении, включая дескрипторы изображения и маски, количество цветовых плоскостей и битов на пиксель, а также ограничивающий прямоугольник изображения в пределах растрового изображения. Эту информацию можно использовать для непосредственного управления растровыми изображениями. Функция ImageList_GetImageCount извлекает количество изображений в списке изображений.

Наложения изображений

Каждый список изображений содержит список индексов для использования в качестве наложений. Наложение — это изображение, которое прозрачно наложено на другое изображение. Любой образ в настоящее время в списке изображений можно использовать в качестве наложения. Можно указать до четырех наложений на список изображений. Это ограничение было расширено до 15 в версии 4.71.

Вы добавляете индекс изображения в список наложений с помощью функции ImageList_SetOverlayImage, указав дескриптор списка изображений, индекс существующего изображения и требуемый индекс наложения. Это на деле сообщает списку изображений, что "изображение на индексе x можно использовать как наложение, и я хочу ссылаться на наложение как на индекс наложения y". Индексы наложения являются единичными, а не с нуля, поскольку индекс наложения нуля означает, что наложение не будет использоваться.

Вы указываете наложение при рисовании изображения с помощью функции ImageList_Draw или ImageList_DrawEx. Наложение задается путем выполнения логической операции ИЛИ между нужными флагами рисования и результатом макроса INDEXTOOVERLAYMASK. Макрос INDEXTOOVERLAYMASK принимает индекс наложения и форматирует его для включения вместе с флагами для этих функций. Это нарисует изображение с указанным наложением. В следующем примере показано, как добавляется и задается наложение при рисовании изображения.

ImageList_SetOverlayImage(himl, 0, 3);
ImageList_Draw(himl, 1, hdc, 0, 0, ILD_MASK | INDEXTOOVERLAYMASK(3));

Нарисуйте изображение 1, а затем наложите его на изображение 0. Так как 3 — это индекс наложения, указанный в вызове ImageList_SetOverlayImage, 3 помещается в макрос INDEXTOOVERLAYMASK.

32-разрядные антиалиасные значки

Антилайсинг — это техника для смягчения или размытия острых ребер. Это дает изображения более естественного вида. Списки изображений в Windows Vista и Windows 7 поддерживают использование 32-разрядных значков и растровых изображений. Значения цвета используют 24 бита, а 8 битов используются в качестве альфа-канала на значках. Чтобы создать список изображений, который может обрабатывать 32-битовое изображение на пиксель (bpp), вызовите функцию ImageList_Create, передавая флаг ILC_COLOR32.

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

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

  • Первые три изображения находятся в 16 цветовом режиме для использования в безопасном режиме.
  • Следующие три значка используются в 256-цветовом режиме.
  • Последние три значка имеют альфа-канал и могут использоваться только в операционных системах с цветностью 24 бита или выше.
  • Порядок изображений в формате значка имеет значение. Если порядок неправильный, старые версии Windows плохо работают при извлечении значков. Неправильное извлечение значков может привести к повреждению памяти и неправильной отрисовке.
  • В предыдущих версиях Windows было ограничение ресурсов на 10 значков.

Заметка

Вы можете использовать сторонние средства для создания файлов значков и растровых изображений, содержащих альфа-канал. Если вы используете LoadImage для загрузки 32 битового изображения bpp, содержащего альфа-файл, необходимо указать флаг LR_CREATEDIBSECTION.