Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何从TMenuItem上的ImageList绘制透明位图?_Delphi_Delphi 10.1 Berlin_Tmenuitem - Fatal编程技术网

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
属性。