Lazarus

Programming => LCL => Topic started by: Milsa on September 11, 2017, 07:13:25 pm

Title: How to add transparent icon to ListView?
Post by: Milsa on September 11, 2017, 07:13:25 pm
I am kill all afternoon by finding way to add trasparent icon to ListView. This is my result (1.png). Any is transparent, any not.

Can you help me?

My code is as this:
Code: Pascal  [Select][+][-]
  1.         with ListView.Items.Add do
  2.         begin
  3.           Caption := FieldByName('name').AsString;
  4.           Tag := FieldByName('id').AsInteger;
  5.  
  6.           StrCopy(@Buffer, PChar(FieldByName('path').AsString));
  7.           IconIndex := 0;
  8.           IconHandle := ExtractAssociatedIcon(HInstance, Buffer, @IconIndex);
  9.           if IconHandle <> 0 then
  10.             FileIcon.Handle := IconHandle;
  11.           BGRAImageList.Width := FileIcon.Width;
  12.           BGRAImageList.Height := FileIcon.Height;
  13.           ImageIndex := BGRAImageList.AddIcon(FileIcon);
  14.         end;  
  15.  
First try was without BGRA components. This is actual try. Result is the same with or without BGRA components.

How Lazarus does work with icons?

I won't use packages from third party. Lazarus don't use third party components too.
Title: Re: How to add transparent icon to ListView?
Post by: taazz on September 11, 2017, 07:55:57 pm
I think that the ones with the black background are resized. Try to
1) make sure all icons have the extact same size.
2) add smaller icons centered not resized.
Title: Re: How to add transparent icon to ListView?
Post by: wp on September 11, 2017, 08:07:01 pm
Setting up transparent icons is sometimes a pain when I use bmp files, but never had problems with transparent png and with ico. Just use a standard TImageList, set the With/Height according to the size of the images (yes, they all must be the same size) and add them. In the Listview, just assign the ImageIndex to be used, no fancy code with "ExtractIcon", Handles etc.

Just look at the attached demo
Title: Re: How to add transparent icon to ListView?
Post by: Milsa on September 11, 2017, 08:17:11 pm
I think that the ones with the black background are resized. Try to
1) make sure all icons have the extact same size.
2) add smaller icons centered not resized.
They are icons from EXE files without resizing.
Title: Re: How to add transparent icon to ListView?
Post by: Milsa on September 11, 2017, 08:30:24 pm
Setting up transparent icons is sometimes a pain when I use bmp files, but never had problems with transparent png and with ico. Just use a standard TImageList, set the With/Height according to the size of the images (yes, they all must be the same size) and add them. In the Listview, just assign the ImageIndex to be used, no fancy code with "ExtractIcon", Handles etc.

Just look at the attached demo
But my code is realtime grabbing icons from EXE files.
Title: Re: How to add transparent icon to ListView?
Post by: ASerge on September 11, 2017, 09:49:12 pm
But my code is realtime grabbing icons from EXE files.
Simple project. Put the ListView, ImageList, Button. Set ListView.SmallImages = ImageList and code below.
Code: Pascal  [Select][+][-]
  1. implementation
  2.  
  3. uses Windows, CommCtrl, WinDirs, ShellApi;
  4.  
  5. {$R *.lfm}
  6.  
  7. function GetShellIcon(const FileName: UnicodeString): HICON;
  8. const
  9.   CFlagGetIcon = SHGFI_ICON or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES;
  10. var
  11.   R: TSHFileInfoW;
  12. begin
  13.   Result := 0;
  14.   if ExtractIconExW(Pointer(FileName), 0, HICON(nil^), Result, 1) <> 1 then
  15.   begin
  16.     if SHGetFileInfoW(Pointer(FileName), 0, @R, SizeOf(R), CFlagGetIcon) <> 0 then
  17.       Result := R.hIcon;
  18.   end;
  19. end;
  20.  
  21. procedure TForm1.Button1Click(Sender: TObject);
  22. var
  23.   DesktopPath: UnicodeString;
  24.   R: TUnicodeSearchRec;
  25.   Item: TListItem;
  26.   FileIcon: HICON;
  27. begin
  28.   DesktopPath := GetWindowsSpecialDirUnicode(CSIDL_DESKTOPDIRECTORY, False);
  29.   if FindFirst(DesktopPath + '*', faNormal, R) = 0 then
  30.   try
  31.     repeat
  32.       Item := ListView1.Items.Add;
  33.       Item.Caption := UTF8Encode(R.Name);
  34.       FileIcon := GetShellIcon(DesktopPath + R.Name);
  35.       if FileIcon <> 0 then
  36.         Item.ImageIndex := ImageList_AddIcon(ImageList1.{%H-}Handle, FileIcon);
  37.     until FindNext(R) <> 0;
  38.   finally
  39.     SysUtils.FindClose(R);
  40.   end;
  41. end;
  42.  
  43. end.

It looks transparent on my machine.
Title: Re: How to add transparent icon to ListView?
Post by: Milsa on September 12, 2017, 08:05:13 pm
Thank you very much!!! I want this.
Title: Re: How to add transparent icon to ListView?
Post by: wp on September 12, 2017, 10:23:15 pm
The key to this solution seems to be using the API function ImageList_AddIcon(...). Going the way via an intermediate icon (ico := TIcon.Create; ico.Handle := GetShellIcon(...); Item.ImageIndex := ImageList1.AddIcon(ico)) results in the incorrectly painted background seen in the first post for some icons (they seem to be 32-bit icons with alpha channel, such as the icon of Virtualbox.exe).
TinyPortal © 2005-2018