xpmenu是大名鼎鼎的dephi第三方界面控件,最近在使用中发现了几个bug,并对其中的两个进行修正。
b.width := fmenuitem.parent.submenuimages.width; b.width := fmenuitem.parent.getparentmenu.images.width; end; end;
1、首先,是绘制菜单和工具栏图标时,会将图像白色部分作为透明色,导致图像缺损非常难看,如下图所示:![]()
查看xpmenu的源代码,图标是通过txpmenu.drawicon函数绘制的,函数内计算了图标显示的位置、调用graybitmap、dimbitmap、drawbitmapshadow等函数对图像进行了处理,并将图像的transparent设为true,再查看graybitmap、dimbitmap、drawbitmapshadow函数并没有发现会导致透明色计算错误的代码。再往回找,终于在txpmenu.menuedrawitem和txpmenu.toolbardrawbutton里发现了问题,先来看看txpmenu.menuedrawitem:
procedure txpmenu.menuedrawitem(sender: tobject; acanvas: tcanvas; arect: trect;
selected: boolean);
beign
.....
//-------
if hasbitmap then
begin
b.width := fmenuitem.bitmap.width;
b.height := fmenuitem.bitmap.height;
// +jt
//b.canvas.brush.color := ftransparentcolor; // acanvas.brush.color;
b.canvas.brush.color := b.canvas.pixels[0, b.height - 1];//"todd asher" <ashert@yadasystems.com>
b.canvas.fillrect(rect(0, 0, b.width, b.height));
fmenuitem.bitmap.transparent := true;
fmenuitem.bitmap.transparentmode := tmauto;
b.canvas.draw(0,0,fmenuitem.bitmap);
// +jt
end;
if hasimglstbitmap then
begin
{$ifdef ver5u}
if fmenuitem.parent.submenuimages <> nil then
begin
imglisthandle := fmenuitem.parent.submenuimages.handle;
imgindex := fmenuitem.imageindex;
b.height := fmenuitem.parent.submenuimages.height;
// b.canvas.brush.color := ftransparentcolor; // acanvas.brush.color; // +jt
b.canvas.brush.color := b.canvas.pixels[0, b.height - 1];//"todd asher" <ashert@yadasystems.com>
b.canvas.fillrect(rect(0, 0, b.width, b.height));
imagelist_drawex(imglisthandle, imgindex,
b.canvas.handle, 0, 0, 0, 0, clnone, clnone, ild_transparent);
end
else
{$endif}
if fmenuitem.parent.getparentmenu.images <> nil then
begin
imglisthandle := fmenuitem.parent.getparentmenu.images.handle;
imgindex := fmenuitem.imageindex;
b.height := fmenuitem.parent.getparentmenu.images.height;
//b.canvas.brush.color := ftransparentcolor; //acanvas.pixels[2,2]; // +jt
b.canvas.brush.color := b.canvas.pixels[0, b.height - 1];//"todd asher" <ashert@yadasystems.com>
b.canvas.fillrect(rect(0, 0, b.width, b.height));
imagelist_drawex(imglisthandle, imgindex,
b.canvas.handle, 0, 0, 0, 0, clnone, clnone, ild_transparent);
......
if (b <> nil) and (b.width > 0) then // x
drawicon(fmenuitem, acanvas, b, iconrect,
selected or drawtopmenuborder, false, fmenuitem.enabled, fmenuitem.checked,
ftopmenu, fmenu.isrighttoleft);
......
end;