【问题标题】:Delphi XE2 VCL styles, remove a style or disable a class skinning from a TLabelDelphi XE2 VCL 样式,从 TLabel 中删除样式或禁用类蒙皮
【发布时间】:2012-04-17 05:08:36
【问题描述】:

使用 XE2 VCL 样式,我想禁用 TLabel(或属性 sfTextLabelNormal)的皮肤

我尝试了其他问题的各种解决方案,例如使用 Engine.UnRegisterStyleHook,但没有效果。

【问题讨论】:

  • 用 TPaintbox 替换 TLabel 并自己自定义绘制可能会稍微少一些工作。

标签: delphi delphi-xe2 vcl skinning vcl-styles


【解决方案1】:

TLabel 组件不使用样式挂钩,因为它不是TWinControl 的后代,因此您不能使用UnRegisterStyleHook 函数。相反,您必须覆盖 Paint DoDrawText 方法。

更新

这里有一个示例,说明如何覆盖 TLabel 的绘制过程。

//declare this code in the implementation part 
uses
 Vcl.Themes,
 Vcl.Styles;

type
  TLabelHelper= class helper for TCustomLabel
    procedure DrawNormalText(DC: HDC; const Text: UnicodeString; var TextRect: TRect; TextFlags: Cardinal);
  end;

{ TLabelHelper }

procedure TLabelHelper.DrawNormalText(DC: HDC; const Text: UnicodeString;
  var TextRect: TRect; TextFlags: Cardinal);
begin
  Self.DoDrawNormalText(DC, Text, TextRect, TextFlags);
end;


{ TLabel }

procedure TLabel.DoDrawText(var Rect: TRect; Flags: Integer);
const
  EllipsisStr = '...';
  Ellipsis: array[TEllipsisPosition] of Longint = (0, DT_PATH_ELLIPSIS, DT_END_ELLIPSIS, DT_WORD_ELLIPSIS);
var
  Text, DText: string;
  NewRect: TRect;
  Height, Delim: Integer;
begin
  Text := GetLabelText;
  if (Flags and DT_CALCRECT <> 0) and
     ((Text = '') or ShowAccelChar and (Text[1] = '&') and (Length(Text) = 1)) then
    Text := Text + ' ';

  if Text <> '' then
  begin
    if not ShowAccelChar then Flags := Flags or DT_NOPREFIX;
    Flags := DrawTextBiDiModeFlags(Flags);
    Canvas.Font := Font;
    if (EllipsisPosition <> epNone) and not AutoSize then
    begin
      DText := Text;
      Flags := Flags and not DT_EXPANDTABS;
      Flags := Flags or Ellipsis[EllipsisPosition];
      if WordWrap and (EllipsisPosition in [epEndEllipsis, epWordEllipsis]) then
      begin
        repeat
          NewRect := Rect;
          Dec(NewRect.Right, Canvas.TextWidth(EllipsisStr));
          DrawNormalText(Canvas.Handle, DText, NewRect, Flags or DT_CALCRECT);
          Height := NewRect.Bottom - NewRect.Top;
          if (Height > ClientHeight) and (Height > Canvas.Font.Height) then
          begin
            Delim := LastDelimiter(' '#9, Text);
            if Delim = 0 then
              Delim := Length(Text);
            Dec(Delim);
            if ByteType(Text, Delim) = mbLeadByte then
              Dec(Delim);
            Text := Copy(Text, 1, Delim);
            DText := Text + EllipsisStr;
            if Text = '' then
              Break;
          end else
            Break;
        until False;
      end;
      if Text <> '' then
        Text := DText;
    end;

    if Enabled or StyleServices.Enabled then
      DrawNormalText(Canvas.Handle, Text, Rect, Flags)
    else
    begin
      OffsetRect(Rect, 1, 1);
      Canvas.Font.Color := clBtnHighlight;
      DrawNormalText(Canvas.Handle, Text, Rect, Flags);
      OffsetRect(Rect, -1, -1);
      Canvas.Font.Color := clBtnShadow;
      DrawNormalText(Canvas.Handle, Text, Rect, Flags);
    end;
  end;
end;

在使用它之前以这种方式声明一个interposer类

  TLabel = class (Vcl.StdCtrls.TLabel)
    procedure DoDrawText(var Rect: TRect; Flags: Longint); override;
  end;

这就是结果

【讨论】:

  • 你能给我一个覆盖它的例子吗?只需保持字体颜色等就足够了。谢谢。
  • 我遇到了和上面一样的问题,这个解决方案很优雅,而且很简约,所以 +1 来自我 =]
  • 这救了我的命:D
  • @hikari,这个答案是在尚未引入 StyleElements 属性时做出的。在新的 Delphi 版本中,您只需要使用此属性来禁用 TLabel 的样式。因此,只需删除此属性的 `SeFont` 元素,TLabel 将使用定义的自定义颜色。
【解决方案2】:

一些修改RRUZ的解决方案(完整组件,少写):

type
    TjsLabel = class(TLabel)
    private
      FDisableTheme: Boolean;
      procedure SetDisableTheme(const Value: Boolean);
    protected

    public
      procedure Invalidate;override;
    published
      property DisableTheme:Boolean read FDisableTheme write SetDisableTheme;
    end;


procedure Register;

implementation
uses Themes, Styles;

type
    TLabelHelper = class helper for TCustomLabel
      procedure SetThemeBehavior(const AEnableTheme:Boolean);
    end;

    procedure Register;
    begin
      RegisterComponents('JS', [TJSLabel]);
    end;


    procedure TJSLabel.Invalidate;
    begin
      SetThemeBehavior(not DisableTheme);
      inherited;
    end;


    procedure TJSLabel.SetDisableTheme(const Value: Boolean);
    begin
      if FDisableTheme <> Value then
      begin
        FDisableTheme := Value;
        SetThemeBehavior(not Value);
      end;
    end;

    { TLabelHelper }

    procedure TLabelHelper.SetThemeBehavior(const AEnableTheme: Boolean);
    begin
      Self.FDrawTextProc := Self.DoDrawNormalText;
      if AEnableTheme then
        if StyleServices.Enabled then
           Self.FDrawTextProc := Self.DoDrawThemeTextEx
    end;

【讨论】:

    猜你喜欢
    • 2012-08-25
    • 2012-02-26
    • 1970-01-01
    • 2013-10-26
    • 2013-05-18
    • 2012-01-25
    • 1970-01-01
    • 2012-04-18
    • 2015-01-09
    相关资源
    最近更新 更多