Delphi 从ComboBox DrawItem事件中的TImageList复制透明(32位alpha)位图

Delphi 从ComboBox DrawItem事件中的TImageList复制透明(32位alpha)位图,delphi,c++builder,alpha-transparency,c++builder-2010,Delphi,C++builder,Alpha Transparency,C++builder 2010,我正在自定义OnDrawItem事件,以便在项目名称旁边绘制图标。 以下是迄今为止我为OnDrawItem事件编写的代码: void\uu fastcall Form1::ComboBox1DrawItem(TWinControl*控件,int索引, TRect和Rect,TOwnerDrawState) { TCOMBOX*CB=静态(控制); CB->Canvas->FillRect(Rect); boost::scoped_ptr位图(新图形::TBitmap()); 位图->像素格式=P

我正在自定义OnDrawItem事件,以便在项目名称旁边绘制图标。 以下是迄今为止我为OnDrawItem事件编写的代码:

void\uu fastcall Form1::ComboBox1DrawItem(TWinControl*控件,int索引,
TRect和Rect,TOwnerDrawState)
{
TCOMBOX*CB=静态(控制);
CB->Canvas->FillRect(Rect);
boost::scoped_ptr位图(新图形::TBitmap());
位图->像素格式=PF32位;
位图->AlphaFormat=AFPremultiplies;
ImageList1->GetBitmap(索引,bitmap.get());
位图->AlphaFormat=AFPremultiplies;
如果(位图->画布->句柄)
{
//alpha混合的结构
混合功能高炉;
bf.BlendOp=AC\u SRC\u OVER;
bf.BlendFlags=0;
bf.SourceConstantAlpha=0xFF;//0x00(透明)到0xFF(不透明)
bf.AlphaFormat=AC_SRC_ALPHA;//使用位图ALPHA
::AlphaBlend(CB->Canvas->Handle,//目标DC的句柄
矩形左+2,//左上角的x坐标
Rect.Top,//左上角的y坐标
位图->宽度,//目标宽度
位图->高度,//目标高度
位图->画布->句柄,//句柄到源DC
0,//左上角的x坐标
0,//左上角的y坐标
位图->宽度,//源宽度
位图->高度,//源高度
bf//alpha混合函数
);
}
Rect=边界(Rect.Left+20+2,Rect.Top,Rect.Right-Rect.Left,Rect.Bottom-Rect.Top);
DrawTextW(CB->Canvas->Handle,CB->Items->Strings[Index].c_str(),-1,&Rect,DT_VCENTER | DT|u SINGLELINE | DT|u END|省略号);
}
当然,问题是获取一个透明的
TImageList1
以复制到透明的
TBitmap
以保留32位alpha透明度/半透明度。目前,我在生成的
TBitmap
中以白色背景将其显示出来

为了清楚起见,
TImageList
ColorDepth
在将图像加载到它之前,使用
DrawingStyle=dsTransparent
将其设置为
cd32bit
,没有问题

解决这个问题的诀窍是什么

更新和我的最终解决方案

根据这里的回复,这里是我的最终工作代码,供将来可能需要它的其他人使用。当然,这只是一个模板代码,您可能需要根据自己的需要进一步自定义它

void\uu fastcall TForm1::ComboBox1DrawItem(TWinControl*控件、int索引、TRect和Rect、TOwnerDrawState)
{
如果(索引>=0)
{
TCOMBOX*CB=静态(控制);
CB->Canvas->FillRect(Rect);
//注意-ImageList1已将DrawingStyle设置为dsTransparent
ImageList1->Draw(CB->Canvas,Rect.Left+2,Rect.Top,0);
Rect=Bounds(Rect.Left+ImageList1->Width+2+2,Rect.Top,Rect.Right-Rect.Left-ImageList1->Width-2,Rect.Bottom-Rect.Top);
DrawTextW(CB->Canvas->Handle,CB->Items->Strings[Index].c_str(),-1,&Rect,DT_VCENTER | DT|u SINGLELINE | DT|u END|省略号);
}
}

您不需要尝试从imagelist中获取原始位图,因为imagelist本身知道如何绘制尊重透明度的信息。您可以使用它的
Draw
方法来实现这一点


否则,答案建议在调用
GetBitmap
之前将
AlphaFormat
设置为'afIgnored',应该保持透明度。

为什么不让图像列表绘制?你可以使用它的绘制方法。否则请看。@SertacAkyuz谢谢,效果很好。。。如果你能把它做成一种形式的回答,我将非常乐意接受。否则我会等一段时间,自己回答。但在你看来,一个更详细的答案是什么?请把它贴出来,我会删除我的。不客气。@SertacAkyuz这个建议对我来说已经足够解决这个问题了,我已经用这个解决方案更新了我自己的问题,这样将来可能会帮助其他人。再次感谢。