In the interest of full disclosure: I ran into a similar problem and used this Q&A to base my initial solution on. Since I needed a quick fix for my app and compiler (I use C++ Builder 2009) I decided to 'hack' the VCL's private members and set Glyphlist
's ColorDepth
to cd32Bit
, until I had time to work on something more permanent. This hack worked, with a few more changes, but was far from ideal, for all the obvious reasons, but also functionality wise, there were issues to consider.
However, while doing so I experimented further and finally arrived at below, working solution, without any dirty tricks needed. Not being that familiar with the internal workings of VCL and the rather 'it's not possible as is' feedback from people who are far more in depth in VCL I'm a bit unsure on what I'm missing right now !? Because below solution works for me. Confirmed on XP, XP-High-contrast, W7 and W10. The Glyphs don't look good on W2K but then that is true for Main Menu and Popup icons as well, so that is that.
I code in C++ but use the same underlying VCL, so I will post my C++ solution here, as answer to a Delphi question. I hope that is OK, in the interest of offering a path to a solution rather than keeping it to myself. A Delphi guru can convert and post as answer as well then, unless I'm missing something and my solution isn't what was needed all along.
Since I started with the 'hack' approach first I subclassed TSpeedButton
and put the code in a MyTSpeedButton function, but that is not needed to make this work. However, it is the code that I'm posting:
header
class MyVCLTSpeedButton : public TSpeedButton
{
public:
__fastcall MyVCLTSpeedButton(Classes::TComponent* AOwner) ;
void __fastcall AddGlyphWithAlphaChannel(Imglist::TCustomImageList* ImageList, int UpIndex, int DisabledIndex = -1, int ClickedIndex = -1, int DownIndex = -1) ;
};
cpp
void __fastcall MyVCLTSpeedButton::AddGlyphWithAlphaChannel(Imglist::TCustomImageList* ImageList, int UpIndex, int DisabledIndex, int ClickedIndex, int DownIndex)
{
Glyph->Assign(NULL) ; // Clear the current bitmap
NumGlyphs = (DisabledIndex > -1)?((ClickedIndex > -1)?((DownIndex > -1)?(4):(3)):(2)):(1) ;
Graphics::TBitmap *BitMap = new Graphics::TBitmap ;
//BitMap->AlphaFormat = afDefined ; // Don't Change AlphaFormat, it will negatively affect rendering !
BitMap->PixelFormat = pf32bit ; // Doesn't seem to be that important
BitMap->Height = ImageList->Height ;
BitMap->Width = (ImageList->Width * NumGlyphs) ;
BitMap->Canvas->Brush->Color = Parent->Brush->Color ;
BitMap->Canvas->Brush->Style = bsSolid ;
BitMap->Canvas->FillRect(BitMap->Canvas->ClipRect) ;
TIcon *Icon = new TIcon() ;
for (int x = 0 ; x < NumGlyphs ; x++)
{
ImageList->GetIcon((x == 0)?(UpIndex):((x == 1)?(DisabledIndex):((x == 2)?(ClickedIndex):(DownIndex))), Icon) ;
BitMap->Canvas->Draw((ImageList->Width * x), 0, Icon) ;
}
Glyph->Assign(BitMap) ;
delete Icon ;
delete BitMap ;
}