delphiscaletimagelist

How to draw a scaled version of images from the system ImageList?


I create and initialize the TImageList...

ImageList:=TImageList.Create(self);
ImageList.ShareImages:=true;

I get the system ImageList handle for small icons (16x16)...

ImageList.Handle:=SHGetFileInfo('',0,FileInfo,SizeOf(FileInfo),SHGFI_SYSICONINDEX or SHGFI_SMALLICON);

And now I want to draw the icons on my control canvas scaled to 50x50 pixels. How I do this ?


Solution

  • Upscaling small icons is never good idea. 16X16 icon is too small to use it in any other way other as-is.

    For start you can get larger shell images using

    ImageList.Handle:=SHGetFileInfo('',0,FileInfo,SizeOf(FileInfo),SHGFI_SYSICONINDEX or SHGFI_ICON);
    

    Those images will be generally 32x32 pix, but to be on safe side (if Windows are running in high DPI mode) you can get correct size from system

    uses
      Winapi.Windows;
    
    var
      IconWidth, IconHeight: integer;
    
      IconWidth := GetSystemMetrics(SM_CXICON);
      IconHeight := GetSystemMetrics(SM_CYICON);
    

    You can also get even larger shell images with SHGetImageList http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185%28v=vs.85%29.aspx

    To retrieve icon from you ImageList (if ImageList contains icons, and in your case it does) you can use:

    ImageList.GetIcon(Index: Integer; Image: TIcon);
    

    For scaling icons, while preserving transparency, to custom dimension you can use following code:

    procedure StretchDrawIcon(Canvas: TCanvas; Dest: TRect; Icon: TIcon);
    begin
      DrawIconEx(Canvas.Handle, Dest.Left, Dest.Top, Icon.Handle, Dest.Right - Dest.Left, Dest.Bottom - Dest.Top, 0, 0, DI_NORMAL);
    end;