Delphi 如何从TMenuItem上的ImageList绘制透明位图?
我需要在一个项目上绘制一个透明位图。尽管用不同的方法尝试了好几个小时,我还是没有成功:Delphi 如何从TMenuItem上的ImageList绘制透明位图?,delphi,delphi-10.1-berlin,tmenuitem,Delphi,Delphi 10.1 Berlin,Tmenuitem,我需要在一个项目上绘制一个透明位图。尽管用不同的方法尝试了好几个小时,我还是没有成功: var NewItem: TMenuItem; ThisBmp: TBitmap; begin NewItem := TMenuItem.Create(pmSendToCustomTool); NewItem.Caption := ThisCaption; NewItem.Bitmap.SetSize(16,16); NewItem.Bitmap.PixelFormat := pf32
var
NewItem: TMenuItem;
ThisBmp: TBitmap;
begin
NewItem := TMenuItem.Create(pmSendToCustomTool);
NewItem.Caption := ThisCaption;
NewItem.Bitmap.SetSize(16,16);
NewItem.Bitmap.PixelFormat := pf32bit;
NewItem.Bitmap.Transparent := True;
NewItem.Bitmap.TransparentColor := clFuchsia;
ThisBmp := TBitmap.Create;
try
ThisBmp.SetSize(16,16);
ThisBmp.PixelFormat := pf32bit;
ThisBmp.Transparent := True;
ThisBmp.Canvas.Brush.Color := clFuchsia;
ThisBmp.TransparentColor := clFuchsia;
MySystemImageList1.GetBitmap(AIndex, ThisBmp);
CodeSite.Send('ThisBmp', ThisBmp);
NewItem.Bitmap.Assign(ThisBmp);
CodeSite.Send('NewItem.Bitmap', NewItem.Bitmap);
finally
ThisBmp.Free;
end;
这就是在GetBitmap
之后,此BMP在代码站点中的外观:
结果菜单项的外观如下:您的代码无法工作,因为您在使用
GetBitmap()时丢失了所有透明度信息。您必须手动绘制位图,例如:
uses
..., Winapi.CommCtrl;
procedure GetTransparentBitmapFromImageList(ImageList: TCustomImageList; Index: Integer; Bitmap: TBitmap);
var
i: integer;
begin
// make sure your ImageList is set to ColorDepth=cd32bit and DrawingStyle=dsTransparant beforehand...
Bitmap.SetSize(ImageList.Width, ImageList.Height);
Bitmap.PixelFormat := pf32bit;
if (ImageList.ColorDepth = cd32Bit) then
begin
Bitmap.Transparent := False;
Bitmap.AlphaFormat := afDefined;
end
else
Bitmap.Transparent := True;
for i := 0 to Bitmap.Height-1 do
FillChar(Bitmap.ScanLine[i]^, Bitmap.Width*SizeOf(DWORD), $00);
ImageList_Draw(ImageList.Handle, Index, Bitmap.Canvas.Handle, 0, 0, ILD_TRANSPARENT);
end;
或者:
procedure GetTransparentBitmapFromImageList(ImageList: TCustomImageList; Index: Integer; Bitmap: TBitmap);
begin
Bitmap.PixelFormat := pf32bit;
Bitmap.Canvas.Brush.Color := clFuschia;
Bitmap.SetSize(ImageList.Width, ImageList.Height);
ImageList.Draw(Bitmap.Canvas, 0, 0, AIndex, dsTransparent, itImage);
Bitmap.Transparent := True;
Bitmap.TransParentColor := clFuchsia;
Bitmap.TransparentMode := tmAuto;
end;
然后你可以这样做:
var
NewItem: TMenuItem;
begin
NewItem := TMenuItem.Create(pmSendToCustomTool);
NewItem.Caption := ThisCaption;
GetTransparentBitmapFromImageList(MySystemImageList1, AIndex, NewItem.Bitmap);
CodeSite.Send('NewItem.Bitmap', NewItem.Bitmap);
end;
您不只是使用该属性,有什么原因吗?将ImageList指定给父菜单的属性或父菜单项的属性(取决于UI设计),然后将菜单项的ImageIndex
设置为所需的索引。让ImageList为您处理透明图形。是的,这是有原因的。我必须这样做。原因:在弹出菜单中,我有一些项目从SystemImageList(如上所述)获取其标志符号,还有一些项目从标准TImageList获取其标志符号。因为我只能对整个弹出菜单使用一个Imagelist,所以我必须以这种方式拉出部分图示符。您可以1)将所有图像复制到单个TImageList,或2)所有者绘制菜单项,然后您可以从任意源进行绘制。您根本不必使用位图
属性。为什么要手动设置透明颜色?如果将TBitmap.Transparent
设置为True
且未将任何值设置为TransparentColor
TBitmap将使用左下图像像素作为透明颜色。还有,你为什么要设置画笔颜色呢?谢谢Remy,但是当我使用Alternative下的方法时,我得到了这个结果:。。。而且第一个版本也不起作用。这是第一个版本的结果(非透明颜色现在是黑色而不是紫红色):剩下的唯一可能是将图像从SystemImageList复制到与弹出菜单关联的imagelist。如何在保持透明度的同时做到这一点?然后我可以轻松地为所有弹出菜单项设置ImageIndex
属性。