Recent

Author Topic: How to implement a Virtual ImageList for TListView? [SOLVED]  (Read 1547 times)

fournoas

  • New member
  • *
  • Posts: 9
How to implement a Virtual ImageList for TListView? [SOLVED]
« on: August 26, 2024, 09:27:54 am »
I need to display a large number of images in the ListView. I cannot load all these images into the ImageList at once, as it would consume too much memory.

I attempted to implement a virtual ImageList, only to find that the methods of TCustomImageList are non-virtual and cannot be modified to alter its default behavior.

Is there any way to dynamically load images in a ListView?
« Last Edit: August 26, 2024, 10:43:08 am by fournoas »

fournoas

  • New member
  • *
  • Posts: 9
Re: How to implement a Virtual ImageList for TListView?
« Reply #1 on: August 26, 2024, 10:42:13 am »
Mybe the Virtual ImageList is a bad idea.

I implemented the desired functionality using CustomDrawItem.

vfclists

  • Hero Member
  • *****
  • Posts: 1119
    • HowTos Considered Harmful?
Re: How to implement a Virtual ImageList for TListView? [SOLVED]
« Reply #2 on: August 30, 2024, 11:53:39 pm »
Will you show us what the code looks like?
Lazarus 3.0/FPC 3.2.2

fournoas

  • New member
  • *
  • Posts: 9
Re: How to implement a Virtual ImageList for TListView? [SOLVED]
« Reply #3 on: September 04, 2024, 04:16:45 am »
Will you show us what the code looks like?

my pleasure

1. Set ListView1.OnCustomDrawItem event handle
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.ListViewCustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
  2. begin
  3.   if State = [] then Exit;
  4.   case ListView.ViewStyle of
  5.     vsIcon: LoadLargeIcon(Sender, Item);
  6.     vsSmallIcon: LoadSmallIcon(Sender, Item);
  7.     vsReport: LoadSmallIcon(Sender, Item);
  8.   end;
  9. end;
  10.  

2. Draw picture
Code: Pascal  [Select][+][-]
  1. procedure LoadSmallIcon(ListView: TCustomListView; Item: TListItem);
  2. var
  3.   IconRect: TRect;
  4.   Picture: TPicture;
  5. begin
  6.   IconRect := Item.DisplayRect(drIcon);
  7.   Picture := TPicture.Create;
  8.   Picture.LoadFromFile('D:\small.jpg');
  9.   ListView.Canvas.Draw(IconRect.Left, IconRect.Top, FilterPicture(Picture, Item.Selected, ListView.Focused).Graphic);
  10.   Picture.Free;
  11. end;
  12.  
  13. procedure LoadLargeIcon(ListView: TCustomListView; Item: TListItem);
  14. var
  15.   IconRect: TRect;
  16.   Picture: TPicture;
  17. begin
  18.   IconRect := Item.DisplayRect(drIcon);
  19.   Picture := TPicture.Create;
  20.   Picture.LoadFromFile('D:\large.jpg');
  21.   ListView.Canvas.Draw(
  22.     IconRect.Left + (IconRect.Width - Picture.Width) div 2,
  23.     IconRect.Top + (IconRect.Height - Picture.Height),
  24.     FilterPicture(Picture, Item.Selected, ListView.Focused).Graphic);
  25.   Picture.Free;
  26. end;
  27.  

3. Processing image highlight effects
Code: Pascal  [Select][+][-]
  1. function FilterPicture(Picture: TPicture; Selected, Focused: boolean): TPicture;
  2. var
  3.   PixelColor: TColor;
  4.   X, Y: Integer;
  5. begin
  6.   Result := Picture;
  7.   if not Selected then Exit;
  8.   for X := 0 to Picture.Width - 1 do
  9.   begin
  10.     for Y := 0 to Picture.Height - 1 do
  11.     begin
  12.       PixelColor := Picture.Bitmap.Canvas.Pixels[X, Y];
  13.       Picture.Bitmap.Canvas.Pixels[X, Y] :=
  14.         specialize IfThen<TColor>(Focused, DecColor(PixelColor, $30), IncColor(PixelColor, $30));
  15.     end;
  16.   end;
  17. end;
  18.  

It should be noted that the code has the following issues:
1. The picture is not scaled
2. The image highlight effect does not look very good
3. Tested only on Windows
« Last Edit: September 04, 2024, 04:24:50 am by fournoas »

wp

  • Hero Member
  • *****
  • Posts: 12368
Re: How to implement a Virtual ImageList for TListView? [SOLVED]
« Reply #4 on: September 04, 2024, 06:42:11 pm »
Is there also text in these items? Not 100% sure, but don't you have to output this, too? Or, since DefaultDraw should be true, doesn't the ListView itself draw the text, but overwrites the icon because it does not know about it?

fournoas

  • New member
  • *
  • Posts: 9
Re: How to implement a Virtual ImageList for TListView? [SOLVED]
« Reply #5 on: September 05, 2024, 03:25:40 am »
Is there also text in these items? Not 100% sure, but don't you have to output this, too? Or, since DefaultDraw should be true, doesn't the ListView itself draw the text, but overwrites the icon because it does not know about it?

ListView.OwnDraw := False;

ListView will render text and draw icons.

 

TinyPortal © 2005-2018