Search code examples
delphivcldelphi-xe4alphablending

How do I draw an image with an alpha channel to a TSpeedButton?


I've got a TSpeedButton, and a TImageList that holds various glyphs. One of them has an alpha channel, and it looks very nice when drawn to certain parts of the UI... but when that glyph is drawn on a TSpeedButton, it doesn't take the alpha channel into effect.

Looking at the relevant code in TButtonGlyph.DrawButtonGlyph, it's getting passed true for the Transparent parameter, but Transparent isn't taken into account at all in the if FThemesEnabled code path; it only gets referenced in the else section. Since this program has themes enabled, does that mean it's impossible to draw an alpha-blended image to a TSpeedButton?

Is there any way to work around this?

EDIT: Looking at this a bit more closely, it appears that it takes transparency into account... sort of. Pixels that are fully transparent don't get drawn at all, which is correct behavior. But the antialiasing (partial transparency) around the edges gets drawn as fully opaque.


Solution

  • From what I can see, TSpeedButton takes your bitmap and adds it to an image list. That's FGlyphList in the private section of TButtonGlyph. That image list has ColorDepth of cdDeviceDependent. You'd need that image list to have ColorDepth of cd32Bit if you wanted alpha transparency to be respected. So that right there explains the artifacts.

    I'm not sure how you go about working around this. I think that I'd personally subclass TButtonGlyph and connect it directly to an image list of your selection. Then replace TButtonGlyph.DrawButtonGlyph with code that draws from your image list. I'm sure you'll be able to work out the coding.

    But there'll be no simple workaround. Without major modifications to the VCL, that image list is going to use cdDeviceDependent and there's no simple way for you to change that. There's no obvious quick fix that I can see.

    Actually, what I would do would be to use TButton, but that's just me.


    Regarding the Transparent property of the speed button the documentation says:

    Specifies whether the background of the button is transparent.

    Use Transparent to specify whether the background of the button is transparent.

    This property works only if the Flat property of the TSpeedButton is set to True.

    When Windows themes are enabled, the Transparent property cannot make the button background transparent.

    That is, the property influences the button background, for flat buttons, when unthemed, and has no relevance to glyph drawing.