Short answer. After you call:
iconindex:=ImageList.AddIcon(myicon);
call:
iconindex := ImageList_ReplaceIcon(ImageList.Handle, iconindex, myicon.Handle);
to replace the bad image. ImageList_ReplaceIcon is declared in Windows unit. You need to add it to your uses section if you don't have it there already.
Long (boring) answer. These icons are drawn by DrawToDC in
lcl\interfaces\win32\win32wsimglist.pp. The procedure uses one of three different drawing methods based on color depth, drawing effect and Comctl version.
Using Windows, it is possible to borrow the OS ImageList handle and get the index to the same icon in that list. To achieve that, SHGFI_SYSICONINDEX needs to be passed in the flags when calling SHGetFileInfo:
var
SysHandle: THandle;
..
SysHandle := SHGetFileInfo(PChar(folder), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX);
Comparing the results of drawing two icons, one based on borrowing the OS' ImageList and the other icon based on TImageList, the results were not identical. I used the first method ImageList_DrawEx:
ImageList_DrawEx(SysHandle, FileInfo.iIcon, Canvas.Handle, 10,10, 0,0, CLR_NONE, CLR_NONE, ILD_NORMAL or ILD_NORMAL);
ImageList_DrawEx(ImageList.Handle, iconindex, Canvas.Handle, 50,10, 0,0, CLR_NONE, CLR_NONE, ILD_NORMAL or ILD_NORMAL);
First I suspected TIcon, but it did draw the image correctly. So I assume ImageList.
AddIcon is causing this problem. Simply replacing the icon (or whatever AddIcon is adding?) solved the problem on my PC. Notice that I did not see the problem using color depth setting less then 32 bit and this workaround is just for Windows OS. I don't know if the problem exists on other systems.