What you see is not related to broken alpha transparency, but to the artifact of resizing.
As documented , the default size of the LoadImage icon LoadImage loaded by SM_CXICON x SM_CYICON , which is usually 32x32. Since you are requesting an icon that is used by the system, this will be the size of the icon to be specified.
You can check if this matches your code:
.. try icon.Handle := LoadImage( 0, IDI_INFORMATION, IMAGE_ICON, 16, 16, {LR_DEFAULTSIZE or} LR_SHARED ); Assert(icon.Width = GetSystemMetrics(SM_CXICON)); Assert(GetSystemMetrics(SM_CXICON) <> 16); ..
It follows that the icon changes to fit the list of images, probably nothing better than StretchBlt with COLORONCOLOR mode.
Unfortunately, it is not possible to load a system icon with a custom size, because, as documented again,
When loading a system icon or cursor, you must use LR_SHARED or the function cannot load the resource.
What you need to do is load the generic icon with its default size and then change it to 16x16 using the best algorithm. StretchBlt with HALFTONE will probably be better, but using a more advanced graphics library can give the best results.
A fail-safe alternative is to load the resource directly from where it is located. If you do not use the LR_SHARED flag, you will be provided with the required size. You need to do some research to find the actual icon index, as this is not documented. And keep in mind that the index or its life may change over time. Do not forget to destroy the icon yourself in this case, since the system will not do this for a non-shared resource.
icon.Handle := LoadImage(GetModuleHandle(user32), Pointer(104), IMAGE_ICON, 16, 16, 0);