Boontawee Home
Boontawee Home

Reputation: 1033

Howto load 48x48 .ico at runtime into imagelist and preserv transparency

I prefer 48x48 .ico to show in popupmenu.

If BkColor set to clNone, the icon look ugly. ImageList_GetIcon also get some ugly edge too.

enter image description here

If BkColor set to ClMenu, the icon pretty but when highlight the icon have gray background.

enter image description here

ImageList_LoadImage work only for .bmp so can't use.

ImageList1.BkColor := clMenu;
if FileExists(filename) then
begin
    //h := ImageList_LoadImage(0, PChar(filename), 48, 48, CLR_NONE, IMAGE_ICON, LR_LOADFROMFILE);
    h := LoadImage(0, PChar(filename), IMAGE_ICON, 48, 48, LR_LOADFROMFILE);
end
else
begin
    h := ImageList_GetIcon(ImageList1.Handle, 0, ILD_NORMAL);
end;
ImageList_AddIcon(ImageList1.Handle, h);
DeleteObject(h);

Upvotes: 2

Views: 1753

Answers (1)

Boontawee Home
Boontawee Home

Reputation: 1033

I found some info now.

A) To use bigger icon than 32x32, we have to use LoadImage function.

B) To avoid ugly black edge, use 32bit ImageList by use ImageList_Create function at runtime.

C) To avoid ugly white edge, use LoadIcon function from resoures instead of designtime ImageList.

procedure TForm1.LoadICO;
var
   i: Integer;
   h: HIcon;
   folder: string;
   filename: string;
begin
   folder := GetCurrentDir + '\icon\';

   {To support alpha transparency, you need to create the ImageList and populate it at runtime}
   ImageList1.Handle := ImageList_Create(48, 48, ILC_COLOR32 or ILC_MASK, 0, ImageList1.AllocBy);

   /////////////////////////////////////////////////////////////

   filename := folder + ParamStr(i);

   if FileExists(filename) then
   begin
            //h := ImageList_LoadImage(0, PChar(filename), 48, 48, CLR_NONE, IMAGE_ICON, LR_LOADFROMFILE);   
            {ImageList_LoadImage function work only IMAGE_BITMAP}
            h := LoadImage(0, PChar(filename), IMAGE_ICON, 48, 48, LR_LOADFROMFILE);                       
            {LoadImage function work with icon bigger than 32x32}
   end
   else
   begin
            //h := ImageList_GetIcon(ImageList3.Handle, 1, ILD_NORMAL);                                    
            {Ugly when get icon from designtime ImageList}
            h := LoadIcon(hInstance, 'ICO1');                                                              
            {Pretty when load icon from resources}
   end;

   /////////////////////////////////////////////////////////////

   ImageList_AddIcon(ImageList1.Handle, h);
   DeleteObject(h);
end; 

D) To avoid ugly black edge, also use comctl32.dll v6 to enable visualstyle smooth edge. Create xxx.exe.manifest file with content below

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
</assembly>

E) Assign command make ugly white edge too. Use For loop and ImageList_ReplaceIcon function is better.

//ImageList3.Assign(ImageList1);  {Assign command make ugly white edge}
h := ImageList_GetIcon(ImageList1.Handle, i, ILD_NORMAL);
ImageList_ReplaceIcon(ImageList3.Handle, i, h);
DeleteObject(h);

Upvotes: 4

Related Questions