Forum > LCL
How to implement a Virtual ImageList for TListView? [SOLVED]
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