Forum > LCL

How to implement a Virtual ImageList for TListView? [SOLVED]

(1/2) > >>

fournoas:
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?

fournoas:
Mybe the Virtual ImageList is a bad idea.

I implemented the desired functionality using CustomDrawItem.

vfclists:
Will you show us what the code looks like?

fournoas:

--- Quote from: vfclists on August 30, 2024, 11:53:39 pm ---Will you show us what the code looks like?

--- End quote ---

my pleasure

1. Set ListView1.OnCustomDrawItem event handle

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TMainForm.ListViewCustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);begin  if State = [] then Exit;  case ListView.ViewStyle of    vsIcon: LoadLargeIcon(Sender, Item);    vsSmallIcon: LoadSmallIcon(Sender, Item);    vsReport: LoadSmallIcon(Sender, Item);  end;end; 
2. Draw picture

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure LoadSmallIcon(ListView: TCustomListView; Item: TListItem);var  IconRect: TRect;  Picture: TPicture;begin  IconRect := Item.DisplayRect(drIcon);  Picture := TPicture.Create;  Picture.LoadFromFile('D:\small.jpg');  ListView.Canvas.Draw(IconRect.Left, IconRect.Top, FilterPicture(Picture, Item.Selected, ListView.Focused).Graphic);  Picture.Free;end; procedure LoadLargeIcon(ListView: TCustomListView; Item: TListItem);var  IconRect: TRect;  Picture: TPicture;begin  IconRect := Item.DisplayRect(drIcon);  Picture := TPicture.Create;  Picture.LoadFromFile('D:\large.jpg');  ListView.Canvas.Draw(    IconRect.Left + (IconRect.Width - Picture.Width) div 2,    IconRect.Top + (IconRect.Height - Picture.Height),    FilterPicture(Picture, Item.Selected, ListView.Focused).Graphic);  Picture.Free;end; 
3. Processing image highlight effects

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function FilterPicture(Picture: TPicture; Selected, Focused: boolean): TPicture;var  PixelColor: TColor;  X, Y: Integer;begin  Result := Picture;  if not Selected then Exit;  for X := 0 to Picture.Width - 1 do  begin    for Y := 0 to Picture.Height - 1 do    begin      PixelColor := Picture.Bitmap.Canvas.Pixels[X, Y];      Picture.Bitmap.Canvas.Pixels[X, Y] :=        specialize IfThen<TColor>(Focused, DecColor(PixelColor, $30), IncColor(PixelColor, $30));    end;  end;end; 
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

wp:
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?

Navigation

[0] Message Index

[#] Next page

Go to full version