lurker
lurker

Reputation: 58224

Windows Small System Icon Height Incorrect

I'm running on Windows 10, but using Delphi 7 (yes, I know it's quite old).

I want to use the system icons in Windows and have gone about this by defining a TImageList called SystemIcons which I initialize as follows:

var
  fileInfo: TSHFileInfo;

begin
  SystemIcons.Handle := ShGetFileInfo('', 0, fileInfo, SizeOf(fileInfo),
    SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX);

...

I have SystemIcons properties set statically as a TImageList component with width and height set to 16.

Elsewhere, I wish to retrieve an icon from this image list given a valid shell object's image index. Because these are "small system icons", I expect them to be 16x16. The result of calling GetSystemMetrics(SM_CYSMICON) yields 16. Oddly, the dimensions depend upon whether I retrieve them as a bitmap or an icon.

...
var
  icon: TIcon;
  bm: TBitmap;

begin
  ...
  icon := TIcon.Create;
  SystemIcons.GetIcon(imgIndex, icon);

  bm := TBitmap.Create;
  SystemIcons.GetBitmap(imgIndex, bm);

The imgIndex is correct and the same in both cases. The image retrieved is the same in each case, as expected. The dimensions of the bitmap (bm.Width and bm.Height) are also as expected: 16x16. However, the dimensions of the icon (icon.Width and icon.Height) are not. They are 32x32.

When I paint the icon on a canvas it appears as 16x16. So it's only its Height and Width values that appear incorrect. Very odd.

Why are these different?

Upvotes: 0

Views: 121

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595295

The images are likely actually 32x32 to begin with.

Internally, TImageList.GetIcon() simply retrieves an HICON for the chosen image directly from the underlying Win32 ImageList API, using ImageList_GetIcon(), and assigns that to the TIcon.Handle property.

TImageList.GetBitmap(), on the other hand, is a bit different. It sizes the TBitmap to the dimensions of the TImageList (16x16), and then stretch draws the chosen image onto the TBitmap.Canvas using TImageList.Draw(), which in turn uses ImageList_DrawEx().

Upvotes: 1

Related Questions