Sobre as listas de imagens

Uma lista de imagens é uma coleção de imagens do mesmo tamanho, cada uma das quais pode ser referida por seu índice. As listas de imagens são usadas para gerenciar com eficiência grandes conjuntos de ícones ou bitmaps. Todas as imagens em uma lista de imagens estão contidas em um único bitmap largo no formato de dispositivo de tela. Uma lista de imagens também pode incluir um bitmap monocromático que contém máscaras usadas para desenhar imagens de forma transparente (estilo de ícone).

A API do Microsoft Win32 fornece funções de lista de imagens e macros que permitem criar e destruir listas de imagens, adicionar e remover imagens, substituir e mesclar imagens, desenhar imagens e arrastar imagens. Para usar as funções de lista de imagens, inclua o arquivo de cabeçalho de controle comum em seus arquivos de código-fonte e vincule-o à biblioteca de exportação de controle comum. Além disso, antes de chamar qualquer função de lista de imagens, use a função InitCommonControls ou InitCommonControlsEx para garantir que a DLL de controle comum seja carregada.

Os tópicos a seguir são discutidos nesta seção:

Tipos

Existem dois tipos de listas de imagens: não mascaradas e mascaradas. Uma lista de imagens não mascaradas consiste em um bitmap colorido que contém uma ou mais imagens. Uma lista de imagens mascaradas consiste em dois bitmaps de tamanho igual. O primeiro é um bitmap colorido que contém as imagens, e o segundo é um bitmap monocromático que contém uma série de máscaras — uma para cada imagem no primeiro bitmap.

Quando uma imagem não mascarada é desenhada, ela é simplesmente copiada no contexto do dispositivo de destino, ou seja, é desenhada sobre a cor da tela de fundo existente do contexto do dispositivo. Quando uma imagem mascarada é desenhada, os bits da imagem são combinados com os bits da máscara, normalmente produzindo áreas transparentes no bitmap em que a cor da tela de fundo do contexto do dispositivo de destino é exibida. Há vários estilos de desenho que você pode especificar ao desenhar uma imagem mascarada. Por exemplo, você pode especificar que a imagem seja pontilhada para indicar um objeto selecionado.

Criando e destruindo listas de imagens

Você cria uma lista de imagens chamando a função ImageList_Create. Os parâmetros incluem o tipo de lista de imagens a ser criada, as dimensões de cada imagem e o número de imagens que você pretende adicionar à lista. Para uma lista de imagens não mascaradas, a função cria um único bitmap grande o suficiente para conter o número especificado de imagens das dimensões fornecidas. Em seguida, ele cria um contexto de dispositivo compatível com a tela e seleciona o bitmap nele. Para uma lista de imagens mascaradas, a função cria dois bitmaps e dois contextos de dispositivo compatíveis com a tela. Ele seleciona o bitmap de imagem em um contexto de dispositivo e o bitmap de máscara no outro. A DLL de controle comum contém o código executável para as funções de lista de imagens.

Em ImageList_Create, você especifica o número inicial de imagens que estarão em uma lista de imagens, bem como o número de imagens pelas quais a lista pode crescer. Portanto, se você tentar adicionar mais imagens do que o especificado inicialmente, a lista de imagens crescerá automaticamente para acomodar as novas imagens.

Se ImageList_Create for bem-sucedido, ele retornará um identificador para o tipo HIMAGELIST. Use esse identificador em outras funções de lista de imagens para acessar a lista de imagens e gerenciar as imagens. Você pode adicionar e remover imagens, copiar imagens de uma lista de imagens para outra e mesclar imagens de duas listas de imagens diferentes. Quando você não precisar mais de uma lista de imagens, poderá destruí-la especificando seu identificador em uma chamada para a função ImageList_Destroy.

Adicionando e removendo imagens

Você pode adicionar imagens, ícones ou cursores bitmap a uma lista de imagens. Você adiciona imagens bitmap especificando os identificadores para dois bitmaps em uma chamada para a função ImageList_Add. O primeiro bitmap contém uma ou mais imagens para adicionar ao bitmap de imagem e o segundo bitmap contém as máscaras para adicionar ao bitmap de máscara. Para listas de imagens não mascaradas, o segundo identificador de bitmap é ignorado; ele pode ser definido como NULL.

A função ImageList_AddMasked também adiciona imagens bitmap a uma lista de imagens mascaradas. Essa função é semelhante a ImageList_Add, exceto que você não especifica um bitmap de máscara. Em vez disso, você especifica uma cor que o sistema combina com o bitmap de imagem para gerar automaticamente as máscaras. Cada pixel da cor especificada no bitmap de imagem é alterado para preto e o bit correspondente na máscara é definido como 1. Como resultado, qualquer pixel na imagem que corresponda à cor especificada é transparente quando a imagem é desenhada.

A macro ImageList_AddIcon adiciona um ícone ou cursor a uma lista de imagens. Se a lista de imagens estiver mascarada, ImageList_AddIcon adicionará a máscara fornecida com o ícone ou o cursor ao bitmap de máscara. Se a lista de imagens não estiver mascarada, a máscara do ícone ou cursor não será usada ao desenhar a imagem.

Você pode criar um ícone com base em uma imagem e máscara em uma lista de imagens usando a função ImageList_GetIcon . A função retorna o identificador para o novo ícone.

ImageList_Add, ImageList_AddMasked e ImageList_AddIcon atribuir um índice a cada imagem à medida que ela é adicionada a uma lista de imagens. Os índices são baseados em zero; ou seja, a primeira imagem da lista tem um índice de zero, a próxima tem um índice de um, e assim por diante. Depois de adicionar uma única imagem, as funções retornam o índice da imagem. Quando mais de uma imagem é adicionada ao mesmo tempo, as funções retornam o índice da primeira imagem.

A função ImageList_Remove remove uma imagem de uma lista de imagens.

Substituindo e mesclando imagens

As funções ImageList_Replace e ImageList_ReplaceIcon substituem uma imagem em uma lista de imagens por uma nova imagem. ImageList_Replace substitui uma imagem por uma imagem bitmap e máscara e ImageList_ReplaceIcon substitui uma imagem por um ícone ou cursor.

A função ImageList_Merge mescla duas imagens, armazenando a nova imagem em uma nova lista de imagens. A nova imagem é criada desenhando a segunda imagem de forma transparente sobre a primeira. A máscara para a nova imagem é o resultado da execução de uma operação lógica OR nos bits das máscaras para as duas imagens existentes.

Desenhando Imagens

Para desenhar uma imagem, use a função ImageList_Draw ou ImageList_DrawEx. Você especifica o identificador para uma lista de imagens, o índice da imagem a ser desenhada, o identificador para o contexto do dispositivo de destino, um local dentro do contexto do dispositivo e um ou mais estilos de desenho.

Quando você especifica o estilo ILD_TRANSPARENT, ImageList_Draw ou ImageList_DrawEx usa um processo de duas etapas para desenhar uma imagem mascarada. Primeiro, ele executa uma operação lógica AND nos bits da imagem e nos bits da máscara. Em seguida, ele executa uma operação XOR lógica nos resultados da primeira operação e nos bits de plano de fundo do contexto do dispositivo de destino. Esse processo cria áreas transparentes na imagem resultante; ou seja, cada bit branco na máscara torna transparente o bit correspondente na imagem resultante.

Antes de desenhar uma imagem mascarada em um plano de fundo de cor sólida, você deve usar a função ImageList_SetBkColor para definir a cor de plano de fundo da lista de imagens para a mesma cor do destino. A definição da cor elimina a necessidade de criar áreas transparentes na imagem e permite que ImageList_Draw ou ImageList_DrawEx simplesmente copiem a imagem para o contexto do dispositivo de destino, resultando em um aumento significativo no desempenho. Para desenhar a imagem, especifique o estilo ILD_NORMAL em uma chamada para ImageList_Draw ou ImageList_DrawEx.

Você pode definir a cor do plano de fundo para uma lista de imagens mascaradas a qualquer momento para que ela seja desenhada corretamente em qualquer plano de fundo sólido. Definir a cor da tela de fundo como CLR_NONE faz com que, por padrão, as imagens sejam desenhadas de forma transparente. Para recuperar a cor do plano de fundo de uma lista de imagens, use a função ImageList_GetBkColor.

Os estilos ILD_BLEND25 e ILD_BLEND50 pontilham a imagem com a cor de realce do sistema. Esses estilos serão úteis se você for usar uma imagem mascarada para representar um objeto que o usuário pode selecionar. Por exemplo, você pode usar o estilo ILD_BLEND50 para desenhar a imagem quando o usuário a seleciona.

Uma imagem não mascarada é copiada para o contexto do dispositivo de destino usando a operação de raster SRCCOPY. As cores na imagem aparecem da mesma forma, independentemente da cor da tela de fundo do contexto do dispositivo. Os estilos de desenho especificados em ImageList_Draw ou ImageList_DrawEx também não têm efeito sobre a aparência de uma imagem não mascarada.

Arrastando imagens

A API do Win32 inclui funções para arrastar uma imagem na tela. As funções de arrastar movem uma imagem suavemente, em cores e sem que o cursor fique piscando. Imagens mascaradas e sem máscara podem ser arrastadas.

A função ImageList_BeginDrag inicia uma operação de arrastar. Os parâmetros incluem o identificador da lista de imagens, o índice da imagem a ser arrastada e o local do ponto de acesso dentro da imagem. O ponto de acesso é um único pixel que as funções de arrastar reconhecem como o local exato da tela da imagem. Normalmente, um aplicativo define o ponto de acesso para que ele coincida com o ponto de acesso do cursor do mouse. A função ImageList_DragMove move a imagem para um novo local.

A função ImageList_DragEnter define a posição inicial da imagem de arrastar dentro de uma janela e desenha a imagem na posição. Os parâmetros incluem a alça da janela na qual desenhar a imagem e as coordenadas da posição inicial dentro da janela. As coordenadas são relativas ao canto superior esquerdo da janela (não da área do cliente). O mesmo é verdadeiro para todas as funções de arrastar imagem que tomam coordenadas como parâmetros. Isso significa que você deve compensar as larguras dos elementos da janela, como a borda, a barra de título e a barra de menus, ao especificar as coordenadas. Se você especificar um identificador de janela NULL ao chamar ImageList_DragEnter, as funções de arrastar desenharão a imagem no contexto do dispositivo associado à janela da área de trabalho e as coordenadas serão relativas ao canto superior esquerdo da tela.

A função ImageList_SetDragCursorImage cria uma nova imagem de arrastar combinando a imagem fornecida (normalmente uma imagem do cursor do mouse) com a imagem de arrastar atual. Como as funções de arrastar usam a nova imagem durante uma operação de arrastar, você deve usar a função ShowCursor para ocultar o cursor real do mouse depois de chamá ImageList_SetDragCursorImage. Caso contrário, o sistema pode parecer ter dois cursores do mouse durante a operação de arrastar.

Quando um aplicativo chama ImageList_BeginDrag, o sistema cria uma lista de imagens interna temporária e, em seguida, copia a imagem de arrastar especificada para a lista interna. Você pode recuperar o identificador para a lista de imagens de arrastar temporária usando a função ImageList_GetDragImage . A função também recupera a posição de arrastar atual e o deslocamento da imagem de arrasto em relação à posição de arrastar.

Informações da imagem

Há uma série de funções que recuperam informações de uma lista de imagens. A função ImageList_GetImageInfo preenche uma estrutura IMAGEINFO com informações sobre uma única imagem, incluindo as alças dos bitmaps de imagem e máscara, o número de planos de cores e bits por pixel e o retângulo delimitador da imagem dentro do bitmap de imagem. Você pode usar essas informações para manipular diretamente os bitmaps para a imagem. A função ImageList_GetImageCount recupera o número de imagens em uma lista de imagens.

Sobreposições de imagem

Cada lista de imagens inclui uma lista de índices a serem usados como sobreposições. Uma sobreposição é uma imagem que é desenhada de forma transparente sobre outra imagem. Qualquer imagem atualmente na lista de imagens pode ser usada como uma sobreposição. Você pode especificar até quatro sobreposições por lista de imagens. Esse limite foi expandido para 15 na versão 4.71.

Você adiciona o índice de uma imagem à lista de sobreposições usando a função ImageList_SetOverlayImage, especificando o identificador para a lista de imagens, o índice da imagem existente e o índice de sobreposição desejado. Isso, na verdade, diz à lista de imagens que "a imagem no índice x pode ser usada como uma sobreposição, e eu quero me referir à sobreposição como índice de sobreposição y". Os índices de sobreposição são baseados em um, em vez de zero, porque um índice de sobreposição de zero significa que nenhuma sobreposição será usada.

Você especifica uma sobreposição ao desenhar uma imagem com a função ImageList_Draw ou ImageList_DrawEx. A sobreposição é especificada executando uma operação lógica OR entre os sinalizadores de desenho desejados e o resultado da macro INDEXTOOVERLAYMASK. A macro INDEXTOOVERLAYMASK pega o índice de sobreposição e o formata para inclusão com os sinalizadores para essas funções. Isso desenhará a imagem com a sobreposição especificada. O exemplo a seguir demonstra como uma sobreposição é adicionada e especificada ao desenhar a imagem.

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

Isso desenhará a imagem 1 e, em seguida, sobreporá essa imagem com a imagem 0. Como 3 é o índice de sobreposição que você especificou na chamada ImageList_SetOverlayImage , 3 é colocado na macro INDEXTOOVERLAYMASK .

Ícones sem serrilhado de 32 bits

A suavização de borda é uma técnica para suavizar ou borrar bordas nítidas. Isso dá às imagens uma aparência mais natural. As listas de imagens no Windows Vista e no Windows 7 oferecem suporte ao uso de ícones e bitmaps sem serrilhado de 32 bits. Os valores de cor usam 24 bits e 8 bits são usados como um canal alfa nos ícones. Para criar uma lista de imagens que possa manipular uma imagem de 32 bits por pixel (bpp), chame a função ImageList_Create , passando um sinalizador ILC_COLOR32.

Para criar ícones de 32 bits corretamente, você deve criar várias imagens para cada ícone, conforme mostrado na ilustração a seguir.

illustration showing three sizes of icons for each of three color depths

  • As três primeiras imagens estão no modo de 16 cores para uso no modo de segurança.
  • Os próximos três ícones são usados no modo de 256 cores.
  • Os três últimos ícones têm o canal alfa e podem ser usados apenas em sistemas operacionais que executam cores de 24 bits ou superiores.
  • A ordem das imagens no formato de ícone é importante. Se a ordem estiver errada, as versões mais antigas do Windows funcionam mal ao extrair os ícones. Extrair os ícones incorretamente pode causar corrupção de memória e renderização inadequada.
  • As versões anteriores do Windows tinham um limite de recursos de 10 ícones.

Observação

Você pode usar ferramentas de terceiros para gerar arquivos de ícone e bitmaps que contêm um canal alfa. Se você usar LoadImage para carregar um bitmap de 32 bpp que contém alfa, será necessário especificar o sinalizador LR_CREATEDIBSECTION.