32-bitowe ikony w Delphi
O ile nowsze edycje środowiska RAD jakim jest Delphi, posiadają pełne wsparcie dla 32-bitowych ikon czy nawet plików PNG, o tyle w starszych edycjach ich użycie jest mocno ograniczone.
Jedyną opcją wykorzystania ikony z kanałem alpha jest wstawienie komponentu TImage i załadowanie do niego pliku ikony. Co jeśli chcemy użyć przeźroczystego obrazka w menu, pasku narzędzi czy zakładce? Tutaj jedynym komponentem który nam to umożliwia jest TImageList, który niestety gubi informacje o kolorach powyżej 24 bitów.
W tym wpisie pokaże jak sobie z tym poradzić i mimo to użyć ładnych plików ikon w naszych aplikacjach.
Rozwiązanie z racji stosowania pewnego tricku ma pewną wadę. Wszystkie zasoby do TImageList musimy ładować w trakcie działania aplikacji a nie na etapie projektowania – innymi słowy, musimy osobno do pliku wykonywalnego dołączać pliki ikon których użyjemy.
Drugą niewygodą, która jest następstwem pierwszej, jest fakt że przypisując konkretnemu elementowi ImageIndex musimy wpisać go nie widząc załadowanej ikony – wymusza to nas nas ładowanie ikon zawsze w tej samej kolejności i trzymania pozycji danego obrazka zawsze pod tym samym numerkiem.
Są to pewne wady który uprzykrzają proces pisania programu, ale jak to mówią, coś za coś.
Przejdźmy zatem do czynów. Mając umieszczony na formie TImageList musimy go dostosować do przyjmowania 32-bitowych ikon. Skorzystajmy z tej oto procedury:
procedure ConvertTo32BitImageList(ImageList: TImageList);
const
MASK: array[Boolean] of Longint = (0, ILC_MASK);
var
templist: TImageList;
begin
if Assigned(ImageList) then
begin
templist := TImageList.Create(nil);
try
templist.Assign(ImageList);
with ImageList do
begin
Handle := ImageList_Create(Width, Height, ILC_COLOR32 or MASK[Masked], 0, AllocBy);
if not HandleAllocated then
raise EInvalidOperation.Create(SInvalidImageList);
end;
Imagelist.AddImages(templist);
finally
FreeAndNil(templist);
end;
end;
end;
Po skonwertowaniu listy obrazów (pustej), możemy zacząć dodawać nasze zasoby. Dla ułatwienia możemy skorzystać z tej procedury:
procedure AddIconTo32BitImageList(ImageList: TImageList; const FileName: String); var icon: TIcon; stream: TFileStream; begin icon := TIcon.Create; stream := TFileStream.Create(FileName, fmOpenRead); icon.LoadFromStream(stream); ImageList.AddIcon(icon); icon.Free; stream.Free; end;
Jak widać, powyższa procedura przyjmuje 2 parametry, komponent TImageList oraz ścieżkę do ikony którą chcemy dodać. Należy pamiętać o tym aby skonfigurować odpowiednio listę obrazów do naszych potrzeb – ustawić wymiar ikon.
Przykładowe użycie powyższej metody:
procedure TForm1.FormCreate(Sender: TObject); begin ImageList1.Clear; ConvertTo32BitImageList(ImageList1); AddIconTo32BitImageList(ImageList1, 'data\open.ico'); AddIconTo32BitImageList(ImageList1, 'data\save.ico'); AddIconTo32BitImageList(ImageList1, 'data\exit.ico'); end;
Czy owa procedura działa pod Vistą i Win7 ?
Tak.