Udostępnij za pośrednictwem


Informacje o listach grafik

Lista obrazów jest kolekcją obrazów o tym samym rozmiarze, z których każdy może być określany przez jego indeks. Listy obrazów służą do wydajnego zarządzania dużymi zestawami ikon lub map bitowych. Wszystkie obrazy na liście obrazów są zawarte w jednej, szerokiej mapie bitowej w formacie urządzenia ekranu. Lista obrazów może również zawierać monochromatyczną mapę bitową zawierającą maski używane do rysowania obrazów w sposób przezroczysty (styl ikony).

Interfejs API platformy Microsoft Win32 udostępnia funkcje i makra listy obrazów, które umożliwiają tworzenie i niszczenie list obrazów, dodawanie i usuwanie obrazów, zastępowanie i scalanie obrazów, rysowanie obrazów i przeciąganie obrazów. Aby użyć funkcji listy obrazów, dołącz wspólny plik nagłówka kontrolki do plików kodu źródłowego i połącz go ze wspólną biblioteką eksportu kontrolek. Ponadto przed wywołaniem dowolnej funkcji listy obrazów użyj funkcji InitCommonControls lub InitCommonControlsEx, aby upewnić się, że biblioteka DLL dla wspólnych kontrolek jest załadowana.

W tej sekcji omówiono następujące tematy:

Typy

Istnieją dwa typy list obrazów: niemaskowane i maskowane. Niemaskowana lista obrazów składa się z kolorowej mapy bitowej zawierającej co najmniej jeden obraz. Lista zamaskowanych obrazów składa się z dwóch map bitowych o równym rozmiarze. Pierwsza to mapa bitowa koloru zawierająca obrazy, a druga to monochromatyczna mapa bitowa zawierająca serię masek — po jednym dla każdego obrazu w pierwszej mapie bitowej.

Gdy obraz niemaskowany jest rysowany, jest po prostu kopiowany do kontekstu urządzenia docelowego; oznacza to, że jest rysowany na istniejącym kolorze tła kontekstu urządzenia. Podczas rysowania zamaskowanego obrazu, bity obrazu są łączone z bitami maski, co zazwyczaj powoduje powstanie przezroczystych obszarów na bitmapie, gdzie prześwituje kolor tła z kontekstu urządzenia docelowego. Istnieje kilka stylów rysunku, które można określić podczas rysowania maskowanego obrazu. Można na przykład określić, że obraz ma być rozproszkowany, aby wskazać wybrany obiekt.

Tworzenie i niszczenie list obrazów

Listę obrazów można utworzyć, wywołując funkcję ImageList_Create. Parametry obejmują typ listy obrazów do utworzenia, wymiary każdego obrazu oraz liczbę obrazów, które mają zostać dodane do listy. W przypadku listy obrazów niemaskowanych funkcja tworzy pojedynczą mapę bitową wystarczająco dużą, aby przechowywać określoną liczbę obrazów podanych wymiarów. Następnie tworzy kontekst urządzenia zgodnego z ekranem i wybiera do niego mapę bitową. W przypadku listy obrazów maskowanych funkcja tworzy dwie mapy bitowe i dwa konteksty urządzenia zgodne z ekranem. Wybiera mapę bitową obrazu do jednego kontekstu urządzenia, a mapę bitową maski do drugiego. Wspólna biblioteka DLL kontrolki zawiera kod wykonywalny dla funkcji listy obrazów.

W ImageList_Createokreśl początkową liczbę obrazów, które będą znajdować się na liście obrazów, a także liczbę obrazów, według których lista może rosnąć. Dlatego jeśli próbujesz dodać więcej obrazów niż początkowo określone, lista obrazów automatycznie zwiększa się, aby pomieścić nowe obrazy.

Jeśli ImageList_Create się powiedzie, zwraca uchwyt do typu HIMAGELIST. Ten uchwyt jest używany w innych funkcjach listy obrazów w celu uzyskiwania dostępu do listy obrazów i zarządzania nimi. Obrazy można dodawać i usuwać, kopiować obrazy z jednej listy obrazów do innej i scalać obrazy z dwóch różnych list obrazów. Gdy nie potrzebujesz już listy obrazów, możesz ją zniszczyć, określając jej uchwyt w wywołaniu funkcji ImageList_Destroy.

Dodawanie i usuwanie obrazów

Do listy obrazów można dodawać mapowane bitowo obrazy, ikony lub kursory. Obrazy bitmapowe można dodawać, określając uchwyty do dwóch bitmap w wywołaniu funkcji ImageList_Add. Pierwsza mapa bitowa zawiera jeden lub więcej obrazów do dodania do mapy bitowej, a druga mapa bitowa zawiera maski do dodania do mapy bitowej. W przypadku list obrazów niemaskowanych drugi uchwyt mapy bitowej jest ignorowany; można go ustawić na wartość NULL.

Funkcja ImageList_AddMasked dodaje obrazy bitmapowe również do listy zamaskowanych obrazów. Ta funkcja jest podobna do ImageList_Add, z wyjątkiem tego, że nie określa się maski bitmapy. Zamiast tego należy określić kolor, który system łączy z mapą bitową obrazu, aby automatycznie wygenerować maski. Każdy piksel określonego koloru w mapie bitowej obrazu jest zmieniany na czarny, a odpowiedni bit w masce ma wartość 1. W związku z tym każdy piksel w obrazie, który pasuje do określonego koloru, jest przezroczysty, gdy obraz jest rysowany.

Makro ImageList_AddIcon dodaje ikonę lub kursor do listy obrazów. Jeśli lista obrazów jest maskowana, ImageList_AddIcon dodaje do bitmapy maski maskę dostarczoną z ikoną lub kursorem. Jeśli lista obrazów nie jest maskowana, maska ikony lub kursora nie jest używana podczas rysowania obrazu.

Ikonę można utworzyć na podstawie obrazu i maski na liście obrazów przy użyciu funkcji ImageList_GetIcon. Funkcja zwraca uchwyt do nowej ikony.

ImageList_Add, ImageList_AddMaskedi ImageList_AddIcon przypisuje indeks do każdego obrazu podczas dodawania go do listy obrazów. Indeksy są oparte na zerach; oznacza to, że pierwszy obraz na liście ma indeks zero, następny ma indeks jeden itd. Po dodaniu pojedynczego obrazu funkcje zwracają indeks obrazu. Po dodaniu więcej niż jednego obrazu w danym momencie funkcje zwracają indeks pierwszego obrazu.

Funkcja ImageList_Remove usuwa obraz z listy obrazów.

Zastępowanie i scalanie obrazów

Funkcje ImageList_Replace i ImageList_ReplaceIcon zastępują obraz na liście obrazów nowym obrazem. ImageList_Replace zastępuje obraz mapą bitową i maską, a ImageList_ReplaceIcon zastępuje obraz ikoną lub kursorem.

Funkcja ImageList_Merge scala dwa obrazy, przechowując nowy obraz na nowej liście obrazów. Nowy obraz jest tworzony przez rysowanie drugiego obrazu w sposób niewidoczny dla pierwszego. Maska dla nowego obrazu jest wynikiem wykonania operacji logicznej LUB na bitach masek dla dwóch istniejących obrazów.

Rysowanie obrazów

Aby narysować obraz, należy użyć funkcji ImageList_Draw lub ImageList_DrawEx. Należy określić dojście do listy obrazów, indeks obrazu do rysowania, uchwyt do kontekstu urządzenia docelowego, lokalizację w kontekście urządzenia i co najmniej jeden styl rysunku.

Po określeniu stylu ILD_TRANSPARENTImageList_Draw lub ImageList_DrawEx używa dwuetapowego procesu do rysowania zamaskowanego obrazu. Najpierw wykonuje operację logiczną AND na bitach obrazu i bitach maski. Następnie wykonuje operację logiczną XOR na wynikach pierwszej operacji oraz bitach tła w kontekście urządzenia docelowego. Ten proces tworzy przezroczyste obszary na obrazie wynikowym; oznacza to, że każdy biały bit w masce powoduje, że odpowiedni bit w wynikowym obrazie będzie przezroczysty.

Przed narysowania maskowanego obrazu na tle koloru stałego należy użyć funkcji ImageList_SetBkColor, aby ustawić kolor tła listy obrazów na taki sam kolor jak miejsce docelowe. Ustawienie koloru eliminuje konieczność tworzenia przezroczystych obszarów na obrazie i umożliwia ImageList_Draw lub ImageList_DrawEx po prostu skopiować obraz do kontekstu urządzenia docelowego, co powoduje znaczny wzrost wydajności. Aby narysować obraz, określ styl ILD_NORMAL w wywołaniu ImageList_Draw lub ImageList_DrawEx.

Kolor tła dla listy zamaskowanych obrazów można ustawić w dowolnym momencie, aby był on prawidłowo rysowany na dowolnym stałym tle. Ustawienie koloru tła na CLR_NONE powoduje, że obrazy są domyślnie rysowane w przezroczysty sposób. Aby pobrać kolor tła listy obrazów, użyj funkcji ImageList_GetBkColor.

Style ILD_BLEND25 i ILD_BLEND50 aplikują dithering na obraz za pomocą koloru podświetlenia systemu. Te style są przydatne, jeśli używasz maskowanego obrazu do reprezentowania obiektu, który użytkownik może wybrać. Na przykład możesz użyć stylu ILD_BLEND50, aby narysować obraz po wybraniu go przez użytkownika.

Niemaskowany obraz jest kopiowany do kontekstu urządzenia docelowego przy użyciu operacji raster SRCCOPY. Kolory na obrazie są takie same niezależnie od koloru tła kontekstu urządzenia. Style rysunku określone w ImageList_Draw lub ImageList_DrawEx również nie mają wpływu na wygląd niemaskowanego obrazu.

Przeciąganie obrazów

Interfejs API Win32 zawiera funkcje przeciągania obrazu na ekranie. Funkcje przeciągania przesuwają obraz płynnie, w kolorze i bez migotania kursora. Obrazy maskowane i niemaskowane można przeciągać.

Funkcja ImageList_BeginDrag rozpoczyna operację przeciągania. Parametry obejmują uchwyt do listy obrazów, indeks obrazu do przeciągania i lokalizację punktu gorącego na obrazie. Punkt gorąca to pojedynczy piksel, który funkcje przeciągania rozpoznają jako dokładną lokalizację ekranu obrazu. Zazwyczaj aplikacja ustawia punkt gorąca, tak aby pokrywała się z gorącym punktem kursora myszy. Funkcja ImageList_DragMove przenosi obraz do nowej lokalizacji.

Funkcja ImageList_DragEnter ustawia początkową pozycję obrazu do przeciągania w oknie i rysuje obraz w tej lokalizacji. Parametry obejmują uchwyt do okna, w którym ma być rysowany obraz, oraz współrzędne pozycji początkowej w oknie. Współrzędne są określone w stosunku do lewego górnego rogu okna, a nie obszaru roboczego. To samo dotyczy wszystkich funkcji przeciągania obrazu, które przyjmują współrzędne jako parametry. Oznacza to, że podczas określania współrzędnych należy zrekompensować szerokość elementów okna, takich jak obramowanie, pasek tytułu i pasek menu. W przypadku określenia uchwytu NULL podczas wywoływania funkcji ImageList_DragEnter, funkcje przeciągania rysują obraz w kontekście urządzenia skojarzonego z oknem pulpitu, a współrzędne odnoszą się do lewego górnego rogu ekranu.

Funkcja ImageList_SetDragCursorImage tworzy nowy obraz przeciągania, łącząc dany obraz (zazwyczaj obraz kursora myszy) z bieżącym obrazem przeciągania. Ponieważ funkcje przeciągania używają nowego obrazu podczas operacji przeciągania, należy użyć funkcji ShowCursor, aby ukryć rzeczywisty kursor myszy po wywołaniu ImageList_SetDragCursorImage. W przeciwnym razie system może wydawać się mieć dwa kursory myszy na czas trwania operacji przeciągania.

Gdy aplikacja wywołuje ImageList_BeginDrag, system tworzy tymczasową, wewnętrzną listę obrazków, a następnie kopiuje wskazany obraz do przeciągania do listy wewnętrznej. Uchwyt można pobrać do tymczasowej listy obrazów przeciągania przy użyciu funkcji ImageList_GetDragImage. Funkcja pobiera również aktualną pozycję przeciągania oraz przesunięcie obrazu przeciągania względem tej pozycji.

Informacje o obrazie

Istnieje wiele funkcji, które pobierają informacje z listy obrazów. Funkcja ImageList_GetImageInfo wypełnia strukturę IMAGEINFO zawierającą informacje o pojedynczym obrazie, w tym uchwyty obrazów i maski map bitowych, liczbę płaszczyzn kolorów i bitów na piksel oraz prostokąt ograniczenia obrazu w obrębie mapy bitowej obrazu. Te informacje umożliwiają bezpośrednie manipulowanie mapami bitowymi obrazu. Funkcja ImageList_GetImageCount pobiera liczbę obrazów na liście obrazów.

Nakładki na obrazy

Każda lista obrazów zawiera listę indeksów do użycia jako nakładki. Nakładka to obraz, który jest rysowany przezroczysto na innym obrazie. Dowolny obraz znajdujący się obecnie na liście obrazów może być używany jako nakładka. Można określić maksymalnie cztery nakładki na listę obrazów. Ten limit został rozszerzony do 15 w wersji 4.71.

Indeks obrazu można dodać do listy nakładek przy użyciu funkcji ImageList_SetOverlayImage, określając uchwyt do listy obrazów, indeks istniejącego obrazu i żądany indeks nakładki. W efekcie informuje listę obrazów, że "obraz przy indeksie x może być używany jako nakładka i chcę odwołać się do nakładki jako indeks nakładki y." Indeksy nakładki są jednokrotne zamiast zerokrotne, ponieważ indeks nakładki zero oznacza, że nie zostanie użyta żadna nakładka.

Podczas rysowania obrazu za pomocą funkcji ImageList_Draw lub ImageList_DrawEx należy określić nakładkę. Nakładka jest określana przez wykonanie operacji logicznej LUB między żądanymi flagami rysunku a wynikiem makra INDEXTOOVERLAYMASK. Makro INDEXTOOVERLAYMASK pobiera indeks nakładki i formatuje go do używania z flagami dla tych funkcji. Spowoduje to narysowanie obrazu z określoną nakładką. W poniższym przykładzie pokazano, jak nakładka dodaje się oraz określa podczas rysowania obrazu.

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

Spowoduje to narysowanie obrazu 1, a następnie nakładanie tego obrazu z obrazem 0. Ponieważ 3 to indeks nakładki określony w wywołaniu ImageList_SetOverlayImage, 3 znajduje się w makrze INDEXTOOVERLAYMASK.

32-bitowe ikony antyaliasedowe

Antialiasing to technika zmiękczania lub rozmycia ostrych krawędzi. Daje to bardziej naturalny wygląd obrazów. Listy obrazów w systemach Windows Vista i Windows 7 obsługują używanie 32-bitowych ikon i map bitowych z wygładzaniem krawędzi. Wartości kolorów używają 24 bitów, a 8 bitów są używane jako kanał alfa na ikonach. Aby utworzyć listę obrazów, która może obsłużyć obraz 32 bitów na piksel (bpp), wywołaj funkcję ImageList_Create, przekazując flagę ILC_COLOR32.

Aby poprawnie utworzyć ikony 32-bitowe, musisz utworzyć wiele obrazów dla każdej ikony, jak pokazano na poniższej ilustracji.

ilustracja przedstawiająca trzy rozmiary ikon dla każdej z trzech głębokości kolorów

  • Pierwsze trzy obrazy są w trybie 16 kolorów do użycia w trybie awaryjnym.
  • Następne trzy ikony są używane w trybie 256 kolorów.
  • Ostatnie trzy ikony mają kanał alfa i mogą być używane tylko w systemach operacyjnych z kolorem 24-bitowym lub wyższym.
  • Kolejność obrazów w formacie ikony ma znaczenie. Jeśli kolejność jest nieprawidłowa, starsze wersje systemu Windows działają nieprawidłowo podczas wyodrębniania ikon. Niepoprawne wyodrębnianie ikon może spowodować uszkodzenie pamięci i nieprawidłowe renderowanie.
  • Poprzednie wersje systemu Windows miały limit zasobów z 10 ikonami.

Notatka

Narzędzia innych firm umożliwiają generowanie plików ikon i map bitowych zawierających kanał alfa. Jeśli używasz LoadImage do załadowania mapy bitowej 32 bpp zawierającej alfa, musisz określić flagę LR_CREATEDIBSECTION.