【问题标题】:Flat toolbar buttons with Delphi VCL Styles--fixing toolbar items with dropdowns?带有 Delphi VCL 样式的平面工具栏按钮 - 使用下拉菜单修复工具栏项目?
【发布时间】:2025-12-25 03:10:11
【问题描述】:

这是this question 的后续内容,关于在启用 VCL 样式时使工具栏按钮变平。使用该问题中的解决方案,现在我的大部分 TActionToolbar 按钮都是扁平的。但是,有一个工具栏按钮带有一个带有其他操作的下拉菜单:

而且它仍在围绕它绘制按钮边缘。如何删除带有下拉菜单的工具栏按钮的按钮边框,以便它们与其他普通按钮匹配,并且看起来更像禁用 VCL 样式时?

【问题讨论】:

    标签: delphi vcl-styles


    【解决方案1】:

    这种按钮是由TThemedDropDownButton类绘制的,所以你必须重写这个类和TThemedDropDownButton.DrawBackground方法。

    使用same unit of the previous answer 添加一个名为TThemedDropDownButtonEx 的新类

      TThemedDropDownButtonEx= class(TThemedDropDownButton)
      protected
        procedure DrawBackground(var PaintRect: TRect); override;
      end;
    

    然后像这样实现 DrawBackground 方法

    procedure TThemedDropDownButtonEx.DrawBackground(var PaintRect: TRect);
    const
      CheckedState: array[Boolean] of TThemedToolBar = (ttbButtonHot, ttbButtonCheckedHot);
    var
      LIndex : Integer;
    begin
      LIndex := SaveDC(Canvas.Handle);
      try
        if Enabled and not (ActionBar.DesignMode) then
        begin
          if (MouseInControl or IsChecked or DroppedDown) and
             (Assigned(ActionClient) and not ActionClient.Separator) then
          begin
            StyleServices.DrawElement(Canvas.Handle, StyleServices.GetElementDetails(CheckedState[IsChecked or (FState = bsDown)]), PaintRect);
    
           if IsChecked and not MouseInControl then
              StyleServices.DrawElement(Canvas.Handle, StyleServices.GetElementDetails(ttbButtonPressed), PaintRect);
          end
          else
            ;
        end
        else
          ;
      finally
        RestoreDC(Canvas.Handle, LIndex);
      end;
    end;
    

    最后修改TPlatformVclStylesStyle.GetControlClass方法就这样

    更改此代码

    if AnItem.HasItems then
      case GetActionControlStyle of
        csStandard: Result := TStandardDropDownButton;
        csXPStyle: Result := TXPStyleDropDownBtn;
      else
        Result := TThemedDropDownButton;
      end
    else
    

    通过这个

    if AnItem.HasItems then
      case GetActionControlStyle of
        csStandard: Result := TStandardDropDownButton;
        csXPStyle: Result := TXPStyleDropDownBtn;
      else
        Result := TThemedDropDownButtonEx;
      end
    else
    

    【讨论】:

    • 哇,VCL主题之王再次来袭!