我有TSpeedButton
和TImageList
,其中包含各种字形。其中一个有一个alpha通道,当它被绘制到UI的某些部分时看起来非常好......但是当在TSpeedButton
上绘制该字形时,它不会使alpha通道生效
查看TButtonGlyph.DrawButtonGlyph
中的相关代码,true
参数已通过Transparent
,但Transparent
未被考虑在内完全在if FThemesEnabled
代码路径中;它只会在 else 部分中引用。由于此程序启用了主题,这是否意味着无法将Alpha混合图像绘制到TSpeedButton
?
有什么方法可以解决这个问题吗?
编辑:仔细观察一下,看来它需要考虑透明度...等等。完全透明的像素根本不会被绘制,这是正确的行为。但是边缘周围的抗锯齿(部分透明)被绘制为完全不透明。
答案 0 :(得分:6)
从我看到的内容,TSpeedButton
获取您的位图并将其添加到图像列表中。这是FGlyphList
的私人部分中的TButtonGlyph
。该图片列表的ColorDepth
为cdDeviceDependent
。如果您希望尊重Alpha透明度,那么您需要该图片列表ColorDepth
cd32Bit
。所以就在那里解释了这些文物。
我不确定你是如何解决这个问题的。我认为我亲自将TButtonGlyph
子类化,并将其直接连接到您选择的图像列表。然后使用从图片列表中提取的代码替换TButtonGlyph.DrawButtonGlyph
。我确定你能够编制代码。
但是,没有简单的解决方法。如果不对VCL进行重大修改,该图像列表将使用cdDeviceDependent
,并且您无法通过简单的方式进行更改。我看不到明显的快速解决方案。
实际上,我会做的是使用TButton
,但那只是我。
关于速度按钮的Transparent
属性documentation说:
指定按钮的背景是否透明。
使用透明指定按钮的背景是否透明。
仅当TSpeedButton的Flat属性设置为True时,此属性才有效。
启用Windows主题时,“透明”属性无法使按钮背景透明。
也就是说,属性会影响按钮背景,对于平面按钮,未经过训练时,与字形绘制无关。
答案 1 :(得分:0)
为了充分披露:我遇到了类似的问题,并使用此问答来基于我的初始解决方案。因为我需要快速修复我的应用程序和编译器(我使用C ++ Builder 2009),所以我决定ColorDepth
设置为cd32Bit
,直到我有时间处理更长久的事情。这个hack工作了,但有一些更改,但是远远不够理想,出于所有明显的原因,而且功能明智,需要考虑的问题。
然而,在这样做的同时,我进一步尝试并最终到达下面,工作解决方案,不需要任何肮脏的技巧。不熟悉VCL的内部工作方式,而不是“VCL”的内部工作方式。来自VCL中更深入的人的反馈我对我现在缺少的东西有点不确定!因为以下解决方案适合我。在XP,XP-高对比度,W7和W10上确认。字形在W2K上看起来并不好看但是主菜单和弹出图标也是如此,所以就是这样。
我在C ++中编码但是使用相同的底层VCL,所以我将在这里发布我的C ++解决方案,作为Delphi问题的答案。我希望这是好的,为了提供解决方案的途径而不是保持自己。德尔福大师可以转换和发布作为答案,除非我错过了什么,我的解决方案不是一直需要的。
自从我开始使用' hack'方法首先我将TSpeedButton
子类化并将代码放在MyTSpeedButton函数中,但这不是必需的。但是,这是我发布的代码:
标题强>
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 ;
}