TSpeedButton与TAction - 自动生成的禁用图像只考虑黑色

7
首先,我已经知道当你实现一个TSpeedButton时,当你分配其Glyph时,如果你没有超过一个图标,则NumGlyphs应该是1,并且当它被禁用时,它将自动使用同一张图片来自动生成图标的禁用版本。
然而,在我的情况下,我正在为这个速度按钮分配一个操作。 TActionManager同时指向相同的TImageListImagesDisabledImages。 我也测试了没有任何DisabledImages的情况,以及使用全黑蒙版创建图像的副本,并通过DisabledImages进行分配。

这个字形(glyph)在启用情况下显示正常(基于动作设置的图像),但是当禁用时,只会使用图像中的纯黑色来呈现禁用图像。除了纯黑色之外的任何颜色,即使略微偏离黑色,都将被完全忽略,并且不会在渲染禁用图像时包括。

以下是一个测试启用图像和自动生成的禁用图像的比较。该图像只是一个16x16位图,具有一些垂直线条。从最右侧开始,是一条完全黑色的线,其左边是稍浅的线条。

Comparing actions enabled and disabled

如您所见,当禁用时,它只考虑完全黑色的线条。下一条线比完全黑色略微亮一些。
我无法自己分配 "Glyph" 属性,因为它将被分配给它的操作覆盖。我也无法在图像列表上设置两个字符宽的图像,因为这些图像在许多其他没有多个字符概念的地方广泛使用。我也不想使用全黑来制作我的图像。
当有一个操作分配给它时,我如何使已禁用的 TSpeedButton(作为禁用的 TAction 的结果)显示一个禁用的(灰色)图像?
注意:TBitBtn 以及所有依赖于 Glyph 的控件都会出现相同的问题。

u44169002.pas

unit u44169002;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Buttons, System.ImageList,
  Vcl.ImgList, System.Actions, Vcl.ActnList, Vcl.PlatformDefaultStyleActnCtrls, Vcl.ActnMan, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Actions: TActionManager;
    actTest: TAction;
    ImageList: TImageList;
    SpeedButton1: TSpeedButton;
    BitBtn1: TBitBtn;
    procedure actTestExecute(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.actTestExecute(Sender: TObject);
begin
  Self.actTest.Enabled:= False;
end;

end.

u44169002.dfm

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 231
  ClientWidth = 405
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object SpeedButton1: TSpeedButton
    Left = 24
    Top = 24
    Width = 105
    Height = 33
    Action = actTest
    Flat = True
  end
  object BitBtn1: TBitBtn
    Left = 160
    Top = 24
    Width = 105
    Height = 33
    Action = actTest
    Caption = 'Test Action'
    TabOrder = 0
  end
  object Actions: TActionManager
    DisabledImages = ImageList
    Images = ImageList
    Left = 24
    Top = 128
    StyleName = 'Platform Default'
    object actTest: TAction
      Caption = 'Test Action'
      Hint = 'This is just a test action'
      ImageIndex = 0
      OnExecute = actTestExecute
    end
  end
  object ImageList: TImageList
    Left = 24
    Top = 72
    Bitmap = {
      494C010101000800440010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
      0000000000003600000028000000400000001000000001002000000000000010
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000082828200000000006B6B6B000000
      0000555555000000000041414100000000002D2D2D00000000001D1D1D000000
      00000C0C0C000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000424D3E000000000000003E000000
      2800000040000000100000000100010000000000800000000000000000000000
      000000000000000000000000FFFFFF00FFFF0000000000005555000000000000
      5555000000000000555500000000000055550000000000005555000000000000
      5555000000000000555500000000000055550000000000005555000000000000
      5555000000000000555500000000000055550000000000005555000000000000
      5555000000000000FFFF00000000000000000000000000000000000000000000
      000000000000}
  end
end

为了举例,这是我使用的测试位图:

Test Bitmap


事实上,在Vcl.Buttons单元中的TButtonGlyph.CreateButtonGlyph函数中,以下代码似乎仅明确考虑黑色区域:
{ Create a disabled version }
with MonoBmp do
begin
  Assign(FOriginal);
  HandleType := bmDDB;
  Canvas.Brush.Color := clBlack;
  Width := IWidth;
  if Monochrome then
  begin
    Canvas.Font.Color := clWhite;
    Monochrome := False;
    Canvas.Brush.Color := clWhite;
  end;
  Monochrome := True;
end;
with TmpImage.Canvas do
begin
  Brush.Color := clBtnFace;
  FillRect(IRect);
  Brush.Color := clBtnHighlight;
  SetTextColor(Handle, clBlack);
  SetBkColor(Handle, clWhite);
  BitBlt(Handle, 1, 1, IWidth, IHeight,
    MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
  Brush.Color := clBtnShadow;
  SetTextColor(Handle, clBlack);
  SetBkColor(Handle, clWhite);
  BitBlt(Handle, 0, 0, IWidth, IHeight,
    MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
end;

1
只是禁用图像生成算法不够好(即 buttons 中的 TButtonGlyph.CreateButtonGlyph)。分配一个深色图像,您会注意到一个微弱的灰色禁用图像。 - Sertac Akyuz
@SertacAkyuz 刚刚尝试了一下,在完全白色背景上使用完全黑色圆形,并开启 Flat。当禁用时,我仍然看不到任何东西。 - Jerry Dodge
我使用XE2进行了跟踪,也许自那时以来已经发生了变化,尝试使用glyfx的蓝色箭头。 - Sertac Akyuz
1
@Ken 但是你是否已经为它们分配了动作?这才是我问题的根源...我没有亲自分配字形。它们取决于分配给它的动作,以及与该动作相关联的图像。我在一个生产项目中遇到了这个问题,所以我制作了这个测试项目来证明它。我的所有典型字形中都没有任何黑色。它们全部都显示完全透明。请查看我在问题末尾添加的内容。 - Jerry Dodge
1
是的,这就是动作管理器。它取走了控制权。而动作列表则让你重新获得了控制权。 - David Heffernan
显示剩余23条评论
1个回答

0
将速度按钮放在GroupBox上,并禁用您不需要的GroupBox,而无需禁用图标,仍然只有1个图像。 图像将存在,但按钮仍然明显处于未启用状态。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接