Recent

Author Topic: How to add transparent icon to ListView?  (Read 5670 times)

Milsa

  • Sr. Member
  • ****
  • Posts: 309
How to add transparent icon to ListView?
« 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.
I work with Lazarus 2.2.2, FPC 3.2.2, date 2022-05-15
This information is actual to: 28st Dec 2022

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: How to add transparent icon to ListView?
« Reply #1 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.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: How to add transparent icon to ListView?
« Reply #2 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

Milsa

  • Sr. Member
  • ****
  • Posts: 309
Re: How to add transparent icon to ListView?
« Reply #3 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.
I work with Lazarus 2.2.2, FPC 3.2.2, date 2022-05-15
This information is actual to: 28st Dec 2022

Milsa

  • Sr. Member
  • ****
  • Posts: 309
Re: How to add transparent icon to ListView?
« Reply #4 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.
I work with Lazarus 2.2.2, FPC 3.2.2, date 2022-05-15
This information is actual to: 28st Dec 2022

ASerge

  • Hero Member
  • *****
  • Posts: 2212
Re: How to add transparent icon to ListView?
« Reply #5 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.

Milsa

  • Sr. Member
  • ****
  • Posts: 309
Re: How to add transparent icon to ListView?
« Reply #6 on: September 12, 2017, 08:05:13 pm »
Thank you very much!!! I want this.
I work with Lazarus 2.2.2, FPC 3.2.2, date 2022-05-15
This information is actual to: 28st Dec 2022

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: How to add transparent icon to ListView?
« Reply #7 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