* * *

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

Milsa

  • Full Member
  • ***
  • Posts: 165
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.

taazz

  • Hero Member
  • *****
  • Posts: 4402
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: 3889
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
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Milsa

  • Full Member
  • ***
  • Posts: 165
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.

Milsa

  • Full Member
  • ***
  • Posts: 165
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.

ASerge

  • Sr. Member
  • ****
  • Posts: 452
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

  • Full Member
  • ***
  • Posts: 165
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.

wp

  • Hero Member
  • *****
  • Posts: 3889
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).
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus