Delphi and 48x48 (or larger) imagelists - is there a workaround?

I get an imagelist system (with SHGetFileInfo and SHGFI_LARGEICON) by adding two of my own icons and attaching them to a TListView.

The problem is that if the size of the user's icon is not set to 32x32 (for example, it is set to 48x48), Delphi7 TImageList will fail with the error "Invalid image size."

Does anyone know if a workaround is available? I tried to use TPngImageList, but this leads to other problems.

Also note that I would like to keep the alpha channel of the icons. Normal 1-bit transparency is not enough, as icons tend to look ugly.

Thanks!

+4
source share
3 answers

Just when I was about to abandon this page, I came up with a solution: http://delphihaven.wordpress.com/2010/09/06/custom-drawing-on-glass-2/

Apparently, if you try to add an icon larger than 32x32 to timagelist in Delphi7, VCL will give you an "Invalid image size" error, while it can just call himagelist's API, which can easily handle this.

Here is the complete solution:

unit ImageListFix; interface uses CommCtrl, Graphics, ImgList; type TImageListFixer = class(TCustomImageList) public function AddIcon(Image: TIcon): Integer; end; implementation function TImageListFixer.AddIcon(Image: TIcon): Integer; begin if Image = nil then Result := Add(nil, nil) else begin Result := ImageList_AddIcon(Handle, Image.Handle); Change; end; end; end. 

And the code for adding icons to the imagelist system:

 DocumentImgList:=TImageListFixer(GetSystemLargeIconsList); IconToAdd:=TIcon.Create; try IconToAdd.Handle := LoadImage(0, 'c:\Ico1.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE); DocumentImgList.AddIcon(IconToAdd); IconToAdd.Handle := LoadImage(0, 'c:\Ico2.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE); DocumentImgList.AddIcon(IconToAdd); finally IconToAdd.Free; end; 
+3
source

I do not know any restrictions on the size of the images that a TImageList can hold. It seems to me that your problem is that you have icons of different sizes, and you cannot keep icons of different sizes in the same list of images.

If you work with icons of different sizes, you will need to grow smaller ones. You will need to create it in code using a bitmap. You fill the bitmap with a clear, transparent alpha channel, and then add a smaller icon to the center of the bitmap.

Another option would be to maintain two separate image lists, but if you need to draw icons in the same list view, I think this will not be done. I assume that you will need to grow small icons.

For alpha, you will need to create an image list descriptor yourself, because the ColorDepth property does not exist in D7. Because of this, the D7 vanilla TImageList simply cannot support alpha badges.

You bypass this limitation by calling ImageList_Create , passing ILC_COLOR32 and assigning the result to ImageList.Handle . Do this before adding any images. You will need to populate the list at runtime, not development time, but it looks like you are already doing this.

Here is a screenshot of a 48x48 tool button with a 32-bit alpha transparency icon:

48px icon from image list

It is true that I did this in D2010, but my workaround would work for D7 - I used this mechanism until recently with D6. I just show this to prove that there may be 48px icons in the image list. Since the TImageList is just a wrapper around the component of the list of system images, I believe that what you are trying should be perfectly feasible.

+5
source

TImageList throws an "Invalid Image Size" error under only two conditions:

1) The Height or Width property of TImageList is less than 1, or the Height property is greater than 32768 when the TImageList is initially created using the CreateSize () constructor (such restrictions imposed by the Height and Width setters property).

2) you are trying to add / insert a new TBitmap or TIcon, the sizes of which do not match the internal image of the TImageList.

+1
source

Source: https://habr.com/ru/post/1337521/


All Articles